`
goon
  • 浏览: 184113 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Memcached存储机制

 
阅读更多

主要通过测试,推理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中的一个块,还有个比较重要的概念就是pagepage表示同一级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大小的计算方式: 从0M1M,按等比数列划分,默认比例因子是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

 

使用了第20slab的块(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不会增加,所以可见47367k的块可以把内存放满

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

 可见,

lastfirst全部替换出去了。

 

 

 

 

那么再放一个其他大小块的数据呢?

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。例如,如果有39slab,那么就可能多占用38M的内存。而启动时 -f 因子的大小会决定slab数量的大小,所以也会影响到最后有多少数据会超出容量。

 

分享到:
评论

相关推荐

    Memcached存储机制 测试

    **Memcached存储机制详解** Memcached是一款高性能的分布式内存缓存系统,被广泛应用于Web应用中,用于减轻数据库的负载,提高数据访问速度。它的核心原理是将数据存储在内存中,通过键值对的形式进行操作,实现了...

    Memcached缓存机制 用好Cache,优化应用

    **Memcached缓存机制——优化应用的关键** Memcached是一款高性能的分布式内存对象缓存系统,广泛应用于Web应用中,用于缓解数据库的负载,提高数据访问速度。它通过将数据存储在内存中,使得数据访问几乎达到内存...

    PHP内存缓存技术memcached 的安装和工作原理介绍

    2. **数据存储**:客户端使用唯一的键(key)将数据存储到memcached中。数据以键值对的形式存在,键标识数据,值是实际存储的对象。 3. **数据检索**:客户端根据键从memcached中检索数据,同样通过网络通信。 4. **...

    Memcached内存分配与SLAB机制

    SLAB机制是Memcached内存管理的关键组成部分,它通过一种特殊的缓存机制来存储item数据。这种机制能够有效地提高内存利用率并减少内存碎片,从而提高系统的整体性能。 **SLAB机制概述:** - **SLAB(Class)定义**...

    memcached安装软件 libevent magent memcached

    在安装memcached时,libevent作为依赖库,因为它提供了异步事件处理机制,这对于memcached的高效运行至关重要。下载libevent的稳定版本,例如`libevent-2.0.21-stable.tar.gz`,解压并按照以下步骤编译和安装: 1. ...

    memcached.exe及memcached.dll

    1. **内存存储**:Memcached的设计核心是基于内存的存储机制,所有的数据都保存在内存中,这使得数据读取速度非常快。然而,由于数据仅存在于内存中,如果服务器重启或出现故障,所有数据都会丢失。 2. **键值对...

    memcached数据完整迁移到redis

    Memcached 的主要特点包括简单的键值对存储、内存优化的数据结构以及基于内存的缓存机制,适用于处理大量临时数据。 **Redis** 相比之下,Redis 是一个更全面的、支持更多数据结构的键值存储系统。除了基本的键值对...

    python-memcached python-memcached

    Python-memcached库则为Python开发者提供了一个简单易用的接口,能够方便地将数据存储和检索到Memcached服务器上。 这个库的主要功能包括: 1. **键值存储**:Python-memcached允许开发者使用键(key)和值(value...

    memcached全面剖析.pdf

    memcached的内存存储基于一种称为Slab Allocation的机制,该机制通过分配固定大小的内存块(Slabs)来存储数据。这种机制有助于减少内存碎片问题,并提高内存使用效率。尽管Slab Allocation机制高效,但也存在一些...

    memcached源代码分析

    Memcached作为一款成熟的缓存解决方案,其源代码分析不仅有助于理解其内部机制,还能启发开发者如何构建高效、可靠的分布式系统。通过对Memcached源代码的深入剖析,我们可以学习到其在内存管理、网络通信、数据结构...

    memcached-1.5.11.tar.gz

    1. 内存管理:Memcached采用slab分配机制管理内存,将内存分为多个 slab 分区,每个分区内部又细分为多个chunk,以减少内存碎片。 2. 数据存储:键值对存储,键必须是字符串,值可以是任意类型(转换为二进制)。每...

    memcached_1.4.4.rar

    Memcached基于键值对(key-value)存储机制,应用程序可以将数据以键值对的形式存储在Memcached中。当需要访问这些数据时,应用程序首先会尝试从缓存中查找,如果找到就直接返回,否则再去数据库查询,将结果存入缓存...

    memcached+tomcat7共享session所需要的jar包

    - **tomcat7-session-manager-memcached**:这是Tomcat7的一个Session管理器实现,它将默认的Session存储机制替换为使用Memcached。 3. **配置Tomcat**:在Tomcat的`conf/catalina.properties`文件中,添加以下...

    memcached-1.5.4

    - `memcached`的核心设计理念是简单而高效,提供了一个键值对存储的接口,支持多线程服务,使用libevent库处理网络事件。 - `1.5.4`版本是一个稳定版,修复了前一版本中的已知问题,提高了系统的稳定性和性能。 2...

    Memcached 原理和使用详解

    5. **分布式**:Memcached支持基于键的分布式策略,这意味着多个客户端可以同时访问同一个Memcached实例,且数据自动分散在各个节点上,无需额外的分布式协调机制。 **Memcached的安装与使用**: 1. 安装Memcached...

    memcached实现session远程分布式存储

    为了使web应用能使用saas模式的大规模访问,必须实现应用的集群部署.要实现集群部署主要需要实现session共享机制,使得多台应用服务器之间会话统一, tomcat等多数服务都采用了session复制技术实现session的共享

    memcached工具类源码

    - **Key-Value存储**:Memcached支持简单的键值对存储,键是唯一的,用于标识数据,值是存储的数据。 2. **Java中的Memcached客户端库** 在Java中,我们可以使用各种客户端库与Memcached通信,如Spymemcached、...

    memcached(十一)memcached-session-manager

    **标题解析:** "memcached(十一)memcached-session-manager" 这个标题指的是一个关于memcached缓存系统与...通过这个教程,读者将能够掌握如何利用memcached作为session存储机制,提升Web应用的效率和可靠性。

    memcached连接demo

    Memcached基于简单的键值对存储机制,它将数据存储在内存中,以提供快速的数据检索。由于内存的读取速度远高于硬盘,所以Memcached能够显著提升应用性能。它支持多线程并发访问,适用于处理大量并发请求。 在实际...

Global site tag (gtag.js) - Google Analytics