Memcached学习笔记之memcached的内存管理与删除机制

memcached的内存管理与删除机制

1、内存的碎片化####

  如果用c语言直接malloc,free来向操作系统申请和释放内存时,在不断的申请和释放过程中,形成了一些很小的内存片段,无法再利用,这种空闲,但无法利用内存的现象 ---成为内存的碎片化

2、slab allocator缓解内存碎片化####

  memcached用slab allocator机制来管理内存。
salb allocator原理:预先把内存划分成数个slab class仓库(每个slab class大小1M),各仓库切分成不同尺寸的小块(chunk)如下图:

3、系统如何选择合适的chunk###

  memcached根据收到的数据的大小,选择最适合数据大小的chunk组(slab class)。memcached中保存着slab class内空闲chunk的列表,根据该列表选择空的chunk,然后将数据缓存与其中。如下图:

注意:
如果有100byte的内容要存,但122大小的仓库中的chunk满了,并不会寻找更大的,如144的仓库来存储,而是把122仓库的旧数据踢掉!

4、固定大小的chunk带来的内存浪费###

  由于slab allocator机制中,分配的chunk的大小是固定的,因此,对于特定的item,可能造成内存空间的浪费。比如,将100字节的数据缓存到122字节的chunk中,剩余的22字节就浪费了,如下图:

  对于chunk空间的浪费问题,无法彻底解决,只能缓解该问题。开发者可以对网站中缓存中的item的长度进行统计,并制定合理的slab class中的chunk的大小。可惜的是,我们目前还不能自定义chunk的大小,但可以通过参数来调整各slab class中chunk大小的增长速度,即增长因子,grow factor

5、grow factor调优###

  memcached在启动时可以通过-f选项指定growth factor因子,并在某种程度上控制slab之间的差异,默认值为1.25。但是,在该选项出现之前,这个因子曾经固定为2,成为'powers of 2'策略。我们分别用grow factor为2和1.25来看一看效果:

可见,从96字节的组开始,组的大小依次增大为原来的2倍,来看看f=1.25的输出:

对比可知,当f=2时,各slab中的chunk size增长很快,有些情况下就相当浪费内存,因此,我们应该细心统计缓存的大小,指定合理的增长因子。

注意:
当f=1.25时,从输出结果来看,某些相邻的slab class的大小比值并非为1.25,可能会觉得有些计算误差,这些误差是为了保持字节数的对其而故意设置的。

6、memcached的过期数据惰性删除###

1、当某个新值过期后,并没有从内存中删除,因此,stats统计时,curr_item有其信息
2、当某个新值去占用它的位置时,当成空chunk来占用
3、当get值时,判断是否过期,如果过期,返回空,并且清空,curr_item就减少了
即--这个过期,只是让用户看不到这个数据而已,并没有在过期的瞬间立即从内存中删除,这个称谓 lazy expiration 惰性失效
好处--节省了cpu时间和检测的成本

7、memcached的lru删除机制###

  如果以122byte大小的chunk举例,122的chunk都满了,又有了新的值(长度为120)要加入,要挤掉谁?
memcached此处用的lru删除机制,(操作系统的内存管理,常用fifo,lru删除)
lru : least recently used 最近最少使用
fifo : first in,first out
原理:当某个单元被请求时,维护一个计数器,通过计数器来判断最近谁最少被使用,就把谁踢出去。

注:
即使某个key是设置的永久有效期,也一样会被踢出去,即--永久数据被踢现象

8、memcached中的一些参数限制###

key的长度:250字节(二进制协议支持65536个字节)
values的限制:一般都是存储一些文本,如新闻列表等等,这个值足够了。
内存的限制:32位下最大设置到2G.
如果有30g的数据要缓存,一般也不会单实例装30G,一般建议开启多个示例(可以在不同的机器,或同台机器的不同端口)。

posted @ 2017-02-22 15:05  FullStackMe  阅读(84)  评论(0)    收藏  举报