码迷,mamicode.com
首页 > 系统相关 > 详细

memcached内存管理机制详解

时间:2014-12-06 20:20:59      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:memcached   内存管理   

    我们知道,memcached是一个内存缓存系统,因此对于内存的管理是需要使用者了解的。本文将对memcached的内存模型及管理机制做一个详细的描述。

基本概念

    在开始之前,有必要先了解几个基本概念:
    1、slab class:在memcached中,对元素的管理是以slab为单元进行管理的。每个slab class对应一个或多个空间大小相同的chunk。参考下图一。
    2、chunk:存放元素的最小单元。用户数据item(key、value等)最终会保存在chunk中。memcached会根据元素大小将其放到合适的slab class中。每一个slab class中的chunk空间大小是一样的,所以元素存放进来后,chunk可能会有部分空间剩余。参考下图二、下图三。
    3、page:大小固定为1MB。当slab class空间不足时,就会申请page,并将page按chunk的大小进行切割。
bubuko.com,布布扣
                                                  图一  slab class逻辑结构图

bubuko.com,布布扣
                                                图二  元素存入memcached会寻找最合适的slab class
bubuko.com,布布扣
                                                图三 元素放入chunk时可能会有空间浪费

    memcached使用自己的内存管理机制,可以有效避免系统内存碎片,避免给操作系统带来负担。

内存如何分配给元素

启动memcached时,以-m指定大小的内存将会用于数据的存放。默认情况下,这些内存会被分隔成1M的page。每个page在必要时分配给slab class,然后根据slab class里chunk的大小,将page分隔成chunk。
一旦一个page被赋给一个slab class后,它将不会再被移动。因为内存空间有限,如果在slab class 3中使用了较多的page,那么在slab class 4中就只能使用较少的page。可以这么认为,memcached是一个有很多更小的相互独立的缓存系统,每一个更小的缓存系统实际上就是slab class。每个slab class都有它自己的统计信息以及自己的LRU。
在启动memcached时,指定-vv参数,可以在启动日志中查看每个slab class的chunk大小。
$ ./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
[...etc...]
在slab class 1中,每个chunk大小为80字节,每个页面包含13107个chunk(或item)。这两个数相乘,应该最近接1个page的大小(默认是1MB)。
当存储元素时,它们将被放到最合适的slab class中。例如,50字节的元素(包含key、value等信息)将被存放到slab class 1中的chunk,根据之前的说明,此chunk中将会有30字节的空间浪费。如果存放数据总共有90字节,将被存放到slab class 2中,此时会有14字节的空间浪费。
启动时,通过设置参数-f,可以设置每个slab class下chunk的空间增长率。
另外,memcached因为一些其他功能也会使用内存空间。例如:用来查找元素的hash table;连接时也会使用一些缓存。当然,这些功能只会占用很少一部分内存空间。

内存什么时候被回收

与redis不同的是,memcached不会主动回收内存。
如果获取了一个已失效的元素,memcached将会释放内存。后续再将新的元素存放进来时,将会重用此内存。(前提是新元素也是要存放在同一slab class中。)
由于LRU,元素将被踢出以让给新的元素,或发现有过期的元素,它们的内存将被重用。

一个元素将会使用多大空间

除了数据需要占用空间,一个元素本身也占用空间:key的长度、元素的内部数据结构、数据的长度。
可以使用memcached提供的命令./sizes查看占用空间大小。
$ ./sizes 
Slab Stats	56
Thread stats	176
Global stats	108
Settings	88
Item (no cas)	32
Item (cas)	40
Libevent thread	96
Connection	320
----------------------------------------
libevent thread cumulative	11472
Thread stats cumulative		11376

元素什么时候被踢出

如果元素还没有失效(失效日期为0或者将会在将来失效),slab class已经用完了所有空闲的chunk,并且没有空闲的page可以分配给此slab class,此时将会执行LRU,将元素踢出。

LRU怎么决定哪个元素被踢出

当存放新的元素时,内存也可能会被回收。如果在相应的slab class里,既没有空闲的chunk,也没有空闲的page,memcached将会使用LRU算法查找应该被回收的元素。它将会查找LRU列表中尾部(最近最少使用)的一些元素,看它们是否已经失效,如果存在失效的元素,则将此元素占用的空间重用。如果找不到失效的元素,那么将踢出最尾部还没有失效的元素。






memcached内存管理机制详解

标签:memcached   内存管理   

原文地址:http://blog.csdn.net/ado1986/article/details/41774891

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!