memcached的内存管理机制

memcached是一个高效的分布式内存cache,默认使用SlabAllocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。
SlabAllocation机制只为存储外部数据而设计,也就是说所有的key-value数据都存储在SlabAllocation系统里,而memcached的其它内存请求则通过普通的malloc/free来申请,因为这些请求的数量和频率决定了它们不会对整个系统的性能造成影响。

Slab和Chunk

这里写图片描述

slab是memcached一次申请内存的最小单位。memcached启动时使用参数-m指定其可用内存,但并不是启动时所有的内存就全部分配出去了,只有在需要时才会去申请,而且每次申请一定是一个slab。Slab的大小固定为1M(1048576 Byte)。

一个slab由若干个大小相等的chunk组成。每个chunk中都保存了一个item结构体、一对key和value。

虽然在同一个slab中chunk的大小相等的,但是在不同的slab中chunk的大小并不一定相等,在memcached中按照chunk的大小不同,可以把slab分为很多种类(class)。

在启动memcached的时候可以通过-vv来查看slab的种类:

$ 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
slab class 11: chunk size 872 perslab 1202
slab class 12: chunk size 1096 perslab 956
slab class 13: chunk size 1376 perslab 762
slab class 14: chunk size 1720 perslab 609
slab class 15: chunk size 2152 perslab 487
slab class 16: chunk size 2696 perslab 388
slab class 17: chunk size 3376 perslab 310
slab class 18: chunk size 4224 perslab 248
slab class 19: chunk size 5280 perslab 198
slab class 20: chunk size 6600 perslab 158
slab class 21: chunk size 8256 perslab 127
slab class 22: chunk size 10320 perslab 101
slab class 23: chunk size 12904 perslab 81
slab class 24: chunk size 16136 perslab 64
slab class 25: chunk size 20176 perslab 51
slab class 26: chunk size 25224 perslab 41
slab class 27: chunk size 31536 perslab 33
slab class 28: chunk size 39424 perslab 26
slab class 29: chunk size 49280 perslab 21
slab class 30: chunk size 61600 perslab 17
slab class 31: chunk size 77000 perslab 13
slab class 32: chunk size 96256 perslab 10
slab class 33: chunk size 120320 perslab 8
slab class 34: chunk size 150400 perslab 6
slab class 35: chunk size 188000 perslab 5
slab class 36: chunk size 235000 perslab 4
slab class 37: chunk size 293752 perslab 3
slab class 38: chunk size 367192 perslab 2
slab class 39: chunk size 458992 perslab 2
slab class 40: chunk size 573744 perslab 1
slab class 41: chunk size 717184 perslab 1
slab class 42: chunk size 1048576 perslab 1

从上图可以看到,默认情况下memcached把slab分为40类(class1~class40),在class 1中,chunk的大小为80字节,由于一个slab的大小是固定的1048576字节(1M),因此在class1中最多可以有13107个chunk:
13107×80 + 16 = 1048576
在class1中,剩余的16字节因为不够一个chunk的大小(80byte),因此会被浪费掉。

每类chunk的大小有一定的计算公式的,假定i代表分类,class i的计算公式如下:

chunk size(class i) :  (default_size+item_size)*factor^(i-1)+ CHUNK_ALIGN_BYTES

// default_size: 默认大小为48字节,也就是memcached默认的key+value的大小为48字节,可以通过-n参数来调节其大小。
// item_size: item结构体的长度,固定为32字节。default_size大小为48字节,item_size为32,因此class1的chunk大小为48+32=80字节。
// factor: chunk变化大小的因素,默认值为1.25,调节f可以影响chunk的步进大小,在启动时可以使用-f来指定;认为factor在1.05~2范围内是合理的。
// CHUNK_ALIGN_BYTES: 一个修正值,用来保证chunk的大小是某个值的整数倍(在32位机器上要求chunk的大小是4的整数倍)。

内存申请分配

这里写图片描述

向memcached添加一个item时候,memcached首先会根据item的大小,来选择最合适的slab class。
例如,item的大小为190字节,class 4的chunk大小为176字节不足以分配,class 5的chunk大小为224字节,大于190字节,因此该item将放在class 5中(显然这里会有34字节的浪费是不可避免的)是比较合适的。

计算好所要放入的chunk之后,memcached会去检查该类大小的chunk还有没有空闲的,如果没有,将会申请1M(1个slab)的空间并划分为该种类chunk。
例如,我们第一次向memcached中放入一个190字节的item时,memcached会产生一个slab class 5(也叫一个page),并会用去一个chunk,剩余4680个chunk供下次有适合大小item时使用,当我们用完这所有的4681个chunk之后,下次再有一个在177~224字节之间的item添加进来时,memcached会再次产生一个class 5的slab(这样就存在了2个pages)。

删除策略

memcached删除策略是Lazy Expiration

  1. 当存储在内存中的对象过期甚至是flush_all时,它并不会做检查或删除操作,只有在get时查看数据的时间戳,查看数据是否过期。
  2. 删除数据时,memcached同样是懒删除机制,只在对应的数据对象上做删除标识并不回收内存,在下次分配时直接覆盖使用。
  3. 当memcached内存空间不足,即无法从slab class中获取到新的空间时,memcached使用LRU删除机制从最近未被使用的数据中搜索,将其空间分配给新的数据。
// 操作系统的内存管理,常用 FIFO,LRU 删除
LRU: Least Recently Used 最近最少使用
FIFO: First In ,First Out 先进先出

参考:
http://blog.csdn.net/think2me/article/details/52091740
http://www.cnblogs.com/codershuai/p/6150002.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值