memcached默认采用的是Slab Allocator的机制分配管理内存的,在此之前,内存的分配是通过对所有的记录简单地进行malloc和free来进行的,但这种方式容易造成很多内存碎片,加重操作系统内存管理的负担。

内存碎片化

如果用C语言直接 malloc,free 来向操作系统申请和释放内存时, 在不断的申请和释放过程中,形成了一些很小的内存片断,无法再利用。 这种空闲,但无法利用内存的现象即为内存的碎片化。

slab allocator机制

slab allocator的原理是将分配的内存分隔成各种尺寸的块,并把尺寸相同的块分成组,所分配的这些内存不会释放,而是重复利用.

针对客户端发送的数据,memcached会根据收到数据的大小,选择最适合数据大小的slab。memcached中保存着slab内空闲块的列表,根据该列表选择块,然后将数据组上于其中

slab allocator缺点

该机制来带来了一定的问题,就是由于分配的是特定长度的内存,因此无法有效利用分配的内存,如,将100字节的数据缓存到128字节的块中,而剩余的28字节就浪费了

使用growth factor进行调优

memcached启动时可以指定growth factor因子,通过-f选项,就可以在某种程度上控制slab之间的差异,默认为1.25。可由./memcached -f 2 -vv查看内存分配情况

查看memcached内部状态

memcached有个stats的命令,它可以获得各种各样的信息,如:

$telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
stats
STAT pid 4422
STAT uptime 85586
STAT time 1459390330
STAT version 1.4.25
STAT libevent 2.0.22-stable
STAT pointer_size 64
STAT rusage_user 0.329239
STAT rusage_system 0.546175
STAT curr_connections 10
....

通过stats slabsstats items还可以获得关于缓存记录的信息。

memcached的删除数据机制

数据不会从memcached中消失,不会释放已分配的内存,记录超时后,客户端就无法再看到该记录,其存储空间是可以再次利用

lazy expiration

memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期,这种技术被称之为lazy expiration,因此memcached不会在过期监视上耗费CPU时间

LRU

memcached会优先使用已超时的记录空间,但有时候也会发生空间不足的情况,这时间就会使用LRU机制来分配空间,就是说删除最近最少使用的记录来存放新的记录。

但可通过./memcached -M命令中的-M参数来禁止使用LRU机制,如果内存用尽时就会返回错误。

Memcached利用Slab Allocator机制管理内存。

原理

预先把内存划分成数个大小1M的slab class仓库;
再把每个仓库切分成不同尺寸的小块(chunk);
需要存内容时,判断内容的大小,为其选取合理的仓库。

memcached根据收到的数据的大小, 选择最适合数据大小的chunk组。
memcached 中保存着 slab class 内空闲 chunk 的列表, 根据该列表选择空的 chunk, 然后将数据缓存于其中。

注意:如果有 100byte 的数据,但122byte大小的仓库中的chunk满了;
此时会把122byte仓库的旧数据剔除掉,然后存储[Memcachedd的删除机制]。
固定大小chunk的内存浪费

Slab Allocator存在的问题
由于分配的是特定长度的内存,因此无法有效利用分配的内存。
例如: 将100byte数据存入128byte的chunk,则浪费了28byte。

因为不能自定义chunk的大小,所以无法彻底解决chunk空间浪费问题。
问题缓解: 如果预先知道客户端发送的数据的公用的大小,或者仅缓存大小相同的数据的情况下。只要使用适合数据大小的组的列表,就可以减少浪费。

即: 通过缓存中item长度进行统计,通过参数调整slab class大小的增长速度,即增长因子(growth factor),从而制定合理的chunk大小。

Slab Allocator术语
  • page – 分配给slab的内存空间,默认是1MB,分配给slab之后跟据slab大小切分成chunk
  • chunk – 用于缓存数据的内存空间
  • slab class – 特定大小的chunk组
Growth Factor调优

启动时指定growth factor因子,就可以在某种程度上控制slab之间的差异,默认值为1.25。
Memcached –f 2 –vv
(查看growth factor为2时slab中chunk size的差异)
Memcached引入时,最好重新计算一下数据的预期平均长度,调整growth factor,以获得最恰当的设置。

数据删除[过期数据惰性删除]

1、Memcached不会释放已分配的内存,其存储空间可以重复使用。
2、Lazy Expiration
Memcached内部不会监视数据是否过期,而是在get时查看数据的时间戳,查看数据是否过期。被称为lazy expiration(惰性过期)。
3、当Memcached内存空间不足,即无法从slab class中获取到新的空间时,就从最近未被使用的数据中搜索,将其空间分配给新的数据。(如果要禁用LRU,使用-M参数,超出会报错)。
4、不指定具体值则默认数值为64M。

lazy expiration好处:
节省CPU时间和检测成本

LRU删除机制

如果以 128byte的chunk举例, 128byte的chunk都满了, 又有新的值(长度为 120)要加入, 要剔除掉哪个数据?

操作系统的内存管理,常用 FIFO,LRU 删除

  • LRU: Least Recently Used 最近最少使用
  • FIFO: First In ,First Out 先进先出

memcached 使用LRU删除机制
原理: 当某个单元被请求时,维护一个计数器,通过计数器来判断最近谁最少被使用. 就把谁剔除。

