几个重要概念

Slab

memcached通过slab机制进行内存的分配和回收,slab是一个内存块,它是memcached一次申请内存的最小单位,。在启动memcached的时候一般会使用参数-m指定其可用内存,但是并不是在启动的那一刻所有的内存就全部分配出去了,只有在需要的时候才会去申请,而且每次申请一定是一个slab。Slab的大小固定为1MB(1MB=1024KB=1024×1024B=1048576B,1048576字节),一个slab由若干个大小相等的chunk组成。

Slab的分类

根据chunk的大小而将Slab分为不同的类,chunk大小的增幅由增长因子factor决定。根据memcached版本的不同而分类也各有不同,-vv查询分类。

Chunk

chunk是Slab的组成单位,每个Slab都被分割成大小相等的chunk,分割Slab时,不够一个chunk大小的内存空间将被不可以避免的浪费(内存碎片化)。每个chunk中都保存了一个item结构体,item结构体由属性域和数据域组成,数据域中有一个变长数据data,是真正存储缓存记录key和value的地方。

图memcached Slab 分类示意图

源码

typedef struct _stritem {

//属性域

struct _stritem *next;

struct _stritem *prev;

......

//数据域

union {

uint64_t cas;

char end;

} data[];

} item;

Chunk的计算

对于Slab 分类 i,求Slab 分类 i中的chunk的大小:

chunkSize  =  (default_size + item_size)*f^(i-1)  +  CHUNK_ALIGN_BYTES

各参数含义:

l i,分类

l default_size,默认大小为48字节,也就是item结构体中数据域的大小为48字节,可以通过-n参数来调节其大小

l item_size, item结构体的长度,固定为32字节

l f,factor,增长因子,是chunk变化大小的因素,默认值为1.25,调节f可以改变chunk的增幅,在启动时可以使用-f来指定

l CHUNK_ALIGH_BYTES 是一个长常量值,用来保证chunk的大小是这个常量值的整数倍,防止越界。CHUNK_ALIGH_BYTES 大小为sizeof(void *)

例如:void *的长度在不同系统上不一样,在32位机器上,sizeof(void *)值为4

所以,在32为的系统中,Slab 分类1中chunk的大小为:

chunkSize1  =  (48 + 32)* 1.25^(1-1)  +  4 = 84(有待验证)

从chunkSize的计算公式可以看出,可以通过调节-n,-f参数来调整chunk的大小,这也是实际中mecahced调优的关键,合理的调节-n,-f参数以充分利用内存资源,尽可能的减少内存碎片化。

内存分配

当我们通过add命令向memcached中添加一条记录的时候,memcached会根据数据的大小选择合适的slab,memcached维护着slab中空闲的chunk列表,并从中选择一块分配给要添加的记录。

如要存的item大小为100byte,chunk大小为80byte的slab将存不下,而chunk大小为120byte的slab又有剩余,此时memcached会将数据存到chunk大小为120byte的slab中。而剩余的20byte空间将不可避免的浪费。

需要注意的是,当chunk大小为120byte的slab已经满时,memcached并不会寻找更大chunk的slab,如chunk大小为140byte的slab来存储,而是把chunk大小为120byte的slab中的旧数据踢掉。

增长因子调优

memcached 在启动时可以通过­f 选项指定增长因子,默认为1.25。增长因子的不同,chunk大小也不同,应根据实际情况,指定合理的增长因子避免过多的内存空间浪费。

过期数据惰性删除

Memcached中,当某个chunk 中的数据过期后,并不会马上从内存中删除,因此,使用stats 统计时,curr_item中仍然有其信息,直到新的数据占用该chunk ;当试图去get改数据时,先判断是否过期,如果过期则返回空并清空chunk,curr_item减1。过期数据不会马上删除,这种机制称为lazy expiration,即惰性失效,好处是不需要另外去检查数据是否失效,节省了CUP的检测成本。

LRU删除机制

和操作系统内存管理类似,memcached数据删除机制使用的是“最近最少使用”机制(Least Recently Used)进行数据剔除,memcached通过维护一个计数器,来判断最近谁最少被使用,当有新的数据进来时,最近最少用的数据将被剔除。

memcached使用三十二位元的循环冗余校验(CRC-32)计算键值后,将数据分散在不同的机器上。当chunk满了以后,接下来新增的数据会以LRU机制替换掉。

即使某个key被设置永久有效期,也一样会被踢出来,即永久数据被踢现象。

参考文档:

http://kenby.iteye.com/blog/1423989

