共计 9405 个字符,预计需要花费 24 分钟才能阅读完成。
memory+cache 内存缓存
memcache 简介
memcache 是一套 分布式 的高速 缓存系统 ,由 LiveJournal 的 Brad Fitzpatrick 开发,目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的、需要频繁访问数据库的网站访问速度提升效果十分显著。这是一套 开放源代码软件,以 BSD license 授权发布。
官网:http://memcached.org/
分布式:多台 Memcache 服务器来管理数据的架构。
缓存系统:将用户查询的数据缓存到内存之中,方便下次直接从内存中获取。减少了磁盘 IO 的开销。
什么是 nosql?(sql 关系型数据库)
答:MySQL 叫做关系型数据库(主要的特点是都是一个二维表结构(表中的行和列),表与表之间是由关系的)(Oracle(Java)、db2、sqlserver)
非关系型数据:就是不使用 sql 语句作为查询的数据库(保存数据的系统),并且没有严格意义上的二维表的概念。它的数据结构全部是一张巨大的 hash 表(key-value)
hash 表好处:时间复杂度是 0(1):随着数据的增加,查询时间不会存在数量级(1s)的变化。
hash 表坏处:hash 碰撞 不同 key 对应同一个值
key1 ===MD5(sql) | Asion |
key2 | 12 |
key3 | shenzhen |
key4 | iphone |
- 使用原理
在使用的时候,先从 nosql 数据库里面获取,有的话直接返回,没有的话就先从 MySQL 获取,然后缓存到 memcache 里面,下次直接从 memcache 里面返回。
- memcache 与 MySQL 的区别
- 没有使用 SQL 语句
- memcache 没有 MySQL 中的表的概念,都是使用 key-value 来保存的
- memcache 的数据是保存到内存中的,断电即丢失(如何保存数据的持久性?)
1. MemcacheDB可以持久化保存数据。2. repcached也可以实现数据的持久化
注意:NoSQL 是否能够取到 MySQL(关系型数据库)?
答:nosql 的存在永远不是为了取代 MySQL(关系型数据),是关系型数据的一个补充。因为关系型数据库有它独特的地方(事务,存储过程)。
Nosql 主要使用的场景:社交型网站(人人、校内、豆瓣)
课下了解:什么是 C10K 问题?C100K
答:c10k 代表的含义就是当网站的并发数达到 1w 时候网站的整体架构会全部的更新,就叫做 c10k,目前已经被 NoSQL 数据库完美的解决。但是又有 c100k 的问题?
架构网站:
http://www.infoq.com/
memcache 安装(使用端口 11211)
- Windows 下安装
1.1 直接将 memcached 文件放置到某一文件夹下(千万不要使用中文命名的文件夹 | 空格)
1.2 在 cmd 下执行如下命令(不能关闭)可以使用 Ctrl+c 终止
memcache 的端口 11211
1.3 查看是否启动(新开一个窗口),执行如下命令
# netstat -an
- Linux 下安装
- putty–》远程连接 Linux 的一个客户端工具
- 注意:一般连接不上(防火墙)
- 关闭防火墙
- selinux 没有关闭
让 selinux 立即生效
2.1 环境准备
在 Linux 环境下,需要 gcc、g-c++、make(makefile)、cmake、autoconfig(configure)、libtool 等工具
在 Linux 下 联网 的情况下,使用如下命令
# yum install -y gcc make cmake autoconfig libtool
-y 不需要使用确认交互式
2.2 编译安装 memcached
memcached 依赖于 libevent库,因此需要先安装,分别到各自的官网下载稳定版
libevetnt 官网:http://libevent.org/
memcache 官网:http://memcached.org/
先编译安装 libevent,在编译安装 memcached,同时在安装 memcached 需要指定 libevent 的安装路径
具体步骤:
上传
- 先下载 libevent,解压,并安装(一般 Linux 下软件安装都是放在 /usr/local/src 目录下,安装的软件一般放在 /usr/local/NAME)
# ./configure –prefix=/usr/local/libevent && make && make install
b. 安装 memcache,解压、编译、安装
# ./configure –prefix=/usr/local/memcached –with-libevent=/usr/local/libevent && make && make install
2.3 memcached 的启动
# /usr/local/memcached/bin/memcached -m 64 -p 11211 -u nobody -vv
注意:此时 memcached 成功启动,但把信息输出到控制台。
如果想让 memcached 作为服务在 后台启动,只需要加上 - d 选项(daemon 后台)
# /usr/local/memcached/bin/memcached -m 64 -p 11211 -u nobody -d
如何查看服务器是否正常启动?
# ps axu | grep memcached
如果需要查看参数信息,使用 memcached -h 查看帮助:
操作 memcache
memcached 的客户端与服务器端的通信很简单,基于文本的协议,类似 http 协议,可以直接使用 Telnet 来做交互
使用 Telnet 操作(quit 退出)
# telent 服务器的 IP 11211
- Windows 下
连接之后 使用 ctrl + ] 打开 Telnet 的回显
- Linux 下
2. 基本命令:
学习 memcache 的增删改查命令:
add key flag expire length
key: 名称
flag: 1 memcache 按照字符串的方式保存
expire:过期时间,memcache 时间
length:数据长度(B)
※add 增加
# add name 1 0 2 # 在 memcache 服务器上添加一个 key 为的 name 值 长度为 2 个字节,有效期长期有效
如何理解 expire
设置缓存的有效期,有三种格式
- 设置秒数,从设置开始, n 秒 后失效
- 时间戳,到指定时间戳后失效
- 设置为 0,不自动失效(特别注意,不是永久有效。a. 在 memcache 安装时候,指定了一个最长的有效时间,默认是 30 天(源代码)b. 可能不到 30 天,就会被挤出去)
最近最少使用原则
※delete 删除
# delete key
※replace 替换
# replace key flag expire length
※get 获取
# get key
※set 如果数据有 replace,没有则 add
# set key flag expire length
name 存在:
age 不存在:
※incr 增加
# incr age NUMBER
※decr 减少
# decr age NUMBER
※stats 统计 memcache 服务器信息
# stats
※flush_all 清空所有数据
# flush_all
使用 php 操作 memcache
- Windows 下
- 到(http://downloads.php.net/pierre/)下载扩展 dll 文件
- 将该文件放到 php 的 extension_dir 对应的目录下
- 修改 php.ini 文件,加入 extension=php_memcache.dll,引入该文件
- 重启 Apache
- Linux 下(在 Linux 下如何为 php 开启一个扩展,说一下通用方案)
- 到(http://pecl.php.net/package/memcache)去下载扩展源码
beta:测试版:一般都有一些小 bug,但是需要用户去使用发现,如果有问题,可以给官方反馈。然后在做修复
alpha:内部测试版:内部在开发的时候,使用的版本,一般这个版本 bug 众多。但是这个版本往往有新的功能加入。(一般也是新公司才试试)alpha 版本有一些补偿。
stable:稳定版:基本无 bug,能够稳定的运行。
ftp 使用的注意事项:
- vsftpd 是否正常的开启 service vsftpd status
- 一般都只能使用普通用户连接 ftp(不能 root 来连接 ftp)获取使用 sudo
- 自己家目录的大小空间不够(上传文件成功,但是显示的大小为 0)
- 防火墙是否关闭(iptables -F 关闭)(iptables -L)
# cls
# cd
# vim .bashrc
Linux 下载末行模式下
# :x 小写 退出 wq
linux 在编辑模式下
# Z 大写
- 一般下载到 /usr/local/src 目录下,解压,并进入该文件夹内
- 使用当前 php 的 phpize 命令创建 configure 文件(必须在扩展目录内)
# /usr/local/php/bin/phpize 绝对路径 phpize
d. 利用上面生成的 configure 文件,收集系统信息 不需要指定安装路径
# ./configure –with-php-config=/usr/local/php/bin/php-config 告诉它如何去找 php 配置文件
e. 执行编译、安装
# make && make install
注意:可以查看上述命令执行完成之后的结构
# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
- 修改 php.ini 配置文件,重启 Apache
注意:在 Linux 下,如何查看 php.ini 配置文件的位置?
解决:phpinfo();
注意:在 Linux 下,修改配置文件之前,一定要备份
php.ini-backup-2016-1-12
注意:.so 是什么文件?
.so 是 Linux 下的共享对象,类型 Windows 下的.dll 文件
注意:Linux 下,关闭一个服务 可以使用
# pkill -9 httpd
# ps aux | grep httpd
#ps uax | grep httpd
将上面生成的地址增加到 php.ini 配置文件,如下
extension_dir=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
extension=memcacahe.so
- 测试
建立一个 test.php 文件,测试 php 是否有 memcache 的一个模块
php 操作 memcache,保存并获取值
memcached 的内存管理与删除机制
注意:Memcache 最大的 value 也只能是 1M 的空间。
注意:内存碎片化永远都存在,只是哪一种方式可以使得内存碎片最小。
1. 什么是内存碎片化?
在使用这种内存缓存系统的时候,由于不断的申请,释放,就会形成一些很小的内存片段,无法被利用,这种现象就叫做,内存的碎片化。这个小红块就是操作系统无法使用的空间。
- 如何解决?
memcache 利用 slab allocator 的方式来管理(每个 slab class 大小为 1M)
最小的单元叫做 chunk(小块):存放数据的仓库
多个小单元组成一个 chunks:多个小块组成(所有的小块的大小全部一致)
每个 slab class 的大小为 1M
- memcache 如何选择合适的大小?
注意:如果 122Bytes 的 slab 装满了,现在有一个 100Bytes 的数据来了,存到哪里去?
答:肯定不会存在 144,还是存在 122 这个 chunk 里面,利用 LRU 算法来实现数据存储。
- 固定 chunk 带来的内存浪费,22B
- factor 调优
memcached 在启动的时候,会按照一定的大小来组织 slab class,可以通过 -f 来指定
默认是 1.25,相邻 chunk 之间的比值就是增加因子。可以根据自己网站的业务调整缓存因子的大小。
是因为每个业务不一样,所需要的最小的 chunk 是不一样的。这个参数使得我们的系统变得更加适应自己的业务,因为数据可以自己设定大小。
- memcache 的 惰性删除
memcached 内部不会监视记录是否过期,而是在 get 时查看记录的时间戳,检查记录是否过期。这种行为被称为 lazy(惰性)expiration。因此,好处是 memcached 不会在过期监视上耗费 CPU 时间。
比如:有 set(name, asion, 0, 3600) 过了 3600 秒就失效,失效后,并不会自动删除,只有当 get 查询时,检测是否过期,如果过期则删除。
例如 # add name 1 8 2 当 8s 后,是失效,还是不存在?通过 stats 分析
分析:是失效你,而不是不存在,只有在下一次去获取时候,memcache 才会去检测它是否过期,过期了就删除
- memcache 的 LRU 算法
memcached 会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。
顾名思义,这是删除 ” 最近最少使用 ” 的记录的机制。因此,当 memcached 的内存空间不足时(无法从 slab class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空
间分配给新的记录。从缓存的实用角度来看,该模型十分理想。
当 mecache 里面的数据空间(默认是 64M)已经占满了,再继续存储数据能否存储呢?
答: 能存储,要删除过期的数据,如果都没有过期,则删除最不活跃的数据,腾出空间给后面添加数据。
例如:以 122Bytes 的 slab 举例,当数据装满后,如果来了一个 100Bytes 数据,如何处理?(即使永久有效,也会被踢)
分析:内存的管理 LRU 算法、FIFO 算法
- memcache 的一些参数 Ctrl+C
注意:在 vim 下如果输入了 ctrl+s 可以使用 ctrl+q 退出
-p 监听的端口
-l 连接的 IP 地址, 默认是本机
-d start 启动 memcached 服务
-d restart 重起 memcached 服务
-d stop|shutdown 关闭正在运行的 memcached 服务
-d install 安装 memcached 服务
-d uninstall 卸载 memcached 服务
-u 以的身份运行 (仅在以 root 运行的时候有效)
-m 最大内存使用,单位 MB。默认 64MB
注意:如果系统是 32 位的,则最大限制为 2G,如果系统是 64 位,则无限制。
-M 内存耗尽时返回错误,而不是删除项
-c 最大同时连接数,默认是 1024
-f 块大小增长因子,默认是 1.25
-n 最小分配空间,key+value+flags 默认是 48
-h 显示帮助
-v 输出警告和错误信息
-vv 打印客户端的请求和返回信息
-i 打印 memcached 和 libevent 的版权信息
实际使用场景
保存:1. 文件 2. mysql
问题:如果一个文件夹下 session 文件过多,检索变慢,如何处理?
答:分层处理
使用 Memcache 来保存,Memcache 使用分布式来保存(拿多台 Memcache 做存储)
使用 memcache 保存 session
1. 修改 php.ini 文件,配置信息如下
session.save_handler = memcache #代表使用 memcache 保存 session
session.save_path =”tcp://127.0.0.1:11211” # 指定 memcache 服务器的地址和端口
- 测试
1. 开启 session,保存 session
- 从 Memcache 获取 session
高级特性
分布式 memcache 配置
什么是分布式?
由于单台 memcache 的服务能力有限,可以使用多台 memcache 来提供缓存的功能,这种架构就叫做 memcache 的 分布式缓(集群)存系统
如何实现?
可以这样理解,如何将数据分散答各台 Memcache 服务器上。
在客户端实现分布式,在数据保存之前,根据 一定的算法,将数据保存到那台 memcache 服务器上,在获取数据的时候,按照前面相同的算法去对应的 memcache 服务器上获取数据
分布式算法
- 取摸算法
将 key 的值对服务器的台数取余,然后将对应的 value 值保存到对应的余数的那台 memcache 服务器上,一般这个 hash 函数 crc32(key) % 3
crc32()这个函数可以使得一个字符串变成一个 32 位的整数
坏处:当某一台服务器宕机或者需要增加一台服务器的时候,这个时候缓存数据基本全部失效,因为除数变了。不严格的公式,命中率 = 取到数据 / 总数 1/N N 代表服务器的台数
引发出来的问题:当 memcache 宕机之后,缓存数据失效,这个时候 MySQL 的压力会骤增,
这个时候,MySQL 会宕机,然后在重启 MySQL,MySQL 会在短时期内再次宕机,然后,稍微延迟一点(缓存已经重新建立了一部分),又宕机。随着时间的慢慢推移,MySQL 基本上趋于稳定,缓存系统成功建立。因为缓存数据不存在,所有的请求全部要转向 MySQL 来提供,这种现象就叫做 memcache 的雪崩现象。
概图:
- 一致性 hash 实现分布式
- 假想有一个圆环,分布着从 0 到 2^32 这么多个正整数
- 然后在将服务器的节点数通过 hash 函数(crc32())运算后,按照顺时针的方向映射到上面的圆环上
- 将需要存储的数据的 key 也按照上面的 hash 函数运算后,按照顺时针的方向保存到一个 不比 自己小的节点上
注意:只要是 memcache 宕机,就一定会有数据的丢失。但是要想办法让数据丢失的最少,使用一致性 hash,即使有一台服务器宕机,也只是影响一台服务器上的数据。
虚拟节点:分担任务
缓存雪崩现象
雪崩造成的原因?
- 由于算法不当,取摸算法,造成大量缓存失效,会引发雪崩
解决方案:一致性 hash 算法
- 缓存时间都是同一时间,缓存系统会在同一时间全部失效,这个也会造成雪崩
解决方案:缓存时间设置成一个范围内的随机时间(3- 9 小时)
由于某个 memcache 节点的缓存数据失效,导致其他 memcache 节点的缓存命中率下降,缓存中缺失的数据会去 MySQL 数据库中查询,短时期内,造成了 MySQL 服务器压力巨大,造成宕机,就叫做 缓存雪崩现象。
当重启 MySQL 之后,短期内再次宕机,但缓存数据已经建立了一部分,在 MySQL 反复多次启动之后,缓存全部重建完毕,MySQL 不再宕机趋于稳定。
解决方案:把缓存的时间设置成一个范围内的随机值(3- 9 小时),这样就在不同的时间段失效,把重建的工作分担到不同的时间上。
memcache 如何做高可用
- 使用 repcached 实现,全称 replication cached 是由日本人发明的 memcached 的高可用性技术,简称复制缓冲区技术。
- MemcacheDB是一个分布式、key-value 形式的 持久存储系统 。 由 sina 人员开发。它不是一个缓存组件,而是一个基于对象存取的、可靠的、快速的持久存储引擎。协议跟 memcache 一致(不完整),所以很多 memcached 客户端都可以跟它连接。MemcacheDB 采用 Berkeley DB 作为持久存储组件,故很多 Berkeley DB 的特性的他都支持。扩展
- 如何在 Linux 下给一个 php 添加一个扩展,说出通用步骤?
答:
- 下载对应扩展源码
- 上传放入 /usr/local/src/
- 解压 并进入文件夹内
- 在文件夹内执行 绝对路径下的 phpize /usr/local/php/bin/phpize
- 执行 configure ./configure –with-php-config=/usr/local/php/bin/php-config
- make && make install
- 生成一个目录文件,文件下面有一个.so 结尾的文件
- 修改 php.ini 文件
- 增加 extension_dir = 目录 extension= .so 文件
- 重启 Apache
- 添加 phpinfo()
- 浏览器查看
- memcache 的安全性如何解决?
答:
由于 memcache 的本身设计就是极为简洁的,根本没有设置权限方面的限制。为什么不设置权限?只提供缓存功能,为了精简
- 放在内网 192.168.1.110 内网 IP 外网无法访问
- 写一个 防火墙验证规则,只允许自己规定 IP 的包可以转进来,其他的全部丢弃
192.168.1.221 —224
3. 当使用文件保存 session 文件时候,如果文件过多,如何处理?
一般来说,超过 65535 个 session 文件的时候,这个时候 session 的获取就会变得异常缓慢,意味 php 代码执行很慢,如何解决?
答:
分层处理:一个文件夹下建立 A - Z 开头的文件夹 然后 A_Z 在建立
使用 memcache 处理:单台 memcache 处理能力有限,就使用分布式 memcache 来处理
- 如何理解负载均衡集群也是高可用集群,但有不是?
答:负载均衡集群提供了高可用的能力,如果某一台宕机之后,还是可以提供正常的服务,只是服务提供的有些吃力而已。
因为负载均衡集群不提供 keepalive 的机制。监控机制
案例:
在项目中如何使用 Memcache?
Memcache 存在的意义就是缓存数据,减轻 MySQL 的压力。
- 书写一个列表页
- 详情页
扩展
- Linux 下安装一个 php 的扩展的通用方法
答:
- 下载对应的扩展的源码 http://pecl.php.net/package/memcache
- 将对于的扩展上传到 Linux 服务器上,放在(/usr/local/src/ 下)
- 执行 tar -zxvf NAME.tar.gz
- cd NAME
- 执行绝对路径下的 phpize 命名(/usr/local/php/bin/phpize)必须在扩展包的目录内
- 执行 ./configure –with-php-config=/usr/local/php/bin/php-config(–with-php-config= 绝对路径下的 php-config 的路径,并且不需要指定安装的路径)
- make && make install
- 会生成一个目录,在个目录里面有对于的 NAME.so 文件
- 去修改 php.ini 的配置文件,增加两行信息
extension_dir=’ 上面生成的目录 ’
extension=’NAME.so’
- 重启 Apache,然后使用 phpinfo()函数测试一下,在浏览器输入地址查看,搜索如果有 Memcache,代表扩展成功的开启。
CentOS 6.6 下 Memcached 源码安装配置 http://www.linuxidc.com/Linux/2015-09/123019.htm
Memcached 安装及启动脚本 http://www.linuxidc.com/Linux/2013-07/87641.htm
PHP 中使用 Memcached 的性能问题 http://www.linuxidc.com/Linux/2013-06/85883.htm
Ubuntu 下安装 Memcached 及命令解释 http://www.linuxidc.com/Linux/2013-06/85832.htm
Memcached 的安装和应用 http://www.linuxidc.com/Linux/2013-08/89165.htm
使用 Nginx+Memcached 的小图片存储方案 http://www.linuxidc.com/Linux/2013-11/92390.htm
Memcached 使用入门 http://www.linuxidc.com/Linux/2011-12/49516p2.htm
Memcached 的详细介绍:请点这里
Memcached 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-04/129963.htm