memcached内存分配原理及相应源码解析

        memcached默认情况下是采用Slab Allocator的机制分配、管理内存,此原理相当简单,将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合),如下图(借鉴于《memcached全面剖析》):

 

关于此块的初始化逻辑划分的源码在memcached.c文件中:

 

void slabs_init(const size_t limit, const double factor, const bool prealloc) {

……//此处省略很多行

 

     while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {

 

         if (size % CHUNK_ALIGN_BYTES)

             size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

 

         slabclass[i].size = size;

         slabclass[i].perslab = settings.item_size_max / slabclass[i].size;

         size *= factor;

         if (settings.verbose > 1) {

             fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",

                     i, slabclass[i].size, slabclass[i].perslab);

         }

     }

 

     power_largest = i;

     slabclass[power_largest].size = settings.item_size_max;

     slabclass[power_largest].perslab = 1;

……//此处省略很多行

}

如上面的代码部分,POWER_LARGEST表示的是可以分配的chunk组数,默认的是200;settings.item_size_max是表示最大的item大小,也即chunk块的默认最大值,默认值是1024* 1024,这两个值都是直接写死在程序里,没有配置文件可供配置。 factor是chunk大小的增长因子,在启动memcached的时候有-f参数来指定。

上边size的大小初始化为size = sizeof(item) + settings.chunk_size;(其中 settings.chunk_size默认为48),所以从下面的代码:

            if (size % CHUNK_ALIGN_BYTES)

                 size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

最小的chunk大小也会>=56;

第一组的chunk信息就是,每个chunk的大小:         slabclass[i].size = size;

本组内chunk的个数为:                                           slabclass[i].perslab = settings.item_size_max / slabclass[i].size;

第二主信息:

以增长因子 factor的的速度增长size *= factor;但是要慢组大小被 CHUNK_ALIGN_BYTES整除,即size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);

个数的算法也同样

……

 

最后一组,

     slabclass[power_largest].size = settings.item_size_max;

     slabclass[power_largest].perslab = 1;

即一组只有一个chunk,大小为设置的最大值。

 

如果在使用的时候,你发现你的应用场景1M大小的chunk根本不够存储你的一个item,此时,我们需要做的就是修改原文件中settings.item_size_max;的值,位置在memcached.c文件的setting_init(void)函数中;比如我的修改值128 * 1024 * 1024; //64M

-vv模式启动memcached:

 

slab class   1: chunk size    160032 perslab     838

slab class   2: chunk size    240048 perslab     559

slab class   3: chunk size    360072 perslab     372

slab class   4: chunk size    540112 perslab     248

slab class   5: chunk size    810168 perslab     165

slab class   6: chunk size   1215256 perslab     110

slab class   7: chunk size   1822888 perslab      73

slab class   8: chunk size   2734336 perslab      49

slab class   9: chunk size   4101504 perslab      32

slab class  10: chunk size   6152256 perslab      21

slab class  11: chunk size   9228384 perslab      14

slab class  12: chunk size  13842576 perslab       9

slab class  13: chunk size  20763864 perslab       6

slab class  14: chunk size  31145800 perslab       4

slab class  15: chunk size  46718704 perslab       2

slab class  16: chunk size  70078056 perslab       1

slab class  17: chunk size 134217728 perslab       1

可以看到最大的chunk size为134217728 即128M大小,这样我最的item的值被增加到128m的大小。
 
注:以上仅仅为实验得到的数据,还不知道如此实用对于性能上会不会造成很大的影响。

posted on 2012-03-29 09:23  aho  阅读(331)  评论(0编辑  收藏  举报

导航