Memcache和Redis因为操作简单,是我们常用的服务器数据缓存系统,以下文字仅作备忘记录,部份转载至网络。
一、定义
1、Memcache
Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。
2、Redis
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与Memcache一样,为了保证效率,数据都是缓存在内存中。区别的是Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
二、相同和区别
1、存储类型:Memcache和Redis都将数据存放在内存里,所以是内存数据库。Memcache还可用于缓存图像、视频等数据;
2、数据类型:Memcache在添加数据时就要指定数据的字节长度,如:
set key2 0 0 8
cocacola
STORED
而Redis不用指定数据长度,如:
redis 127.0.0.1:6379>set key2 'cocacola'
OK
redis 127.0.0.1:6379>get key2
'cocacola'
3、存储方式:Memcache存储数据为key/value键值对;
4、过期策略:Memcache在set时指定,例如set key2 0 0 8,即永不过期;Redis可能通过设定expire,例如set key2 10'cocacola',
5、虚拟内存:Redis当物理内存用完时,可以将一些很久没用到的value交换到磁盘;
6、Redis不仅仅支持key/value键值对类型的数据,同时还提供list,set,hash等数据结构的存储;
7、数据安全:Memcache断电数据丢失,Redis可以定期备份数据到磁盘,进行持久化;
8、数据恢复:Memcache数据无法恢复,Redis丢失后可以通过aof恢复;
9、分布式:设定Memcache集群,利用magent做一主多从;Redis可以做一主多从,也可以一主一从;
三、Memcache、Redis、MongoDB的几点对比
1、性能
都比较高,性能对我们来说应该都不是瓶颈;
总体来讲,TPS方面Redis和Memcache差不多,要大于mongoDB;
2、操作的便利性
Memcache:数据结构单一;
Redis:丰富一些,数据操作方面,Redis更好一些,较少的网络IO次数;
Mongodb:支持丰富的数据表达,索引,最类似关系型数据库,支持的查询语言非常丰富;
3、内存空间的大小和数据量的大小
Redis:在2.0版本后增加了自己的VM特性,突破物理内存的限制;可以对key value设置过期时间(类似Memcache);
Memcache:可以修改最大可用内存,采用LRU算法;
MongoDB:适合大数据量的存储,依赖操作系统VM做内存管理,吃内存也比较厉害,服务不要和别的服务在一起;
4、可用性(单点问题)
Redis:依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题,所以单点问题比较复杂;
不支持自动sharding,需要依赖程序设定一致hash 机制;
一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡;
Memcache:本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题;
MongoDB:支持master-slave,replicaset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切分机制;
5、可靠性(持久化)
Redis:支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响;
Memcache:不支持,通常用在做缓存,提升性能;
MongoDB:从1.8版本开始采用binlog方式支持持久化的可靠性;
6、数据一致性(事务支持)
Memcache:在并发场景下,用cas保证一致性;
Redis:事务支持比较弱,只能保证事务中的每个操作连续执行;
MongoDB:不支持事务;
7、数据分析
MongoDB内置了数据分析的功能(mapreduce),Memcache和Redis不支持;
8、应用场景
Redis:数据量较小的更性能操作和运算上;
Memcache:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适合读多写少,对于数据量比较大,可以采用sharding);
MongoDB:主要解决海量数据的访问效率问题;
四、安装和操作Memcache
A. 服务器端安装Memcache
安装Memcache之前,必须先下载和安装libevent,因为Memcache使用libevent库用于Socket处理,所以在安装Memcache之前还需要安装libevent。
libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名的用于apache的php缓存库memcached也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。
Ⅰ. 下载安装libevent,如果wget不能下载,可以本地下载后用SFTP上传到服务器。
#wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
#tar -xzvf libevent-2.0.21-stable.tar.gz
#cd libevent-2.0.21-stable
#./configure -prefix=/usr/local/libevent 配置安装路径
#make
#make install
Ⅱ. 下载安装Memcache,安装中需要手动指定libevent的安装位置。
#wget http://www.memcached.org/files/memcached-1.4.20.tar.gz
#tar -xzvf memcached-1.4.20.tar.gz
#cd memcached-1.4.20
#./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent 手动指定安装路径和libevent的已经安装的位置
#make && make install
如果不指定安装路径,安装成功后会把memcached放到/usr/local/lib/memcached。
Ⅲ. 测试安装是否成功
#ls -al /usr/local/bin/mem*
-rwxr-xr-x 1 root root 341872 9月 2 11:06 /usr/local/bin/memcached
说明已经安装成功了。
B. 命令行操作Memcache
Ⅰ. 启动Memcache服务
# /usr/local/bin/memcached -d -m 100 -u root -l 192.168.1.114 -p 12000 -c 256 -P /tmp/memcached.pid
-d选项是启动一个守护进程
-m是分配给Memcache使用的内存数量,单位是MB,我这里是100MB
-u是运行Memcache的用户,我这里是root
-l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.1.114
-p是设置Memcache监听的端口,我这里设置了12000,最好是1024以上的端口
-c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定
-P是设置保存Memcache的pid文件,我这里是保存在 /tmp/memcached.pid
Ⅱ. 想要结束Memcache进程
#kill `cat /tmp/memcached.pid`
也可以启动多个守护进程,不过端口不能重复。
Ⅲ. 连接测试Memcache
#telnet 192.168.1.114 12000
Trying 192.168.1.114...
Connected to 192.168.1.114.
Escape character is '^]'.
set key2 0 60 8
cocacola
STORED
get key2
cocacola
END
Ⅳ. 退出Memcache命令行模式
quit
经过以上操作,说明Memcached已经安装成功。
C. 一些常见问题
Ⅰ. 启动服务时出现:/usr/local/bin/memcached: error while loading shared libraries: libevent-1.2.so.1: cannot open shared object file: No such file or directory,具体错误根据libevent版本号会略有不同;
#LD_DEBUG=libs memcached -v
#ln -s /usr/lib/libevent-1.2.so.1 /usr/lib64/libevent-1.2.so.1
#/usr/local/bin/memcached -d -m 100 -u root -p 12000 -c 1000 -P /tmp/memcached.pid
#ps -auxⅡ. 设置Memcached随机自启动
#vi /etc/rc.d/rc.local
在行末加上Memcached的启动命令/usr/local/bin/memcached -d -m 100 -u root -l 192.168.1.114 -p 12000 -c 256 -P /tmp/memcached.pid,下次服务器重启时Memcached会随机自启动。
D. Memcache相关命令
Ⅰ. 启动Memcached常用参数
-p <num> 设置端口号(默认不设置为: 11211)
-l <ip_addr> 绑定地址 (默认:所有都允许,无论内外网或者本机更换IP,有安全隐患,若设置为127.0.0.1就只能本机访问)
-d 独立进程运行
-u <user> 绑定使用指定用于运行进程
-m <num> 允许最大内存用量,单位M (默认: 64 MB)
-c <num> 选项是最大运行的并发连接数,默认是1024,按照你服务器的负载量来设定
-P <file> 将PID写入文件<file>,这样可以使得后边进行快速进程终止, 需要与 -d 一起使用
-U <num> UDP监听端口 (默认: 11211, 0 时关闭)
Ⅱ. 连接Memcached,使用telnet接口命令连接
#telnet ip 端口号
Ⅲ. 写入Memcached
<command name> <key> <flags> <exptime> <bytes>
<data block>
1) <command name> 可以是set, add, replace。
set 表示按照相应的<key>存储该数据,没有的时候增加,有的覆盖。
add 表示按照相应的<key>添加该数据,但是如果该<key>已经存在则会操作失败。
replace 表示按照相应的<key>替换数据,但是如果该<key>不存在则操作失败。
2) <key> 客户端需要保存数据的key。
3) <flags> 是一个16位的无符号的整数(以十进制的方式表示)。
该标志将和需要存储的数据一起存储,并在客户端get数据时返回。
客户可以将此标志用做特殊用途,此标志对服务器来说是不透明的。
4) <exptime> 过期的时间。
若为0表示存储的数据永远不过时(但可被服务器算法:LRU 等替换)。
如果非0(unix时间或者距离此时的秒数),当过期后,服务器可以保证用户得不到该数据(以服务器时间为标准)。
5) <bytes> 需要存储的字节数(不包含最后的"\r\n"),当用户希望存储空数据时,<bytes>可以为0,最后客户端需要加上"\r\n"作为"命令头"的结束标志。
结果响应:REPLY
6) <data block> 紧接着"命令头"结束之后就要发送数据块(即希望存储的数据内容),最后加上"\r\n"作为此次通讯的结束。
当以上数据发送结束之后,服务器将返回一个应答。可能有如下的情况:
“CLIENT_ERROR”: 客户端错误,可能是由于输入data和bytes长度不一致引起
"STORED" : 表示存储成功
"NOT_STORED" : 表示存储失败,但是该失败不是由于错误。通常这是由于“add”或者“replace”命令本身的要求所引起的,或者该项在删除队列之中。
Ⅳ. 获取检查key/value
get <key>*\r\n
<key>* 表示一个或者多个key(以空格分开)
"\r\n" 命令头的结束
结果响应:REPLY
服务器端将返回0个或者多个的数据项,每个数据项都是由一个文本行和一个数据块组成。当所有的数据项都接收完毕将收到"END\r\n"。
每一项的数据结构:
VALUE <key> <flags> <bytes>\r\n
<data block>\r\n
1) <key> 希望得到存储数据的key
2) <falg> 发送set命令时设置的标志项
3) <bytes> 发送数据块的长度(不包含"\r\n")
4) "\r\n" 文本行的结束标志
5) <data block> 希望接收的数据项。
6) "\r\n" 接收一个数据项的结束标志。
如果有些key出现在get命令行中但是没有返回相应的数据,这意味着服务器中不存在这些项,这些项过时了,或者被删除了。
如:get aa
VALUE aa 33 4
cola
END
Ⅴ. 删除key/value
delete <key> <time>\r\n
1) <key> 需要被删除数据的key
2) <time> 客户端希望服务器将该数据删除的时间(unix时间或者从现在开始的秒数)
3) "\r\n" 命令头的结束
Ⅵ. 检查Memcache服务器状态
stats\r\n
在这里可以看到memcache的获取次数,当前连接数,写入次数,已经命中率等。
STAT pid 25301
STAT uptime 3918
STAT time 1409632362
STAT version 1.4.20
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.028995
STAT rusage_system 0.043993
STAT curr_connections 5
STAT total_connections 9
STAT connection_structures 6
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 1
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 136
STAT bytes_written 1172
STAT limit_maxbytes 104857600
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT bytes 73
STAT curr_items 1
STAT total_items 1
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
ENDⅦ. 高级缓存细节查看办法
stats reset 清空统计数据
stats malloc 显示内存分配数据
stats cachedump slab_id limit_num 显示某个slab中的前limit_num个key列表,显示格式如下
ITEM key_name [ value_length b; expire_time|access_time s]
其中,memcached 1.2.2及以前版本显示的是 访问时间(timestamp),1.2.4以上版本,包括1.2.4显示过期时间(timestamp),如果是永不过期的key,expire_time会显示为服务器启动的时间。
stats cachedump 7 2
ITEM copy_test1 [250 b; 1207795754 s]
ITEM copy_test [248 b; 1207793649 s]
stats slabs 显示各个slab的信息,包括chunk的大小、数目、使用情况等
stats items 显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数)
stats detail [on|off|dump] 设置或者显示详细操作记录,参数为on,打开详细操作记录,参数为off,关闭详细操作记录,参数为dump,显示详细操作记录(每一个键值get、set、hit、del的次数)。
Ⅷ. 清空所有键值
flush_all
注:flush并不会将items删除,只是将所有的items标记为expired,因此这时memcache依旧占用所有内存。
Ⅸ. 退出
quit
E. PHP程序中应用Memcache
PHP包含了Memcache和Memcached两种扩展方式,这两种接口使用PHP代码都能够操作Memcache服务器,具体程序可以查看PHP手册。
当前服务器环境中使用更多的是不带d的memcache版本,是一个原生版本,完全在PHP框架内开发。带d的memcached是使用libmemcached库提供的api与Memcache服务器端进行交互,相对来讲,memcached版本的功能更安全一些。
Memcache:http://pecl.php.net/package/memcache,需要zlib支持。
Memcached:http://pecl.php.net/package/memcached,libmemcached:http://libmemcached.org/libMemcached.html。
按照上述步骤,正常安装libevent和memcache,然后进行以下操作。
Ⅰ.PHP安装Memcache扩展
#wget http://pecl.php.net/get/memcache-2.2.7.tgz
#tar -xzvf memcache-2.2.7.tgz
#/usr/local/php/bin/phpize 执行phpize扩展安装程序,该路径根据自己PHP服务器环境会有所不一样
#./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with-zlib-dir 我的服务器使用源码包安装,所以需要手动指定路径。
#make && make install
完成后显示 Installing shared extensions:/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/,该路径根据你安装PHP方式不同,会有较大差别。
#ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
ls时可以看到memcache.so文件存在该目录下。
#vi /usr/local/php/etc/php.ini 根据自己服务器环境php.ini路径会有所不同
编辑php.ini文件在zend模块之前加入如下代码
extension_dir="usr/local/php/lib/php/extensions/no-debug-non-zts-20090626"
extension=memcache.so
重启web服务器,结束该扩展安装。
Ⅱ. PHP安装memcached扩展
因为memcached扩展是基于libmemcached,所以要先安装libmemcached。
#wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
#tar -xzvf libmemcached-1.0.18.tar.gz
#cd libmemcached-1.0.18
#./configure --prefix=/usr/local/libmemcached --with-memcached
#make && make install
安装libmemcached结束后,可以继续安装php的memcached扩展。
#wget http://pecl.php.net/get/memcached-2.2.0.tgz
#tar -xzvf memcached-2.2.0
#cd memcached-2.2.0
#/usr/local/php/bin/phpize 执行phpize扩展安装程序,PHP路径根据自己服务器具体环境会有不一样。
#./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached --prefix=/usr/local/phpmemcached --with-zlib-dir 我的服务器使用源码包安装,需要手指定路径。
#make && make install
完成后会显示 Installing shared extensions:/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/,该路径根据服务你安装PHP方式不同,会有较大差别。
#ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/
ls时可以看到memcached.so文件存在该目录下。
#vi /usr/local/php/etc/php.ini 根据自己服务器环境php.ini路径会有所不同
编辑php.ini文件,在zend模块之前加入如下代码
[memcache]
extension_dir="/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/"
extension=memcached.so
重启web服务器,结束该扩展安装。
Ⅲ. 管理监控Memcache
memadmin是一个基于php5、jQuery的memcache管理监控工具,该工具基于PHP Memcache开发,需要Ⅱ的支持,具体使用方法可以参照官方网站。
Ⅳ.PHP脚本操作Memcache
五、安装和操作Redis