http://www.dexcoder.com/selfly/article/2248

http://www.dexcoder.com/selfly/series/63

http://www.cnblogs.com/luluping/archive/2009/01/14/1375456.html

分布式缓存技术memcached学习系列(三)——memcached内存管理机制的更多相关文章

  1. 分布式缓存技术redis学习系列

    分布式缓存技术redis学习系列(一)--redis简介以及linux上的安装以及操作redis问题整理 分布式缓存技术redis学习系列(二)--详细讲解redis数据结构(内存模型)以及常用命令 ...

  2. 分布式缓存技术redis学习系列(一)——redis简介以及linux上的安装

    redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...

  3. 分布式缓存技术redis学习系列(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性. 安全性设置 设置客户端操作秘密 redis安装 ...

  4. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  5. 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  6. 分布式缓存技术redis学习(三)——redis高级应用(主从、事务与锁、持久化)

    上文<详细讲解redis数据结构(内存模型)以及常用命令>介绍了redis的数据类型以及常用命令,本文我们来学习下redis的一些高级特性.目录如下: 安全性设置 设置客户端操作秘密 客户 ...

  7. 分布式缓存技术redis学习系列(二)——详细讲解redis数据结构(内存模型)以及常用命令

    Redis数据类型 与Memcached仅支持简单的key-value结构的数据记录不同,Redis支持的数据类型要丰富得多,常用的数据类型主要有五种:String.List.Hash.Set和Sor ...

  8. 分布式缓存技术redis学习(一)——redis简介以及linux上的安装

    redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...

  9. 分布式缓存技术redis学习(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  10. C语言深入学习系列 - 字节对齐&内存管理

    用C语言写程序时需要知道是大端模式还是小端模式. 所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中:所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高 ...

随机推荐

  1. Word 页眉插入自动标题(页眉显示章节标题)

    做word文档时有时候需要将章节标题加到页眉中,这里实现自动获取和自动更新页眉里面的标题 1.双击页眉,输入固定文字作为页眉左边的显示,然后敲2下table键,为接下来插入自动标题做好准备,如下图: ...

  2. 纯净版xp系统在局域网共享需要密码如何解决

    纯净版xp系统在局域网共享需要密码怎么办?这是近来不少朋友都向小编反馈的问题.他们表示每次共享者更改密码后其他人都需要再重新输入密码,感觉十分的麻烦.下面是系统城小编给大家整理的一些有关XP系统局域网 ...

  3. Visual Studio 2015官方社区版/专业版/专业版下载地址

    Visual Studio 2015官方社区版/专业版/专业版下载地址 以下 Visual Studio 2015 社区版/专业版/专业版资源都是官方MSDN原版下载资源,统一为ISO格式镜像,使用解 ...

  4. 点云数据(point cloud) 【转】

    转自caimagic的专栏 一:什么是点云数据 点云数据是指在一个三维坐标系统中的一组向量的集合.这些向量通常以X,Y,Z三维坐标的形式表示,而且一般主要用来代表一个物体的外表面形状.不经如此,除(X ...

  5. 什么是Copy-Only Backup? 为什么要用它?

    Copy-only backup是一种独立于传统SQL Backup方法的一种备份方式. 一般来说, 做一次数据库备份会影响到后面的备份和还原作业. 然而, 有时你需要为了某个特殊的目的而做一次备份但 ...

  6. iOS开发-图片查看(ScrollView+UIPageControl)

    上周没事写了一个简单的图片查看,上次的查看只用到了一个UIImageView,不断的替换背景图片,实现图片之间的切换.通过ScrollView可以很简单的是实现图片之间的查看,设置setPagingE ...

  7. 《TCP/IP具体解释卷2:实现》笔记--接口层

    接口层包含在本地网上发送和接收分组的硬件与软件. 我们用设备驱动程序来表示与硬件及网络接口通信的软件,网络接口是指在一个特定网络上硬件与设备驱动器之间的接口. Net/3接口层试图在网络协议和连接到一 ...

  8. [CSS3]Clearfix

    <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="index ...

  9. [Javascript] Create Objects

    var vehicle1 = {type: "Motorboat", capacity: 6, storedAt: "Ammunition Depot"}; v ...

  10. 【Nodejs】“快算24”扑克牌游戏算法 1.01

    考虑到1.00版本需要改源码变更四个数字,这版修改了一下变成控制台输入了. 先把两个数四则运算得到结果想清楚就是C2代码,三个数就是C3,四个数就是C4.简单的代码简单,却是复杂的基础:复杂的脱胎于简 ...