首页 Memcache 正文
408

Memcache内存分配机制

  • yiqingpeng
  • 2017-08-09
  • 0
  •  
内存分配的方式有两种:
1、静态分配:预先分配好一定大小的内存,这种分配方式效率高,但有可能会浪费内存空间。
2、动态分配:根据需要实时调整内存大小,这种分配方式效率低,但内存利用率高。

Memcache采用的是静态分配方式。

Memcache内存组织方式:
slab1
page1 page2 pageN
chunk1 chunk2 chunkN chunk1 chunk2 chunkN chunk1 chunk2 chunkN

Slab: 它是具有相同大小的chunk集合,一个Slab包括多个Page, 一个Page包含多个chunk, chunk是最终数据存储的地方。
Page: 默认大小是1M,page1满了之后,分配page2。
Chunk: 数据存储的单位,默认是96B, 以后在每个slab中都是根据倍数因子向上递增。Chunk的实际利用量=key+数据+flag。

Slab Allocator机制是将分配给Memcached的内存,切分成若干个Slab,每个Slab下的Page的大小默认是1M,也就是说,如果一个Slab占用了50M的内存的话,在默认的情况下就有50个Page。在Memcached启动的时候是没有活动的Slab的,在插入数据的时候,如果Chunk不够用才会申请Slab,一旦分配了内存就不会释放,重复利用。

Memcached缓存原理
Memcached根据收到的数据的大小,选择最适合数据大小的Slab,比如数据大小是96B,那么就会将数据放在Slab1中, Memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。

Memcache LRU(最近最少使用算法):
首先我们要知道:
1,Memcached的LRU算法针对每个Slab执行,而不是针对整体。 
2,数据只会存在指定的Slab中,即使该Slab已经满了,而且更大的Slab也有空间,这种情况会在指定的Slab执行LRU算法,因为数据不会被存放到更大的Slab中。

一个Slab会有多个Page,一个page默认是1M,启动Memcached会预分配1M,当1M的数据满之后,如果有新数据进来,那么会重新分配一个Page给这个slab,但是Memcached是有内存上限的,如果不能申请Page的话,这时候就要针对这个Slab再利用LRU算法剔除掉最近最少使用的数据了。

注:
所有的Slab都会分配一个Page,就算超出了-m参数指定的内存大小。
过期的数据如果没被显式调用get,也要占用空间。因为LRU是针对双向链表前面的数据,每个Slab由两个指针来维护该双向链表,即heads和tails指针,分别指向最老的数据和最新的数据。这就可能导致没有过期的数据被踢。

一种有效缓解使用LRU的方法是:
1,避免大对象
如果系统上只有及个别几个大对象的话,会浪费内存空间,因为Slab申请了Page是不能释放内存的,及个别大对象会导致Slab申请了内存资源而得不到充分的利用。
2,调整增长因子
根据项目的需求调整增长因子,使内存充分利用。


总而言之,言而总之,就是让内存充分利用。避免Slab中的Chunk虚位以待。

正在加载评论...