memcache内存分配机制

memcache的内存分配机制

前言:应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用,对于这种情况缓存系统不能接受。因此Memcached采用了Slab Allocator机制来分配、管理内存。


(1)Slab Allocator内存分配机制

Memcache按照预先规定的大小,将分配的内存分割成特定长度的块,以解决内存碎片问题。

Memcache的存储涉及到slab,page,chunk三个概念,三者是包含关系,从小到大如下:

  • Page:分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk

  • Chunk:用于缓存记录kv值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes,数据只有100bytes存储在128bytes中,存在些浪费。
    Chunk最大就是Page的大小,即一个Page中就一个Chunk

  • Slab Class:Slab按照大小分组,就组成不同的Slab Class

slab class图示:

示例:如果有100bytes要存,那么Memcached会选择上图中Slab Class 2存储,因为它是120bytes的Chunk。

综上所述:将memcache可以使用的内存按照一定规律进行切片,切完之后的内存空间可以形象的看做快递柜,然后往其中每个’快递柜’中放置key-value,其中存放key-value的单位为’chunk’,当’快递柜’格子被占满时,将按照最近最少使用算法就行相应的覆盖放置。

Slab之间的差异可以使用Growth Factor控制,默认1.25。

(2)懒过期Lazy Expiration

memcached不会监视数据是否过期,而是在取数据时才看是否过期,过期的把数据有效期限标识为0,并不清除该数据。以后可以覆盖该位置存储其它数据。


(3)LRU

当内存不足时,memcached会使用LRU(Least Recently Used)机制来查找可用空间,分配给新纪录使用




memcache的使用
(4)比较重要的几个启动参数

**-f:**增长因子,chunk的值会按照增长因子的比例增长(chunk size growth factor).

**-n:**每个chunk的初始大小(minimum space allocated for key+value+flags),chunk大小还包括本身结构体大小.

**-I:**每个slab page大小(Override the size of each slab page. Adjusts max item size)

**-m:**需要分配的大小(max memory to use for items in megabytes)

-u username memcached运行的用户身份,必须普通用户
-p 绑定的端口,默认11211
-m num 最大内存,单位MB,默认64MB
-c num 最大连接数,缺省1024
-d 守护进程方式运行
-f 增长因子Growth Factor,默认1.25
-v 详细信息,-vv能看到详细信息
-M 内存耗尽,不许LRU
-U 设置UDP监听端口,0表示禁用UDP

(5)Slab Allocator 的缺点

由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100 字节的数据缓存到128 字节的chunk 中,剩余的28字节就浪费了,对于该问题目前还没有完美的解决方案,但是可以通过分析目标应用缓存的大小,来调整chunk的大小以减少浪费。

memcached 在启动时指定Growth Factor因子(通过f选项),就可以在某种程度上控制slab之间的差异。默认值为1.25,可以对存储的key-value进行数据统计大小分析,然后制定合理的Growth Factor因子(没办法,要合理使用内存嘛),一般情况下使用缺省的Growth Factor因子。


(6)memcache启动:
~]# memcached -u memcached -p 11211 -f 1.25 -vv
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       120 perslab    8738
slab class   3: chunk size       152 perslab    6898
slab class   4: chunk size       192 perslab    5461
slab class   5: chunk size       240 perslab    4369
slab class   6: chunk size       304 perslab    3449
slab class   7: chunk size       384 perslab    2730
slab class   8: chunk size       480 perslab    2184
slab class   9: chunk size       600 perslab    1747
slab class  10: chunk size       752 perslab    1394
slab class  11: chunk size       944 perslab    1110
slab class  12: chunk size      1184 perslab     885
slab class  13: chunk size      1480 perslab     708
slab class  14: chunk size      1856 perslab     564
slab class  15: chunk size      2320 perslab     451
slab class  16: chunk size      2904 perslab     361
slab class  17: chunk size      3632 perslab     288
slab class  18: chunk size      4544 perslab     230
slab class  19: chunk size      5680 perslab     184
slab class  20: chunk size      7104 perslab     147
slab class  21: chunk size      8880 perslab     118
slab class  22: chunk size     11104 perslab      94
slab class  23: chunk size     13880 perslab      75
slab class  24: chunk size     17352 perslab      60
slab class  25: chunk size     21696 perslab      48
slab class  26: chunk size     27120 perslab      38
slab class  27: chunk size     33904 perslab      30
slab class  28: chunk size     42384 perslab      24
slab class  29: chunk size     52984 perslab      19
slab class  30: chunk size     66232 perslab      15
slab class  31: chunk size     82792 perslab      12
slab class  32: chunk size    103496 perslab      10
slab class  33: chunk size    129376 perslab       8
slab class  34: chunk size    161720 perslab       6    
slab class  35: chunk size    202152 perslab       5
slab class  36: chunk size    252696 perslab       4
slab class  37: chunk size    315872 perslab       3
slab class  38: chunk size    394840 perslab       2
slab class  39: chunk size    493552 perslab       2
slab class  40: chunk size    616944 perslab       1    #有内存浪费
slab class  41: chunk size    771184 perslab       1    #有内存浪费
slab class  42: chunk size   1048576 perslab       1
<26 server listening (auto-negotiate)
<27 server listening (auto-negotiate)
<28 send buffer was 212992, now 268435456
<29 send buffer was 212992, now 268435456
<28 server listening (udp)
<29 server listening (udp)
<28 server listening (udp)
<29 server listening (udp)
<28 server listening (udp)
<29 server listening (udp)
<28 server listening (udp)
<29 server listening (udp)

==> 预创建了这些slab class,按照增长因子1.25创建至1M一个,不够使用再创建划分至相同slab class下,memcache默认使用内存64M。


(7)与memcached通信的不同语言的连接器
  • libmemcached提供了C库和命令行工具。
# yum list all | grep memcached
memcached.x86_64 1.4.15-10.el7_3.1 @base
libmemcached.i686 1.0.16-5.el7 base
libmemcached.x86_64 1.0.16-5.el7 base
libmemcached-devel.i686 1.0.16-5.el7 base
libmemcached-devel.x86_64 1.0.16-5.el7 base
memcached-devel.i686 1.4.15-10.el7_3.1 base
memcached-devel.x86_64 1.4.15-10.el7_3.1 base
opensips-memcached.x86_64 1.10.5-4.el7 epel
php-ZendFramework-Cache-Backend-Libmemcached.noarch
php-pecl-memcached.x86_64 2.2.0-1.el7 epel
python-memcached.noarch 1.48-4.el7 base
uwsgi-router-memcached.x86_64 2.0.17.1-2.el7 epel

(8)memcache协议:
  • 查看/usr/share/doc/memcached-1.4.15/protocol.txt
add mykey 1 60 4
    keyname  flags  存活时间  多少字节

add key flags exptime bytes , 增加key,过期时间为秒,bytes为存储数据的字节数



参考: https://www.jianshu.com/p/0e7629401a2e
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值