Memcached简介
Memcached是一个高性能的服务器内存缓存软件。在早期版本的Memcached使用的是alloc来分配内存,存在内存碎片,在新版本的Memcached采用了Slab Allocator来分配内存。在MC启动时会要求制定一块内存区域,然后会划分为多个Slab,每个Slab默认大小为1M,可以指定。每个Slab又包含多个truck,每个Slab的truck大小不同,但同一个Slab的truck大小是一样的。在存入数据到MC时,MC会查找最合适的truck来存储数据。比如数据是100字节,现在有truck大小分别为64byte,128byte,144byte,那么会找到128byte的truck存储。不过仍然存在空间的浪费,比如这个例子中就浪费了28byte。所以保证合适大小的空间很重要,我们可以在MC启动时指定负载因子-f
参数来指定,默认是1.25.通常情况下这都是一个比较合理的值,无需修改。另外避免空间浪费的一个处理方法是,将数据大小差不多的放入到相同的MC中。比如一个MC的truck大小为1M,另外一个为1K。那么将数据量在1M左右的都放入到1M的那个MC。
与Redis比较
与Redis相比:
1.MC只支持key/value,Redis支持key/value,list,set,map等6种数据结构;
2.都支持key的过期
MC不主动检查item是否过期,只有在get时检查,但是检查到过期也不会删除,只是做一个标记。在有数据要set时该空间可以被重试使用。MC在分配空间时优先使用已经过期的key/value对的空间,如果分配的空间占满时,会使用LRU算法,删除最近最少使用的key。可以使用-M
参数来启动MC,这样但MC内存耗尽时,会返回一个报错信息(对于完整数据缓存有用)。
Redis是主动监测,在key过期时会主动删除。
3.MC没有持久化功能,无法恢复数据;Redis可以定时保存数据到磁盘,Redis重启可以重新加载到内存。
应用场景
1.将变化频率低的数据事先就放入MC中;
比如商品分类、系统角色等等。
后续如有修改,修改数据库并同步到MC。
这样所有用户的请求全部请求的MC,不会请求数据库。
2.热点数据缓存
3.集群会话共享
分布式缓存设计思想
1.每台MC的内容不一样,所有的服务器内容加起来接近数据库的容量;
2.通过在客户端程序或在负载均衡器上使用Hash算法,让同一内容始终分配到同一台MC。
3.普通的HASH算法会导致MC节点宕机后数据发生流动,可能发生雪崩;
4.采用一致性HASH算法可以使节点宕机对数据的流动降到最低。
5.每个MC节点之间互不通信,数据独立存取。
安装Memcache
安装libevent
由于Memcached使用了libevent库,所以要先安装libevent。
从https://github.com/libevent/libevent/releases获取最新稳定版本下载。这里下载的是libevent-2.1.8-stable.tar.gz。
tar zxvf libevent-2.1.8-stable.tar.gz
cd libevent-2.1.8-stable
./configure
make
make install
问题:
执行./configure
时出错。错误信息:libevent error: no acceptable C compiler found in $PATH
。
解决办法:安装gcc,执行yum install gcc
,然后再执行./configure
。
安装Memcached
从http://memcached.org/downloads下载最新稳定版本,这里下载的是memcached-1.5.10.tar.gz。
tar -zxvf memcached-1.5.10.tar.gz
cd memcached-1.5.10
./configure
make
make install
验证是否安装成功
memcached -h
提示:
memcached: error while loading shared libraries: libevent-2.1.so.6: cannot open shared object file: No such file or directory
。
解决:
find / -name "libevent-2.1.so.6"
可以找到
/usr/local/lib/libevent-2.1.so.6
/data/tools/libevent-2.1.8-stable/.libs/libevent-2.1.so.6
将/usr/local/lib
加到/etc/ld.so.conf中
然后执行ldconfig
,然后再次执行memcached -h
就正常了。
启动Memcached
memcached -m 64 -p 11211 -d -c 8192 -u root
相关参数可以使用memcached -h
查看。本例中-m 64指定内存大小为64M,-p 11211指定端口,-d指定为守护进程,-c指定连接数,-u指定用户(在用root启动时需要指定)。
增加实例,只需修改启动的端口即可。下面新增一个实例
memcached -m 64 -p 11212 -d -c 8192 -u root
命令行客户端操作MC数据
MC命令
- 添加数据(add)
key : 给这个值设置一个名字add key flag expiretime bytes value
flag : 标志,是一个整数
expiretime : 有效期,以秒为单位,0表示没有延迟
bytes : 这是一个需要存储在memcached的数据的长度
value : 是一个需要存储的数据。数据需要将通过在新的一行后输入
注意:bytes要和value的长度一致,否则会出现CLIENT_ERROR bad data chunk错误 - 为一个新的或现有的键(key)设置一个值(set)
set key flag expiretime bytes value
- 替换已存在的 key(键) 的 value(数据值)(replace)
replace key flag expiretime bytes value
- 向已存在 key(键) 的 value(数据值) 后面追加数据(append)
append key flag expiretime bytes value
- 向已存在 key(键) 的 value(数据值) 前面追加数据(prepend)
prepend key flag expiretime bytes value
- 获取存储在 key(键) 中的 value(数据值)(get)
get key
- 删除已存在的 key(键)(delete)
delete key
- incr 与 decr 命令用于对已存在的 key(键) 的数字值进行自增或自减操作
incr key increment_value decr key increment_value
- 清理缓存中的所有数据(flush_all)
flush_all [time] - time : (可选) 在指定时间后执行清理缓存操作
- stats / stats slabs / stats sizes / stats items
stats 显示统计信息例如 PID(进程号)、版本号、连接数等 stats slabs 显示各个slab的信息,包括chunk的大小、数目、使用情况等 stats sizes 显示所有item的大小和个数 stats items 显示各个 slab 中 item 的数目和存储时长 命令格式: gets key 命令格式: cas key flags exptime bytes unique_cas_token [noreply] value
- gets / cas
gets 获取带有 CAS 令牌的 value(数据值) cas 执行一个”检查并设置”的操作
通过Telnet来测试
// 添加数据
add key001 0 10 5 // 回车
hello
// 获取数据
get key001
// 删除数据
delete key001
// 向value前追加数据
prepend key001 0 0 3
123
// 向value后追加数据
append key001 0 0 3
123
// 将key001的value替换为world
replace key001 0 0 5
world
通过nc测试
写入:
printf "set key001 0 0 5\r\nhello\r\n" | nc 127.0.0.1 11211
读取:
printf "get key001\r\n" | nc 127.0.0.1 11211
删除:
printf "delete key001\r\n" | nc 127.0.0.1 11211
# cas操作需要先根据gets key来获取CAS令牌
# 1.获取令牌
printf "gets key001\r\n" | nc 127.0.0.1 11211
# 2.cas更新key的value
printf "cas key001 0 0 5 14 \r\nworld\r\n" | nc 127.0.0.1 11211