注: 即使某个 key 是设置的永久有效期,也一样会被踢出来!
--即永久数据被踢现象

参数限制

  • key 的长度: 250 字节, (二进制协议支持 65536 个字节)
  • value 的限制: 1m, 一般都是存储一些文本,如新闻列表等等,这个值足够了. 内存的限制: 32 位下最大设置到 2g.

如果有 30G数据要缓存,一般也不会单实例装 30G, (不要把鸡蛋装在一个篮子里),,可以开启多个实例(在不同的机器,或同台机器上的不同端口)

memcached内存管理机制[未整理]的更多相关文章

  1. 分布式缓存系统 Memcached 内存管理机制

    在前面slab数据存储部分分析了Memecached中记录数据的具体存储机制,从中可以看到所采用的内存管理机制——slab内存管理,这也正是linux所采用的内存高效管理机制,对于Memchached ...

  2. 简述 Memcached 内存管理机制原理?

    早期的 Memcached 内存管理方式是通过 malloc 的分配的内存,使用完后通过 free 来回收内存,这种方式容易产生内存碎片,并降低操作系统对内存的管理效 率.加重操作系统内存管理器的负担 ...

  3. Spark Tungsten in-heap / off-heap 内存管理机制--待整理

    一:Tungsten中到底什么是Page? 1. 在Spark其实不存在Page这个类的.Page是一种数据结构(类似于Stack,List等),从OS层面上讲,Page代表了一个内存块,在Page里 ...

  4. 分布式缓存技术memcached学习(三)——memcached内存管理机制

    几个重要概念 Slab memcached通过slab机制进行内存的分配和回收,slab是一个内存块,它是memcached一次申请内存的最小单位,.在启动memcached的时候一般会使用参数-m指 ...

  5. 分布式缓存技术memcached学习系列(三)——memcached内存管理机制

    几个重要概念 Slab memcached通过slab机制进行内存的分配和回收,slab是一个内存块,它是memcached一次申请内存的最小单位,.在启动memcached的时候一般会使用参数-m指 ...

  6. memcached内存管理机制分析

    memached是高性能分布式内存对象系统,通过在内存中存储数据对象来减少对磁盘的数据读取次数,提高服务速度. 从业务需求出发.我们通过一条命令(如set)将一条键值对(key,value)插入mem ...

  7. Memcached 内存管理详解

    Memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,便于我们理解memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用. 首先需要我们先了解两 ...

  8. java内存管理机制剖析(一)

    最近利用工作之余学习研究了一下java的内存管理机制,在这里记录总结一下. 1-1.java内存区域 当java程序运行时,java虚拟机会将内存划分为若干个不同的数据区域,这些内存区域创建和销毁的时 ...

  9. 一文洞悉JVM内存管理机制

    前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图: 一.为什么要学习内存管理? Java与C++之间有一堵由内存动态分配和垃圾回收机制所围成的高墙,墙 ...

随机推荐

  1. oracle归档日志的操作

                 oracle利用重做日志文件记录对数据库的操作.可是重做日志文件组是循环使用的,当所有的日志文件都被填满时,系统自己主动切换到第一组日志文件,当然数据库管理员也能够使用命令手 ...

  2. 【python3】 enumerate用法总结(转)

    http://blog.csdn.net/churximi/article/details/51648388 enumerate()说明 enumerate()是python的内置函数 enumera ...

  3. .NET-分页处理方式

    分页方案一: 现在常见的前端框架datatable,easyui等的分页插件,都是采用的前端分页,原理:先将符合条件的数据全部加载到页面上,然后计算分页,进行分页处理.(装载全部数据) 优点: --在 ...

  4. ASP入门(十五)- Global.asa

    Global.asa 文件是一个可选文件,它可包含被 ASP 应用程序中每个页面访问的对象.变量和方法的声明.所有合法的浏览器脚本都可以在 Global.asa 中使用. Global.asa 文件只 ...

  5. 看见上帝的 10 个公式……

    原文 Top Ten Greatest Equations Ever 本文内容 No.1 麦克斯韦方程组 No.2 欧拉方程 No.3 牛顿第二定律 No.4 毕达哥拉斯定理 No.5 薛定谔方程 N ...

  6. C#.NET常见问题(FAQ)-索引器indexer有什么用

    索引器就是名值对,你声明一个名值对的类,就可以给数组的指定元素赋值,也可以很方面的访问到指定元素值对应的下标(个人认为完全可以自己写一个类似的list来实现,没有必要多此一举学一个额外的方法)   复 ...

  7. iOS 按钮拖动。

    -(void)testMove { moveBtn = [[UIButton alloc ]init]; moveBtn.frame = CGRectMake(0, 30, 60, 60); move ...

  8. Git如何获得两个版本间所有变更的文件列表

    https://segmentfault.com/q/1010000000133613 git diff --name-status HEAD~2 HEAD~3

  9. sell 项目 订单详情表 设计 及 创建

    1.数据库设计 2.订单详情表 创建 /** * 订单详情表 */ create table `order_detail` ( `detail_id` varchar(32) not null, `o ...

  10. JSON语言规范与Java中两种解析工具基本使用

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6652250.html  一:JSON语言规范 一言以蔽之:“一个 :一个键值对,一个{}一个对象,一个[]一个 ...