Memcached存储机制
slab class 1: chunk size 88 perslab 11915slab class 2: chunk size 112 perslab 9362slab class 3: chunk size 144 perslab 7281slab class 4: chunk size 184 perslab 5698slab class 5: chunk size 232 perslab 4519slab class 6: chunk size 296 perslab 3542slab class 7: chunk size 376 perslab 2788slab class 8: chunk size 472 perslab 2221slab class 9: chunk size 592 perslab 1771slab class 10: chunk size 744 perslab 1409slab class 11: chunk size 936 perslab 1120slab class 12: chunk size 1176 perslab 891slab class 13: chunk size 1472 perslab 712slab class 14: chunk size 1840 perslab 569slab class 15: chunk size 2304 perslab 455slab class 16: chunk size 2880 perslab 364slab class 17: chunk size 3600 perslab 291slab class 18: chunk size 4504 perslab 232slab class 19: chunk size 5632 perslab 186slab class 20: chunk size 7040 perslab 148slab class 21: chunk size 8800 perslab 119slab class 22: chunk size 11000 perslab 95slab class 23: chunk size 13752 perslab 76slab class 24: chunk size 17192 perslab 60slab class 25: chunk size 21496 perslab 48slab class 26: chunk size 26872 perslab 39slab class 27: chunk size 33592 perslab 31slab class 28: chunk size 41992 perslab 24slab class 29: chunk size 52496 perslab 19slab class 30: chunk size 65624 perslab 15slab class 31: chunk size 82032 perslab 12slab class 32: chunk size 102544 perslab 10slab class 33: chunk size 128184 perslab 8slab class 34: chunk size 160232 perslab 6slab class 35: chunk size 200296 perslab 5slab class 36: chunk size 250376 perslab 4slab class 37: chunk size 312976 perslab 3slab class 38: chunk size 391224 perslab 2slab class 39: chunk size 489032 perslab 2<96 server listening<112 server listening<116 send buffer was 8192, now 268435456<116 server listening (udp)<120 new client connection<120 exit>120 ERROR<120 quit<120 connection closed.<120 new client connection
statsSTAT pid 12212STAT uptime 10STAT time 1367559145STAT version 1.2.6STAT pointer_size 32STAT curr_items 0STAT total_items 0STAT bytes 0 --已存数据大小STAT curr_connections 3STAT total_connections 4STAT connection_structures 4STAT cmd_get 0STAT cmd_set 0STAT get_hits 0STAT get_misses 0STAT evictions 0STAT bytes_read 11STAT bytes_written 7STAT limit_maxbytes 33554432---最大容量STAT threads 1END
Slab的大小是怎么算出来的呢?
?
?
public static void main(String[] arg){ byte[] arr=new byte[1024*6]; //使用7k的块 int i=0; int n=i+140; for(;i<n;i++){ boolean status=MemcachedUtil.getInstance().set(String.valueOf(System.currentTimeMillis()+""+i), arr,60*60); if(!status){ System.out.println("------------------------------"); } System.out.println(status); } }
stats slabsSTAT 20:chunk_size 7040 --块大小STAT 20:chunks_per_page 148 ----每个page中块数量STAT 20:total_pages 1 --------只有一个pageSTAT 20:total_chunks 148 ---第20个slab级别的块数量总和= total_pages* chunks_per_pageSTAT 20:used_chunks 148STAT 20:free_chunks 0STAT 20:free_chunks_end 8STAT active_slabs 1STAT total_malloced 1041920 ---所有数据占用内存=140*(7040+key所占内存)ENDstats itemsSTAT items:20:number 140STAT items:20:age 241STAT items:20:evicted 0STAT items:20:outofmemory 0ENDstats sizes6240 140END
int i=0;int n=i+8;
stats slabsSTAT 20:chunk_size 7040STAT 20:chunks_per_page 148STAT 20:total_pages 1STAT 20:total_chunks 148STAT 20:used_chunks 148STAT 20:free_chunks 0STAT 20:free_chunks_end 0 ---第一个page中148个chunk全部占用STAT active_slabs 1STAT total_malloced 1041920ENDstats itemsSTAT items:20:number 148STAT items:20:age 407STAT items:20:evicted 0STAT items:20:outofmemory 0END
int i=0;int n=i+1;
stats slabsSTAT 20:chunk_size 7040STAT 20:chunks_per_page 148STAT 20:total_pages 2 -----新加了一个pageSTAT 20:total_chunks 296STAT 20:used_chunks 296STAT 20:free_chunks 0STAT 20:free_chunks_end 147STAT active_slabs 1STAT total_malloced 2083840ENDstats itemsSTAT items:20:number 149 ---总过有149个块被使用STAT items:20:age 1053STAT items:20:evicted 0STAT items:20:outofmemory 0END
?
stats slabsSTAT 20:chunk_size 7040STAT 20:chunks_per_page 148STAT 20:total_pages 32STAT 20:total_chunks 4736STAT 20:used_chunks 4736STAT 20:free_chunks 0STAT 20:free_chunks_end 0STAT active_slabs 1STAT total_malloced 33341440END
byte[] arr=new byte[1024*6]; //使用7k的块 MemcachedUtil.getInstance().set("first1", arr,60*60); MemcachedUtil.getInstance().set("first2", arr,60*60); MemcachedUtil.getInstance().set("first3", arr,60*60); MemcachedUtil.getInstance().set("first4", arr,60*60); int i=1; int n=i+4732; for(;i<n;i++){ boolean status=MemcachedUtil.getInstance().set(String.valueOf(i), arr,60*60); } MemcachedUtil.getInstance().set("last1", arr,60*60); MemcachedUtil.getInstance().set("last2", arr,60*60); MemcachedUtil.getInstance().set("last3", arr,60*60); MemcachedUtil.getInstance().set("last4", arr,60*60); System.out.println(MemcachedUtil.getInstance().get("first1")); System.out.println(MemcachedUtil.getInstance().get("first2")); System.out.println(MemcachedUtil.getInstance().get("first3")); System.out.println(MemcachedUtil.getInstance().get("first4")); System.out.println(MemcachedUtil.getInstance().get("last1")); System.out.println(MemcachedUtil.getInstance().get("last2")); System.out.println(MemcachedUtil.getInstance().get("last3")); System.out.println(MemcachedUtil.getInstance().get("last4"));
nullnullnullnull[B@46a5c4[B@2d09e0[B@e38fca[B@1f528ab
stats itemsSTAT items:20:number 4736STAT items:20:age 87STAT items:20:evicted 4STAT items:20:outofmemory 0END
byte[] arr=new byte[1024*8]; //使用8k的块 MemcachedUtil.getInstance().set("new1", arr,60*60); System.out.println(MemcachedUtil.getInstance().get("new1"));
stats slabs=================slab20的状态没变化STAT 20:chunk_size 7040STAT 20:chunks_per_page 148STAT 20:total_pages 32STAT 20:total_chunks 4736STAT 20:used_chunks 4736STAT 20:free_chunks 0STAT 20:free_chunks_end 0============数据被放在了slab21中,新开了一个slab21的pageSTAT 21:chunk_size 8800STAT 21:chunks_per_page 119STAT 21:total_pages 1STAT 21:total_chunks 119STAT 21:used_chunks 119STAT 21:free_chunks 0STAT 21:free_chunks_end 118STAT active_slabs 2STAT total_malloced 34388640ENDstats itemsSTAT items:20:number 4736STAT items:20:age 283STAT items:20:evicted 4STAT items:20:outofmemory 0STAT items:21:number 1STAT items:21:age 22STAT items:21:evicted 0STAT items:21:outofmemory 0END
?
byte[] arr=new byte[1024*8]; //使用8k的块 int i=1; int n=i+118; for(;i<n;i++){ boolean status=MemcachedUtil.getInstance().set("newnew"+String.valueOf(i), arr,60*60); } System.out.println(MemcachedUtil.getInstance().get("newnew118"));
stats slabsSTAT 20:chunk_size 7040STAT 20:chunks_per_page 148STAT 20:total_pages 32STAT 20:total_chunks 4736STAT 20:used_chunks 4736STAT 20:free_chunks 0STAT 20:free_chunks_end 0STAT 21:chunk_size 8800STAT 21:chunks_per_page 119STAT 21:total_pages 1STAT 21:total_chunks 119STAT 21:used_chunks 119STAT 21:free_chunks 0STAT 21:free_chunks_end 0 ---已全部被占用STAT active_slabs 2STAT total_malloced 34388640ENDstats itemsSTAT items:20:number 4736STAT items:20:age 579STAT items:20:evicted 4STAT items:20:outofmemory 0STAT items:21:number 119STAT items:21:age 318STAT items:21:evicted 0STAT items:21:outofmemory 0END
?
MemcachedUtil.getInstance().set("newnewnew0", arr,60*60); System.out.println(MemcachedUtil.getInstance().get("newnewnew0"));
stats slabsSTAT 20:chunk_size 7040STAT 20:chunks_per_page 148STAT 20:total_pages 32STAT 20:total_chunks 4736STAT 20:used_chunks 4736STAT 20:free_chunks 0STAT 20:free_chunks_end 0STAT 21:chunk_size 8800STAT 21:chunks_per_page 119STAT 21:total_pages 1 -----page没有增加,还是1STAT 21:total_chunks 119STAT 21:used_chunks 119STAT 21:free_chunks 0STAT 21:free_chunks_end 0STAT active_slabs 2STAT total_malloced 34388640ENDstats itemsSTAT items:20:number 4736STAT items:20:age 725STAT items:20:evicted 4STAT items:20:outofmemory 0STAT items:21:number 119STAT items:21:age 162STAT items:21:evicted 1 ----替换掉了一个slab21的块STAT items:21:outofmemory 0END
?
byte[] arr=new byte[1024*2]; //使用2k的块 MemcachedUtil.getInstance().set("newnewnewnew0", arr,60*60); System.out.println(MemcachedUtil.getInstance().get("newnewnewnew0"));
?
stats slabsSTAT 15:chunk_size 2304STAT 15:chunks_per_page 455STAT 15:total_pages 1STAT 15:total_chunks 455STAT 15:used_chunks 455STAT 15:free_chunks 0STAT 15:free_chunks_end 454STAT 20:chunk_size 7040STAT 20:chunks_per_page 148STAT 20:total_pages 32STAT 20:total_chunks 4736STAT 20:used_chunks 4736STAT 20:free_chunks 0STAT 20:free_chunks_end 0STAT 21:chunk_size 8800STAT 21:chunks_per_page 119STAT 21:total_pages 1STAT 21:total_chunks 119STAT 21:used_chunks 119STAT 21:free_chunks 0STAT 21:free_chunks_end 0STAT active_slabs 3STAT total_malloced 35436960ENDstats itemsSTAT items:15:number 1STAT items:15:age 55STAT items:15:evicted 0STAT items:15:outofmemory 0STAT items:20:number 4736STAT items:20:age 1251STAT items:20:evicted 4STAT items:20:outofmemory 0STAT items:21:number 119STAT items:21:age 688STAT items:21:evicted 1STAT items:21:outofmemory 0END
这样算下来,memcached中的实际 数据总量可能就会超出启动时设置的32M,因为当一个slab大小的数据把内存沾满后,还可能为每个其他的slab大小的数据额为分配一个page,每个page的大小是1M。例如,如果有39个slab,那么就可能多占用38M的内存。而启动时 -f 因子的大小会决定slab数量的大小,所以也会影响到最后有多少数据会超出容量。
?