5.2 Memcached内存存储
Memcached默认情况下采用Slab Allocation的机制分配、管理内存。
下面将详细描述数据时如何在Memcached内存中存储,以及如何高效率的管理数据。
5.2.1 Slab Allocation机制
在Slab Allocation机制之前,内存分配都时通过对所有记录简单进行malloc和free来进行的。但是,这种方式会导致内存碎片,家中操作系统内存管理器的负担。其实,Slab Allocation 的原理相当简单,按照预先规定的大小,将分配的内存分隔成各种尺寸的块(chuck),并把尺寸相同的块分组(chunk的集合),注意,分配的块可以重复利用,不释放到内存中。
如图5-5所示,将88、112、144等分别分成了不同的组(slab class)。
介绍几个基本概念
- Page:分配给Slab的内存空间,默认1MB
- Chunk:用于缓存记录的内存空间
- Slab Class:特定大小的chunk的组
如图5-5所示,Chunk的增长因子growth factor默认是1.25。
接下来看一个问题:对于确定的Slab,一个Page可以存储几个?把Page(默认1MB)分给112Bytes的Slab,则可以得到9个Slab(1024/112)
Slab Allocator机制简单来说就是,Memcached根据收到的数据大小,选择合适数据的大小的Slab。Memcached中保存着Slab内空闲Chunk的列表,根据该列表选择Chunk,然后将数据缓存与其中。如图5-6所示,如果需要申请100bytes的空间,则根据Chunks的大小选择Slab Class2
Slab Allocator解决的当初的内存碎片问题,但是新的机制也给Memcached带来了新的问题。这个问题是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如100bytes的空间使用了112字节的Chunk,剩余12字节就浪费了。
5.2.2 使用Growth Factor进行调优
Memcached在启动时指定Growth Factor因子(通过-f选项),就可以在某种程度上控制slab之间的差异,默认值1.25。但是,在该选项出现之前,这个因子层固定位2,称为“powersof2”策略。让我们用以前的设置,以verbose模式启动Memcached试试看,如图5-7所示。
从图5-7中可以了解到Growth Factor因子决定了chunksize的增长幅度差异,图5-7其实就是从128开始持续2倍的策略。采用默认f=1.25,可以得到图5-8所示的分配结果。
可以使用Memcached的stats命令查看slabs的利用率等各种各样的信息,如表5-3所示。
使用Memcached的作者Brad写的名为memcached-tool的perl脚本,可以方便获得slab的使用情况。
5.2.3 Item
item是我们保存的数据,例如:
set name 0 30 5 qiang
代表把一个key 为name、value为qiang的键值对保存在 内存中30s,memcached会把这些数据打包成一个item,每个完整的item包括几个部分:
- key:键
- nkey:键长
- flags:用户自定义的flag
- nbytes:值长
- suffix:后缀Buffer
- nsuffix:后缀长
一个完整的item长度是“键长+值长+后缀长+item结构大小(32字节)” item操作就是根据这个长度来计算slab的classid的。