目录
内容
对比memcached与redis;依据官网信息,对memcached进行介绍。
memcached与redis的对比
memcached | redis |
多线程 | 单线程 |
集群,由client或proxy负责路由 | 集群,自带分片规则,也可由client或proxy进行路由 |
只有一种数据结构,可满足cas场景 | 有多种数据结构,使用场景更多 |
指令少,类似redis的string相关指令 | 指令多 |
单实例轻松达到每秒20w,性能更高 | 单实例每秒数万 |
对内存切分并分组,用于内存分配 | 没有对内存进行切分 |
what
simply memory cache (a key/value store) daemon
依赖内存的k-v缓存,且是个守护进程
硬件
依赖
- cpu占用低,分配较大的内存,网络占用依赖读取的数据。
- cpu依赖
- 以快速回应为目标,所以cpu占用低。
- memcached是多线程的,默认4个线程,若80+,则非常慢。(redis是单线程的)
- 一般情况,对cpu没有要求,且1个线程即可。
- 内存依赖
- 越大越好
- 分配物理内存,不要超过内存实际大小,避免swap
布局
- 和webserver混部,可以
- 和db混部,不推荐
- 独立部署,可以
- 思考:使用docker,可分配内存,不用担心混部的内存问题。dockerhub地址
启动
参数
-m 单位M。可占用的内存空间,实际占用可能多一点。最少64M。
-d 守护进程
-v 输出控制信息
-p 端口 自1.5.6默认监听TCP端口
-U udp端口 自1.5.6默认关闭,不适合传输大数据
-e 实现可重启的cache -e /tmpfs_mount/memory_file
默认连接数最多1024
查看配置 echo "stats settings" | nc localhost 11211
配置client
- 一致性hash
- server配置顺序要一致
- 权重 可为分配内存多的memcached实例设置较高的权重
- (memcached集群,由client或proxy负责路由;redis集群,自带分片规则,也可由client或proxy进行路由。)
外部存储
- 将hash table 和 key 存在内存,value存在外部存储。
- 只有1、2个memcached实例,没必要使用外部存储。
- 数据量比key量大很多,且可提升命中率的情况
可重启的cache
自1.5.18
添加启动参数-e /tmpfs_mount/memory_file,向进程发送SIGUSR1 信号,等待退出。
shutdown过程中,会生成/tmpfs_mount/memory_file.meta,并写入cache数据。
restart时从该文件读数据。当某些启动参数变更时,该文件将清空,如-m。
(redis的AOF和RDB可基本保证数据不丢失,不会因为启动参数变更,导致文件清空。)
指令
memcached,针对某个item执行指令。
item构成
key 最多250字节
32bit flag value
超时
相对秒数
0代表不超时
最多设置30天 60*60*24*30
超过30天,server会视为unix timestamp
绝对时间
自1970-1-1 0:0:0的时间
64bit CAS value,确保k-v的唯一性
数据
(memcached只有一种数据结构,可满足cas场景;redis有多种数据结构,使用场景更多。)
指令
set
存储数据,覆盖已有数据,新item位于LRU的top位置。
add
仅当key不存在时,存储数据,新item位于LRU的top位置。
replace
仅当key不存在时,存储数据,很少使用。
append
将数据追加到已存在的item的最后字节之后,可用于管理list。
prepend
将数据插入到已存在的item的第一个字节之前,可用于管理list。
cas
check and set,仅当刚刚访问的item没有被修改
get
获取一个或多个key的数据
gets
获取一个与item相关的CAS ID,用于cas指令,若自gets后casid已经变更,则cas失败。
delete
删除item
incr/decr
当item存储的value是64bit整数的字符串形式时,可执行增加或减少,且参数只允许整数。item不存在则失败。
stats
stats items
stats slabs
stats size
可用于评估slab设置大小
flush_all
将N秒后过期的items置为已超时
性能
单实例轻松达到每秒20w
(比redis单例性能高很多)
内存结构
page-slab-chunk
(memcached对内存切分并分组,用于内存分配;redis没有对内存进行切分。)
memcached将内存分为多个page,每个page大小上限为1M。
page以slab class表示,每个slab可分为多个chunk。在同一slab内部的chunk的大小是相同,不同slab内部的chunk的大小可能是不同的。
举例
$ ./memcached -vv
slab class 1: chunk size 80 perslab 13107
slab class 2: chunk size 104 perslab 10082
slab class 3: chunk size 136 perslab 7710
slab class 4: chunk size 176 perslab 5957
slab class 5: chunk size 224 perslab 4681
slab class 6: chunk size 280 perslab 3744
slab class 7: chunk size 352 perslab 2978
slab class 8: chunk size 440 perslab 2383
slab class 9: chunk size 552 perslab 1899
slab class 10: chunk size 696 perslab 1506
[...etc...]
清晰可见
- 存在多个slab class,如slab class 1
- slab分为多个chunk,例如slab class1,chunk大小为80字节,共有13107个chunk。
item如何选slab
与item大小最相近的chunk,该chunk对应的slab class。
例如item大小50字节,则选择slab class 1,并占用一个chunk。
例如item大小90字节,则选择slab class 2,并占用一个chunk。