主要通过测试,推理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是一款高性能的分布式内存缓存系统,被广泛应用于Web应用中,用于减轻数据库的负载,提高数据访问速度。它的核心原理是将数据存储在内存中,通过键值对的形式进行操作,实现了...
**Memcached缓存机制——优化应用的关键** Memcached是一款高性能的分布式内存对象缓存系统,广泛应用于Web应用中,用于缓解数据库的负载,提高数据访问速度。它通过将数据存储在内存中,使得数据访问几乎达到内存...
2. **数据存储**:客户端使用唯一的键(key)将数据存储到memcached中。数据以键值对的形式存在,键标识数据,值是实际存储的对象。 3. **数据检索**:客户端根据键从memcached中检索数据,同样通过网络通信。 4. **...
SLAB机制是Memcached内存管理的关键组成部分,它通过一种特殊的缓存机制来存储item数据。这种机制能够有效地提高内存利用率并减少内存碎片,从而提高系统的整体性能。 **SLAB机制概述:** - **SLAB(Class)定义**...
在安装memcached时,libevent作为依赖库,因为它提供了异步事件处理机制,这对于memcached的高效运行至关重要。下载libevent的稳定版本,例如`libevent-2.0.21-stable.tar.gz`,解压并按照以下步骤编译和安装: 1. ...
1. **内存存储**:Memcached的设计核心是基于内存的存储机制,所有的数据都保存在内存中,这使得数据读取速度非常快。然而,由于数据仅存在于内存中,如果服务器重启或出现故障,所有数据都会丢失。 2. **键值对...
Memcached 的主要特点包括简单的键值对存储、内存优化的数据结构以及基于内存的缓存机制,适用于处理大量临时数据。 **Redis** 相比之下,Redis 是一个更全面的、支持更多数据结构的键值存储系统。除了基本的键值对...
Python-memcached库则为Python开发者提供了一个简单易用的接口,能够方便地将数据存储和检索到Memcached服务器上。 这个库的主要功能包括: 1. **键值存储**:Python-memcached允许开发者使用键(key)和值(value...
memcached的内存存储基于一种称为Slab Allocation的机制,该机制通过分配固定大小的内存块(Slabs)来存储数据。这种机制有助于减少内存碎片问题,并提高内存使用效率。尽管Slab Allocation机制高效,但也存在一些...
1. 内存管理:Memcached采用slab分配机制管理内存,将内存分为多个 slab 分区,每个分区内部又细分为多个chunk,以减少内存碎片。 2. 数据存储:键值对存储,键必须是字符串,值可以是任意类型(转换为二进制)。每...
Memcached基于键值对(key-value)存储机制,应用程序可以将数据以键值对的形式存储在Memcached中。当需要访问这些数据时,应用程序首先会尝试从缓存中查找,如果找到就直接返回,否则再去数据库查询,将结果存入缓存...
- **tomcat7-session-manager-memcached**:这是Tomcat7的一个Session管理器实现,它将默认的Session存储机制替换为使用Memcached。 3. **配置Tomcat**:在Tomcat的`conf/catalina.properties`文件中,添加以下...
- `memcached`的核心设计理念是简单而高效,提供了一个键值对存储的接口,支持多线程服务,使用libevent库处理网络事件。 - `1.5.4`版本是一个稳定版,修复了前一版本中的已知问题,提高了系统的稳定性和性能。 2...
5. **分布式**:Memcached支持基于键的分布式策略,这意味着多个客户端可以同时访问同一个Memcached实例,且数据自动分散在各个节点上,无需额外的分布式协调机制。 **Memcached的安装与使用**: 1. 安装Memcached...
为了使web应用能使用saas模式的大规模访问,必须实现应用的集群部署.要实现集群部署主要需要实现session共享机制,使得多台应用服务器之间会话统一, tomcat等多数服务都采用了session复制技术实现session的共享
- **Key-Value存储**:Memcached支持简单的键值对存储,键是唯一的,用于标识数据,值是存储的数据。 2. **Java中的Memcached客户端库** 在Java中,我们可以使用各种客户端库与Memcached通信,如Spymemcached、...
**标题解析:** "memcached(十一)memcached-session-manager" 这个标题指的是一个关于memcached缓存系统与...通过这个教程,读者将能够掌握如何利用memcached作为session存储机制,提升Web应用的效率和可靠性。
Memcached基于简单的键值对存储机制,它将数据存储在内存中,以提供快速的数据检索。由于内存的读取速度远高于硬盘,所以Memcached能够显著提升应用性能。它支持多线程并发访问,适用于处理大量并发请求。 在实际...
- **内存管理**:Memcached 使用Slab Allocation机制,将内存划分为多个大小固定的Slabs,每个Slab存储相同大小的对象,避免了内存碎片,提高了内存利用率。 - **预分配内存**:为了避免频繁的内存分配和释放,...