memcached存储机制研究

声明:

1、本文需要对memcache有一定了解

2、测试用memcached版本1.4.5

3、错误之处恳请指正!

 

很早就听说用memcached缓存数据,在分配内存未用尽时偶尔也会出现踢出未过期数据的问题。对此一直不是很理解,由于项目遇到应用选择问题,所以专门对其进行了些测试和研究。

 

首先简单介绍几个名词,了解过memcache原理的应该都不陌生:

chunk 数据存放的最小单元,不同slab中的chunk大小不同

page 内存页,每页有若干相同大小的chunk

slab 数据区,每区有一个以上的page(动态分配)

 

存储原理

当开启一个memcached服务时,它会初始化若干个slab以及对应的chunk,但是此时仅是结构,并没有真正分配实际内存。例如:

# /usr/local/bin/memcached -d -m 1m -u root -l 192.168.1.60 -p 12000 -c 256 -f 1.25 -vv

需要注意的几个参数:

-m 1m:为该守护分配1M存储空间

-f 1.25:不同slab中chunk大小的增长幅度,默认为1.25倍

-vv:测试用,方便查看分配情况

启动后会显示如下信息:

 

 

slab class   1: chunk size        80 perslab   13107 ----》slab1中chunk大小为80字节,每页有13107个chunk

slab class   2: chunk size       104 perslab   10082 ---》slab2中chunk大小约为80*1.25字节(该处会考虑到数据对齐,可能不是严格的倍数值),每页有10082个chunk

slab class   3: chunk size       136 perslab    7710 ---》slab3中chunk大小约为104*1.25

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

slab class  11: chunk size       872 perslab    1202

slab class  12: chunk size      1096 perslab     956

slab class  13: chunk size      1376 perslab     762

slab class  14: chunk size      1720 perslab     609

slab class  15: chunk size      2152 perslab     487

slab class  16: chunk size      2696 perslab     388

slab class  17: chunk size      3376 perslab     310

slab class  18: chunk size      4224 perslab     248

slab class  19: chunk size      5280 perslab     198

slab class  20: chunk size      6600 perslab     158

slab class  21: chunk size      8256 perslab     127

slab class  22: chunk size     10320 perslab     101

slab class  23: chunk size     12904 perslab      81

slab class  24: chunk size     16136 perslab      64

slab class  25: chunk size     20176 perslab      51

slab class  26: chunk size     25224 perslab      41

slab class  27: chunk size     31536 perslab      33

slab class  28: chunk size     39424 perslab      26

slab class  29: chunk size     49280 perslab      21

slab class  30: chunk size     61600 perslab      17

slab class  31: chunk size     77000 perslab      13

slab class  32: chunk size     96256 perslab      10

slab class  33: chunk size    120320 perslab       8

slab class  34: chunk size    150400 perslab       6

slab class  35: chunk size    188000 perslab       5

slab class  36: chunk size    235000 perslab       4

slab class  37: chunk size    293752 perslab       3

slab class  38: chunk size    367192 perslab       2

slab class  39: chunk size    458992 perslab       2

slab class  40: chunk size    573744 perslab       1

slab class  41: chunk size    717184 perslab       1

slab class  42: chunk size   1048576 perslab       1

 

此时并没有开放实际存储数据的内存块,也就是之前分配的1M还没有用到。但是注意,此时memcached会为每一类slab发放一个page的权限(默认每页为1M),也就是说每个slab都能存入1M的数据,所以实际内存占用将不仅仅是之前分配的1M!当然该例子这是比较极端情况。

有数据进来时,memcached会先判断该数据的大小符合哪一类slab从而将其存入,例如40B的话会选择存入slab1;500B的话则会存入slab9。

假设为该守护分配足够大的内存空间,当slab1的第一个page被填满,则程序会动态分配一个新page,其他页也如此。

假设分配的内存已被用尽,其他新的slab则只能使用初始化时分配的那唯一一个page,而不能动态分配新的page。新数据只能通过LRU算法覆盖该slab中已存在的chunk,前提是chunk中数据设置了过期时间,否则不对其进行LRU而优先覆盖(貌似是这样的)。

 

将1M数据写满后,进telnet用stats slabs查看结果:

 

# telnet 192.168.1.60 12000

Trying 192.168.1.60...

Connected to localhost (192.168.1.60).

Escape character is '^]'.

stats slabs

STAT 1:chunk_size 80 ---------> 该slab中每块chunk的大小

STAT 1:chunks_per_page 13107 -> 每页包含的chunk数量

STAT 1:total_pages 1 ---------> 该slab目前所用的页数

STAT 1:total_chunks 13107 ----> 该slab总共的chunks

STAT 1:used_chunks 13107 -----> 现在已使用有效的chunks

STAT 1:free_chunks 0 ---------> 过期释放掉的chunks

STAT 1:free_chunks_end 0 -----> 剩余未使用的chunks

STAT 1:mem_requested 722882

STAT 1:get_hits 0

STAT 1:cmd_set 13107

STAT 1:delete_hits 0

STAT 1:incr_hits 0

STAT 1:decr_hits 0

STAT 1:cas_hits 0

STAT 1:cas_badval 0

STAT active_slabs 1

STAT total_malloced 1048560

END

 

 

最后需要注意的几点:

1、存入数据时会优先使用已过期数据的空间,再使用未被使用的空间,即free_chunks会比free_chunks_end先用掉

2、存入数据时会优先使用未设置过期时间的数据空间,不再对其使用LRU算法(当成已过期数据?)

3、这里的LRU算法指的是“最近最久未被使用”,而不是“最近最少使用”

4、memcache确实只适合用来作为缓存,万不可将其用于可高可靠性需求的场合

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值