`
yysct2005
  • 浏览: 87585 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Memcached深入理解 – memcached究竟是如何运作的

 
阅读更多

网上其实有很多文章说明了memcached是如何运作的,特别是底层的内存分配是如何运作的。我参考过很多资料,比较有启发意义的有几个:

  • 首先是官方的英文资料,虽然文章太多、很难看懂,我个人觉得说得也不是太清晰,不够直观(附上官方wiki地址 )。还有git上memcached原作者的protocol.txt 也值得一读,有时间的话,我会翻译一下。
  • 其次是mixi网站的核心技术人员写的5篇全面剖析,这5篇文章写得很实用,从各方面彻底解剖了memcached,可惜的是这一系列文章对于核心的内存分配逻辑描述还不够详细(个人觉得),而且很多监控方面的guide都是基于mixi站点已经有的一套框架,对于从头开发的人来说只能是用来指明方向的,实际指导意义不大(附上我转载的帖子入口 )。
  • 此外还有Mike Perham的一篇博客 ,写得不错,很详细地举例说明了memcached内部的内存分配逻辑,以及内存浪费现象。
  • 还有梁子的一篇博客 ,也是一篇很好的博客,从他的角度非常详细地描述了memcached内部的内存分配逻辑。我个人觉得他的文章解释的是最清楚的,虽然在文笔和错别字上实在是。。。。

1. 几个关键概念

Page为内存分配的单位
Memcached的内存分配以page为单位,默认情况下一个page是1M,可以通过-I参数修改,最小1K,最大128M。如果需要申请内存时,memcached会划分出一个新的page并分配给需要的slab区域。page一旦被分配在memcached重启前不会被回收或者重新分配(page ressign已经从1.2.8版移除了)。

Slabs划分数据空间
Memcached并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列大小的slabs,每个slab只负责一定大小范围内的数据存储。每个slab只存储大于其上一个slab的size并小于或者等于自己最大size的数据。例如:slab 3只存储大小介于137 到 224 bytes的数据。如果一个数据大小为230byte的数据进行存储,它将被分配到slab 4中。每个slab负责的空间其实是不等的,memcached默认情况下下一个slab的最大值为前一个的1.25倍,这个可以通过修改-f参数来修改增长比例。

Chunk才是存放缓存数据的单位
Chunk是一系列固定的内存空间,这个大小就是管理它的slab的最大存放大小。例如:slab 1的所有chunk都是104byte,而slab 4的所有chunk都是280byte。chunk是memcached实际存放缓存数据的地方,因为chunk的大小固定为slab能够存放的最大值,所以所有分配给当前slab的数据都可以被chunk存下。如果实际的数据大小小于chunk的大小,空余的空间将会被闲置,这个是为了防止内存碎片而设计的。举例来说,如果chunk size是224byte,而存储的数据只有200byte,剩下的24byte将被闲置。此外,memcached允许配置的最小的chunk空间为48个字节(key+value+flags),通过-n参数可以调节这个数值。

2. 理解这三者之间的关系

要理解memcached是如何分配内存的就要从理解上述三个东西之间的关系开始。
page 是memcached在收到内存不够的请求,并进行内存分配的单位。举例来说,slab2的所有空间都用完了,又有大小适合slab2的数据过来了,那么slab2就会向memcached请求新的内存空间,memcached就会划分一个page大小的内存量到slab2。page的默认大小是1M,这个数值可以通过参数-I来修改。
slab 是memcached用来划定存储空间的大小概念,每当memcached启动的时候,它会按照-n参数配置的值(如果有的话,否则为默认值)来决定第一个slab的大小,然后根据-f参数的值来决定后续slab大小的增长速率,一个一个地决定后续的slab的大小,直到slab的大小达到设定的page大小(一般是1M)。
chunk 是实际用来存储数据的内存空间,它的大小和包含它的slab的大小是一致的。当page大小的内存分配到slab的时候,slab会根据自身的大小将page大小的内存分割成 page / slabsize 个chunk。

memcached启动时候,slab创建以及chunk分配的细节可以参照下面的数据(使用-vv命令查看的详细内存分配过程)。

Source code      
/
usr/
bin/
memcached -
u nobody -
m 64
 -
p 11211
 -
l 127.0.0.1 -
vv
slab class   1
:
 chunk size        96
 perslab   10922

slab class   2
:
 chunk size       120
 perslab    8738

slab class   3
:
 chunk size       152
 perslab    6898

slab class   4
:
 chunk size       192
 perslab    5461

slab class   5
:
 chunk size       240
 perslab    4369

slab class   6
:
 chunk size       304
 perslab    3449

slab class   7
:
 chunk size       384
 perslab    2730

slab class   8
:
 chunk size       480
 perslab    2184

slab class   9
:
 chunk size       600
 perslab    1747

slab class  10
:
 chunk size       752
 perslab    1394

slab class  11
:
 chunk size       944
 perslab    1110

slab class  12
:
 chunk size      1184
 perslab     885

slab class  13
:
 chunk size      1480
 perslab     708

slab class  14
:
 chunk size      1856
 perslab     564

slab class  15
:
 chunk size      2320
 perslab     451

slab class  16
:
 chunk size      2904
 perslab     361

slab class  17
:
 chunk size      3632
 perslab     288

slab class  18
:
 chunk size      4544
 perslab     230

slab class  19
:
 chunk size      5680
 perslab     184

slab class  20
:
 chunk size      7104
 perslab     147

slab class  21
:
 chunk size      8880
 perslab     118

slab class  22
:
 chunk size     11104
 perslab      94

slab class  23
:
 chunk size     13880
 perslab      75

slab class  24
:
 chunk size     17352
 perslab      60

slab class  25
:
 chunk size     21696
 perslab      48

slab class  26
:
 chunk size     27120
 perslab      38

slab class  27
:
 chunk size     33904
 perslab      30

slab class  28
:
 chunk size     42384
 perslab      24

slab class  29
:
 chunk size     52984
 perslab      19

slab class  30
:
 chunk size     66232
 perslab      15

slab class  31
:
 chunk size     82792
 perslab      12

slab class  32
:
 chunk size    103496
 perslab      10

slab class  33
:
 chunk size    129376
 perslab       8

slab class  34
:
 chunk size    161720
 perslab       6

slab class  35
:
 chunk size    202152
 perslab       5

slab class  36
:
 chunk size    252696
 perslab       4

slab class  37
:
 chunk size    315872
 perslab       3

slab class  38
:
 chunk size    394840
 perslab       2

slab class  39
:
 chunk size    493552
 perslab       2

slab class  40
:
 chunk size    616944
 perslab       1

slab class  41
:
 chunk size    771184
 perslab       1

slab class  42
:
 chunk size   1048576
 perslab       1

 

3. 举个例子来分析

首先,是memcached启动时候的情况:
商人A很有钱,他有100个大小一摸一样的仓库(100M的memcached服务器,每个page大小1M,就是一个仓库)。商人A根据自己的商品尺寸,将自己的仓库分成了42种(42个slab),定义为最小一种的仓库是专门用来存放尺寸为96的货物的(slab1大小为96个字节),然后每种仓库存放的货物大小都是之前一种的1.25倍(增长因子-f为1.25)。商人预先将42个仓库按照预定义的42种货物大小整理、装修了下(memcached启动时候的42个slab预分配、chunk分割)。1号仓库(slab1)中有10922个(1M * 1024 * 1024 / 96)货物存储空间(chunk),后续的仓库类型的装修、空间分配都以此类推。

其次,来看下slab满了的时候的情况:
商人A进了一批尺寸是150的货物,共6899个。货物按大小分配,进入3号仓库( slab3)。因为3号仓库是仓库类型3,其大小只有6898个位置(6898个chunk),6898个货物被安置到仓库类型3(slab3)的3号仓库里去。然后还多出来一个货物没地方放,商人就安排了一个新的仓库装修成仓库类型3(1M的空间分配给slab3,大小为152个字节,含6898个chunk),然后将多余的一个货物放入到新的仓库里。

这个例子看过以后,相信大家都已经很明白前述的三个概念之间的关系以及memcached是如何分配内存空间的了。

4. memcached里的内存浪费

读过上文之后大家应该很明白memcached的内存分配方式了。memcached这样分配内存的好处是不会存在内存碎片,但是坏处也很明显,就是内存的浪费。就拿前面的商人例子来说,如果遇到一种极端的情况,所有的货物进来的都是121个字节的大小,那么按逻辑他们都会被分到slab3里面去,也就是分到大小是152的slab里,也就是说每塞进一个对象,就会有31个字节的内存空间被浪费掉了。

5. memcached的数据回收机制

memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。 这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。如果某一个item在memcached里过期了,这个东西并不会被删除,而是客户端无法再看见该记录(invisible,透明), 其存储空间即可重复使用。一般情况下memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况, 此时就要使用名为 Least Recently Used(LRU)机制来分配空间。 顾名思义,这是删除“最近最少使用”的记录的机制。 因此,当memcached的内存空间不足时(无法从slab class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。

以上,主要是memcached的内存分配利用的一些经验。当然,memcached的配置、调优、监控在这篇文章里是没有涉及的,以后有机会的话会补上。

分享到:
评论

相关推荐

    memcached全面剖析–4. memcached的分布式算法.txt

    memcached全面剖析–4. memcached的分布式算法.txt

    memcached windows稳定版

    在终端(也即cmd命令界面)下输入 ‘c:\memcached\memcached.exe -d install’ 安装 3. 再输入: ‘c:\memcached\memcached.exe -d start’ 启动。NOTE: 以后memcached将作为windows的一个服务每次开机时自动启动...

    Memcached 1.2.1.0 For Windows

    1、安装:memcached.exe –d install 2、启动:memcached.exe -d start 此时memcached已经注册为开机启动服务完成安装。 使用参数: -p 监听的端口 -l 连接的IP地址, 默认是本机 -d start 启动memcached服务 -d ...

    memcached 64位 window

    memcached 64位 window memcached 64位 window memcached 64位 window

    memcached安装包以及MemCachedClient

    memcached, libevent, MemCachedClient

    memcached入门到理解

    memcached入门到理解 博文链接:https://johnnyhg.iteye.com/blog/237733

    memcached for Win32/x64服务器(袋鼠图标,版本是1.4.13)

    MemCached For Win32 服务器(高洛峰老师讲课那种) p 监听的端口 l 连接的IP地址 默认是本机 d start 启动memcached服务 d restart 重起memcached服务 d stop|shutdown 关闭正在运行的memcached服务 d ...

    安装Memcached及Memcached配置

    安装Memcached及Memcached配置

    网上收集最新的Memcached学习资料

    Memcached原理和使用详解.pdf memcached完全剖析–1._memcached的基础.pdf memcached全面剖析.pdf Memcached内存分析、调优、集群.pptx

    memcached for win32

    MemCached For Win32 服务器 -p 监听的端口 -l 连接的IP地址, 默认是本机 -d start 启动memcached服务 -d restart 重起memcached服务 -d stop|shutdown 关闭正在运行的memcached服务 -d install 安装memcached服务 -...

    memcached安装软件 libevent magent memcached

    memcached安装软件 libevent-2.0.21-stable.tar.gz magent.tar.gz memcached-1.4.15.tar.gz

    python-memcached python-memcached

    python-memcached python-memcached

    Memcached v1.5.7 For Windows (附带Memcached和libevent源码两个版本)

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的...

    memcached全面剖析.zip

    理解memcached的内存存储 memcached全面剖析–3. memcached的删除机制和发展方向 memcached全面剖析–4. memcached的分布式算法 memcached全面剖析–5. memcached的应用和兼容程序 可关注公众号:Java与大数据...

    Memcached 学习资料(memcached Memcached使用手册 Memcached源码剖析笔记)

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的...

    memcached-win-32/64-1.4.4-14

    memcached的基本设置: -p 监听的端口 -l 连接的IP地址, 默认是本机 -d start 启动memcached服务 -d restart 重起memcached服务 -d stop|shutdown 关闭正在运行的memcached服务 -d install 安装memcached服务 -d ...

    Memcached v1.5.3 For Windows (附带Memcached和libevent源码)

    Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的...

    MemCached 缓存系统配置说明

    这里需要解释说明一下,很多开发者觉得Memcached是一种分布式缓存系统,但是其实Memcached服务端本身是单实例的,只是在客户端实现过程中可以根据存储的主键做分区存储,而这个区就是Memcached服务端的一个或者多个...

    memcached-2.4.2.jar memcached-2.4.2.jar

    使用memcached 方法 package com.war.common.util; import com.danga.MemCached.*; import java.util.Date; public class MemCached { protected static MemCachedClient mcc; protected static Logger log; ...

    Memcached 1.4.13(Windows 32/64)最新稳定版

    memcached是一套分布式的快取系统,是一套开放源代码软件,以BSD license授权释出。是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。 以下是 memcached 在 Windows 系统下的 x86/x64 版本...

Global site tag (gtag.js) - Google Analytics