主要通过测试,推理memcached的存储机制。
平台 windows7
版本 memcached-1.2.6-win32
启动日志:
E:\memcached\memcached-1.2.6-win32-bin>memcached -m 32 -p 12001 -vv
slab class 1: chunk size 88 perslab 11915 slab class 2: chunk size 112 perslab 9362 slab class 3: chunk size 144 perslab 7281 slab class 4: chunk size 184 perslab 5698 slab class 5: chunk size 232 perslab 4519 slab class 6: chunk size 296 perslab 3542 slab class 7: chunk size 376 perslab 2788 slab class 8: chunk size 472 perslab 2221 slab class 9: chunk size 592 perslab 1771 slab class 10: chunk size 744 perslab 1409 slab class 11: chunk size 936 perslab 1120 slab class 12: chunk size 1176 perslab 891 slab class 13: chunk size 1472 perslab 712 slab class 14: chunk size 1840 perslab 569 slab class 15: chunk size 2304 perslab 455 slab class 16: chunk size 2880 perslab 364 slab class 17: chunk size 3600 perslab 291 slab class 18: chunk size 4504 perslab 232 slab class 19: chunk size 5632 perslab 186 slab class 20: chunk size 7040 perslab 148 slab class 21: chunk size 8800 perslab 119 slab class 22: chunk size 11000 perslab 95 slab class 23: chunk size 13752 perslab 76 slab class 24: chunk size 17192 perslab 60 slab class 25: chunk size 21496 perslab 48 slab class 26: chunk size 26872 perslab 39 slab class 27: chunk size 33592 perslab 31 slab class 28: chunk size 41992 perslab 24 slab class 29: chunk size 52496 perslab 19 slab class 30: chunk size 65624 perslab 15 slab class 31: chunk size 82032 perslab 12 slab class 32: chunk size 102544 perslab 10 slab class 33: chunk size 128184 perslab 8 slab class 34: chunk size 160232 perslab 6 slab class 35: chunk size 200296 perslab 5 slab class 36: chunk size 250376 perslab 4 slab class 37: chunk size 312976 perslab 3 slab class 38: chunk size 391224 perslab 2 slab 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
日志只是显示了将来的分配策略,并未真正分配内存。
Slab表示块大小的级别,chunk表示slab中的一个块,还有个比较重要的概念就是page,page表示同一级slab大小的块的集合。
查看数据状态:
stats STAT pid 12212 STAT uptime 10 STAT time 1367559145 STAT version 1.2.6 STAT pointer_size 32 STAT curr_items 0 STAT total_items 0 STAT bytes 0 --已存数据大小 STAT curr_connections 3 STAT total_connections 4 STAT connection_structures 4 STAT cmd_get 0 STAT cmd_set 0 STAT get_hits 0 STAT get_misses 0 STAT evictions 0 STAT bytes_read 11 STAT bytes_written 7 STAT limit_maxbytes 33554432 ---最大容量 STAT threads 1 END
Slab的大小是怎么算出来的呢?
slab大小的计算方式: 从0M到1M,按等比数列划分,默认比例因子是1.25.例如上例中:88*1.25=112.
存数据,测试代码:
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 slabs
STAT 20:chunk_size 7040 --块大小
STAT 20:chunks_per_page 148 ----每个page中块数量
STAT 20:total_pages 1 --------只有一个page
STAT 20:total_chunks 148 ---第20个slab级别的块数量总和= total_pages* chunks_per_page
STAT 20:used_chunks 148
STAT 20:free_chunks 0
STAT 20:free_chunks_end 8
STAT active_slabs 1
STAT total_malloced 1041920 ---所有数据占用内存=140*(7040+key所占内存)
END
stats items
STAT items:20:number 140
STAT items:20:age 241
STAT items:20:evicted 0
STAT items:20:outofmemory 0
END
stats sizes
6240 140
END
使用了第20个slab的块(7k的块),使用了140个,还剩8个。
再执行8次:
int i=0; int n=i+8;
结果:
stats slabs STAT 20:chunk_size 7040 STAT 20:chunks_per_page 148 STAT 20:total_pages 1 STAT 20:total_chunks 148 STAT 20:used_chunks 148 STAT 20:free_chunks 0 STAT 20:free_chunks_end 0 ---第一个page中148个chunk全部占用 STAT active_slabs 1 STAT total_malloced 1041920 END stats items STAT items:20:number 148 STAT items:20:age 407 STAT items:20:evicted 0 STAT items:20:outofmemory 0 END
那么再放一个
7k的块会怎么分配呢?
测试:
int i=0; int n=i+1;
结果:
stats slabs STAT 20:chunk_size 7040 STAT 20:chunks_per_page 148 STAT 20:total_pages 2 -----新加了一个page STAT 20:total_chunks 296 STAT 20:used_chunks 296 STAT 20:free_chunks 0 STAT 20:free_chunks_end 147 STAT active_slabs 1 STAT total_malloced 2083840 END stats items STAT items:20:number 149 ---总过有149个块被使用 STAT items:20:age 1053 STAT items:20:evicted 0 STAT items:20:outofmemory 0 END
那么我用7k的块,把32M内存占完,之后再存数据看会是什么情况:
先测一下多少数据可以把内存沾满,经测试,当到以下状态时,再放数据,total_chunks不会增加,所以可见4736个7k的块可以把内存放满:
stats slabs STAT 20:chunk_size 7040 STAT 20:chunks_per_page 148 STAT 20:total_pages 32 STAT 20:total_chunks 4736 STAT 20:used_chunks 4736 STAT 20:free_chunks 0 STAT 20:free_chunks_end 0 STAT active_slabs 1 STAT total_malloced 33341440 END
修改测试程序:
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"));
输出:
null null null null [B@46a5c4 [B@2d09e0 [B@e38fca [B@1f528ab
数据状态:
stats items STAT items:20:number 4736 STAT items:20:age 87 STAT items:20:evicted 4 STAT items:20:outofmemory 0 END
可见,
last把first全部替换出去了。
那么再放一个其他大小块的数据呢?
byte[] arr=new byte[1024*8]; //使用8k的块 MemcachedUtil.getInstance().set("new1", arr,60*60); System.out.println(MemcachedUtil.getInstance().get("new1"));
输出:
[B@1ff0a34
数据状态:
stats slabs =================slab20的状态没变化 STAT 20:chunk_size 7040 STAT 20:chunks_per_page 148 STAT 20:total_pages 32 STAT 20:total_chunks 4736 STAT 20:used_chunks 4736 STAT 20:free_chunks 0 STAT 20:free_chunks_end 0 ============数据被放在了slab21中,新开了一个slab21的page STAT 21:chunk_size 8800 STAT 21:chunks_per_page 119 STAT 21:total_pages 1 STAT 21:total_chunks 119 STAT 21:used_chunks 119 STAT 21:free_chunks 0 STAT 21:free_chunks_end 118 STAT active_slabs 2 STAT total_malloced 34388640 END stats items STAT items:20:number 4736 STAT items:20:age 283 STAT items:20:evicted 4 STAT items:20:outofmemory 0 STAT items:21:number 1 STAT items:21:age 22 STAT items:21:evicted 0 STAT items:21:outofmemory 0 END
那么把slab21的这个page放满之后,如果再放数据会是什么情况呢?是继续新增slab21的page还是做替换呢?:
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"));
输出:
[B@c0fc8e
stats slabs STAT 20:chunk_size 7040 STAT 20:chunks_per_page 148 STAT 20:total_pages 32 STAT 20:total_chunks 4736 STAT 20:used_chunks 4736 STAT 20:free_chunks 0 STAT 20:free_chunks_end 0 STAT 21:chunk_size 8800 STAT 21:chunks_per_page 119 STAT 21:total_pages 1 STAT 21:total_chunks 119 STAT 21:used_chunks 119 STAT 21:free_chunks 0 STAT 21:free_chunks_end 0 ---已全部被占用 STAT active_slabs 2 STAT total_malloced 34388640 END stats items STAT items:20:number 4736 STAT items:20:age 579 STAT items:20:evicted 4 STAT items:20:outofmemory 0 STAT items:21:number 119 STAT items:21:age 318 STAT items:21:evicted 0 STAT items:21:outofmemory 0 END
再放一个:
MemcachedUtil.getInstance().set("newnewnew0", arr,60*60); System.out.println(MemcachedUtil.getInstance().get("newnewnew0"));
输出:
[B@1ff0a34
stats slabs STAT 20:chunk_size 7040 STAT 20:chunks_per_page 148 STAT 20:total_pages 32 STAT 20:total_chunks 4736 STAT 20:used_chunks 4736 STAT 20:free_chunks 0 STAT 20:free_chunks_end 0 STAT 21:chunk_size 8800 STAT 21:chunks_per_page 119 STAT 21:total_pages 1 -----page没有增加,还是1 STAT 21:total_chunks 119 STAT 21:used_chunks 119 STAT 21:free_chunks 0 STAT 21:free_chunks_end 0 STAT active_slabs 2 STAT total_malloced 34388640 END stats items STAT items:20:number 4736 STAT items:20:age 725 STAT items:20:evicted 4 STAT items:20:outofmemory 0 STAT items:21:number 119 STAT items:21:age 162 STAT items:21:evicted 1 ----替换掉了一个slab21的块 STAT items:21:outofmemory 0 END
再放一个2k的块也一样:
byte[] arr=new byte[1024*2]; //使用2k的块 MemcachedUtil.getInstance().set("newnewnewnew0", arr,60*60); System.out.println(MemcachedUtil.getInstance().get("newnewnewnew0"));
stats slabs STAT 15:chunk_size 2304 STAT 15:chunks_per_page 455 STAT 15:total_pages 1 STAT 15:total_chunks 455 STAT 15:used_chunks 455 STAT 15:free_chunks 0 STAT 15:free_chunks_end 454 STAT 20:chunk_size 7040 STAT 20:chunks_per_page 148 STAT 20:total_pages 32 STAT 20:total_chunks 4736 STAT 20:used_chunks 4736 STAT 20:free_chunks 0 STAT 20:free_chunks_end 0 STAT 21:chunk_size 8800 STAT 21:chunks_per_page 119 STAT 21:total_pages 1 STAT 21:total_chunks 119 STAT 21:used_chunks 119 STAT 21:free_chunks 0 STAT 21:free_chunks_end 0 STAT active_slabs 3 STAT total_malloced 35436960 END stats items STAT items:15:number 1 STAT items:15:age 55 STAT items:15:evicted 0 STAT items:15:outofmemory 0 STAT items:20:number 4736 STAT items:20:age 1251 STAT items:20:evicted 4 STAT items:20:outofmemory 0 STAT items:21:number 119 STAT items:21:age 688 STAT items:21:evicted 1 STAT items:21:outofmemory 0 END
可见,当内存被沾满后,如果再存放一种新的slab大小的数据,那么memcached会新开一个且只开一个这种slab大小的page,当这个page被沾满后,就会执行数据替换。
这样算下来,memcached中的实际 数据总量可能就会超出启动时设置的32M,因为当一个slab大小的数据把内存沾满后,还可能为每个其他的slab大小的数据额为分配一个page,每个page的大小是1M。例如,如果有39个slab,那么就可能多占用38M的内存。而启动时 -f 因子的大小会决定slab数量的大小,所以也会影响到最后有多少数据会超出容量。
相关推荐
Memcached存储机制 测试 Memcached存储机制 测试 Memcached存储机制 测试
为了使web应用能使用saas模式的大规模访问,必须实现应用的集群部署.要实现集群部署主要需要实现session共享机制,使得多台应用服务器之间会话统一, tomcat等多数服务都采用了session复制技术实现session的共享
memcached介绍 memcached安装 memcached操作 内存存储机制 数据过期与删除机制 php操作memcached 多服务器集群算法 缓存无底洞效应 缓存雪崩 老数据被踢现象 结课作业
这里需要解释说明一下,很多开发者觉得Memcached是一种分布式缓存系统,但是其实Memcached服务端本身是单实例的,只是在客户端实现过程中可以根据存储的主键做分区存储,而这个区就是Memcached服务端的一个或者多个...
Nginx+Tomcat7+Memcached集群Session共享 ...主要是利用memcached-session-manager(下面简称msm)开源tomcat插件改变tomcat原始的session存储机制,将session的存储放到分布式缓存memcache中,从而实现对session的共享
memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存...第2章 理解memcached的内存存储 第3 章 memcached的删除机制和发展方向 第4 章 memcached的分布式算法 第5 章 案例memcached的应用和兼容程序
理解memcached的内存存储 memcached全面剖析–3. memcached的删除机制和发展方向 memcached全面剖析–4. memcached的分布式算法 memcached全面剖析–5. memcached的应用和兼容程序 可关注公众号:Java与大数据...
Memcached通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。Memcached由Danga Interactive最初为了加速 LiveJournal网站访问速度而开发的,后 ...
本次介绍memcached的数据删除机制,以及memcached的最新发展方向——二进制协议(Binary Protocol)和外部引擎支持。上次介绍过,memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible...
最近的memcached默认情况下采用了名为SlabAllocator的机制分配、管理内存。 在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器...
这里需要有点说明,很多开发者觉得Memcached是一种分布式Cache,但是其实Memcached服务端本身是单实例的,只是在客户端实现过程中可以根据存储的主键作分区存储,而这个区就是Memcached服务端的一个或者多个实例,...
第2章 理解memcached的内存存储..............................................................................................12 2.1 Slab Allocation机制:整理内存以便重复使用................................
memcachedb是 一个由新浪网的开发人员开放出来的开源项目,给memcached分布式缓存服务器添加了Berkeley DB的持久化存储机制和异步主辅复制机制
memcachedb是一个由新浪网的开发人员开放出来的开源项目,给memcached分布式缓存服务器添加了Berkeley DB的持久化存储机制和异步主辅复制机制,让memcached具备了事务恢复能力、持久化能力和分布式复制能力,非常...
一种非常简单的由Redis支持的临时存储机制,旨在与ActiveRecord一起使用,但实际上可以与其他ORM或任何类一起使用。 我专门开发了Frivol,用于Mad Mimi( ),以帮助缓存需要相当长的运行时间()的数据库查询的...
3.2.3 Memcached的删除机制 3.2.4 Memcached的分布式算法 3.3 Memcached的管理与性能监控 3.3.1 如何管理Memcached 3.3.2 Memcached的监控 3.3.3 Memcached变种产品介绍 3.4 通过UDFs实现Memcached与...
和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更...
和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更...
和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更...