文章目录
第1章 memcached 的内存管理与删除机制
1.1 内存碎片化
1.2 slab allocator 缓解内存碎片化
1.3 系统如何选择合适的 chunk?
1.4 固定大小 chunk 带来的内存浪费
1.5 grow factor调优
1.6 memcached 的惰性删除机制
1.7 memcached 的lru 删除机制
1.8 memcached 中的一些参数限制
如果用 c 语言直接 malloc,free 来向操作系统申请和释放内存时,在不断的申请和释放过程中,形成了一些很小的内存片断,无法再利用.这种空闲,但无法利用内存的现象,—称为内存的碎片化.
memcached 用 slab allocator 机制来管理内存.
slab allocator 原理: 预告把内存划分成数个 slab class 仓库.(每个 slab class 大小 1M)各仓库,切分成不同尺寸的小块(chunk). (图 3.2)
需要存内容时,判断内容的大小,为其选取合理的仓库.
memcached 根据收到的数据的大小, 选择最适合数据大小的 chunk 组(slab class)memcached 中保存着 slab class 内空闲 chunk 的列表, 根据该列表选择空的 chunk, 然后将数据缓存于其中。
警示:如果有 100byte 的内容要存,但 122 大小的仓库中的 chunk 满了
并不会寻找更大的,如 144 的仓库来存储,
而是把 122 仓库的旧数据踢掉! 详见过期与删除机制
由于 slab allocator 机制中, 分配的 chunk 的大小是”固定”的, 因此, 对于特定的 item,可能造成内存空间的浪费.
比如, 将 100 字节的数据缓存到 122 字节的 chunk 中, 剩余的 22 字节就浪费了
对于 chunk 空间的浪费问题,无法彻底解决,只能缓解该问题.开发者可以对网站中缓存中的 item 的长度进行统计,并制定合理的 slab class 中的 chunk 的大小.
可惜的是,我们目前还不能自定义 chunk 的大小,但可以通过参数来调整各 slab class 中 chunk大小的增长速度. 即增长因子, grow factor!
memcached 在启动时可以通过f 选项指定 Growth Factor 因子, 并在某种程度上控制 slab 之间的差异. 默认值为 1.25. 但是,在该选项出现之前,这个因子曾经固定为 2,称为”powers of 2” 策略。我们:
#分别用 grow factor 为 2 和 1.25 来看一看效果
memcached -f 2 -vvv
...
memcached -f 2.5 -vvv
...
#对比可知, 当 f=2 时, 各 slab 中的 chunk size 增长很快,有些情况下就相当浪费内存.因此,我们应细心统计缓存的大小,制定合理的增长因子.
(注意:当 f=1.25 时,从输出结果来看,某些相邻的 slab class 的大小比值并非为 1.25,可能会觉得有些计算误差,这些误差是为了保持字节数的对齐而故意设置的.)
当某个值过期后,并没有从内存删除, 因此,stats 统计时, curr_item 有其信息
当某个新值去占用他的位置时,当成空 chunk 来占用.
当 get 值时,判断是否过期,如果过期,返回空,并且清空, curr_item 就减少了.
即–这个过期,只是让用户看不到这个数据而已,并没有在过期的瞬间立即从内存删除.这个称为 lazy expiration, 惰性失效.好处— 节省了 cpu 时间和检测的成本
如果以 122byte 大小的 chunk 举例, 122 的 chunk 都满了, 又有新的值(长度为 120)要加入, 要 挤掉谁?memcached 此处用的 lru 删除机制.(操作系统的内存管理,常用 fifo,lru 删除)
lru: least recently used 最近最少使用 fifo: first in ,first out 原理: 当某个单元被请求时,维护一个计数器,通过计数器来判断最近谁最少被使用. 就把谁t出.
(注:即使某个 key 是设置的永久有效期,也一样会被踢出来!
即–永久数据被踢现象)
key 的长度: 250 字节, (二进制协议支持 65536 个字节)
value 的限制: 1m, 一般都是存储一些文本,如新闻列表等等,这个值足够了.
内存的限制: 32 位下最大设置到 2g.
如果有 30g 数据要缓存,一般也不会单实例装 30g, (不要把鸡蛋装在一个篮子里),一般建议 开启多个实例(可以在不同的机器,或同台机器上的不同端口)