今天研究了一下memcache的内存分配策略,发现其和redis的确是有很大不同的,很多人知道memcache是提前预占用内存的,并且,其内存的占用是定长的,所以其内存的占用是可以被计算出来的。但是,其分配策略不是那么简单的,其合理的设置调优,也并不是那么容易的事情。下面就讲一下我的理解。以及-m参数认为无效的原因。

理解memcache的确必须先理解 slab、page、chunk 三个概念。page组成了slab,chunk组成了page,chunk是数据真实存储的位置,默认情况下,page的大小是1M,当然这个可以通过参数修改,chunk默认从96B开始,以1.25的倍数在slab区间增长。即,slab1 的chunk为96B,那slab2的所有chunk都是120B,那slab3的所有chunk就是150B,依次类推。因为page大小都是1m,那么相当于chunk的个数就确定了,如果slab1有一个page,那么就应该有10922个chunk,在内存未达到配置内存上限的时候,这个page是可以增加的,但是这里增加的单位就是page,也就是1M,比如已经存了10922个96B以下数据的key,再存一个新的,内存又没有达到配置上限,就会page增加,相应的也就再增加10922个chunk。下面具体代码看一下

启动命令

启动命令就定死了其slab的分配规则,这样就能看到数据616944以上的,一个page也就只能存一个了,也就是就会占用1M的内存,其最大是不能存储1M以上的,除非你将page的配置设置1M以上,或者数据压缩。

这个时候看一下telnet localhost 11212    stats slabs

可以看到,当其没有数据的时候,规则虽然确定,但是没有真的去分配内存的。

使用php脚本存入一个值

再次运行stats slabs

发现其开始分配内存,并且直接占用了1M内存(total_malloced 1048512),used_chunks 1

我们试试存储超过10922个key

发现结果

page变成了2, total_malloced也为2M,我们启动的时候-m为2也就是说运行其使用的内存就是2M,那试一下超过2M

结果:

我们发现所有的21844个chunk全被占用,内存没有增加,这个时候肯定就有数据比淘汰了,也就是被新的key替换了。

但是如果我们测试96B以上的数据

结果:

其占用的slab5,内存突破了2M,又加了1M,我换了key,所以肯定是新增,slab1的没有动,还是占满的。这个数据为什么占用的比实际130B大,使用的是slab5应该是key等也需要内存的占用,这些不管,这也说明了-m参数的原则是在slab不变的情况下,不能突破限制,但是如果遇到数据有其他slab,那么他就会再增加一个page的大小,这也就是有的人说-m配置没有作用的原因,实际上不是没有作用。我们测试能否这个slab5出现两个page,我只要循环大于4369即可,因为240一个chunk这里STAT 5:chunks_per_page 4369

结果:

内存没有再增加,slab5的所有chunk被占满了,page没有增加,这里也就是说,其做大就是内存达到-m限制后,再新增的slab区间,每增加一个,就加一个page的大小,比如-m 2,如果slab1已经占满了2M,那其极限内存,就是2M+42*page的大小,不会再变化。所以其策略就是,一旦slab被分配是不会再变化的

 

 

程序本天成,妙手偶得之!我们只是代码的搬运工!

转载请注明:http://www.521php.com/archives/2039/

目前有4 条留言

  1. 2016年12月10日 下午 3:16 广告任务网   |  引用  |  #1     

    日复一日,年复一年,你的博客,让人流连!

  2. 2016年12月12日 下午 3:21 chao   |  引用  |  #2     

    测试php7评论

  3. 2016年12月13日 上午 8:49 蒂欧娜   |  引用  |  #3     

    今天真冷,哈哈!

  4. 2021年10月01日 下午 5:17 ChuHai5   |  引用  |  #4     

    新手,学习中,多谢啦

发表评论

昵称:

网址:

eg.博客主题调用的是Gravatar头像,你可以通过邮箱注册获得头像.
/ 快捷键:Ctrl+Enter