前言

memcached默认情况下采用了名为Slab Allocator的机制来管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。

slab allocator

图1-1

slab allocator的机制非常简单,它根据配置的内存大小,以页(page)为单位向操作系统申请内存,将其分割成各种尺寸的块(chunk),尺寸相同的块组合在一起就是slab。其中,chunk就是用来存储数据的最小单位。为了便于理解,我们可以在启动memcached的时候加上-vv来查看内存规划的情况:

[root@vm10 bin]# /usr/local/memcached/bin/memcached -u root -l 192.168.56.10 -p 32054 -P /tmp/memcached_32054.pid -vv
#slab编号 chunk大小 chunk个数
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 120 perslab 8738
#篇幅有限,此处省略若干条...
slab class 39: chunk size 524288 perslab 2

  

注意此时memcached并不会立马申请内存,而是等要存数据的时候才去申请。

可以看到,memcached规划出39个slab,chunk大小的范围:96字节~524288字节,越往后越大,增长速度是1.25,这个速度被称为增长因子。每个slab里面chunk的个数也罗列出来了,我们可以计算出每个slab里chunk大小乘以chunk个数刚好等于1m,也就是一页。为什么是一页呢?因为我这个memcached是刚启动,还没有存数据,当这一页的内存都写满数据了,memcached就会再申请一页的内存。接下来详细说一下存数据的过程:

1.memcached根据数据的大小选择slab,如图1-1的情况,当有80字节的数据过来的时候,就会分配给slab1,当有100字节的数据过来的时候,就会去到slab2。

2.找到slab之后要看看存到哪个chunk里边去,因为memcached保存着slab内空闲chunk列表,所以根据该列表很快就能找到要把数据存到哪个chunk里面

3.当没有空闲chunk可用时,memcached会给这个slab申请一页(page)大小的内存(默认1m),然后切分成大小相同的chunk,再把数据放到新的chunk中

4.如果没有内存可以申请了,则会对该slab进行lru,而不是对整个memcache进行lru。

结论

1.申请内存是以页为单位去申请的,这样省去了频繁申请内存的开销

2.重复使用已分配的内存,也就是说,分配到的内存不会被释放,而是重复利用,这样省去了频繁释放内存的开销

3.因为chunk是固定大小的,所以会导致内存浪费。比如100字节的数据放到120字节的chunk里,就浪费掉了20字节的内存。但这个浪费不是永久的,当数据过期的时候会有新数据存入,比如下次是119字节的数据放到这块120字节的chunk里,就只浪费了1字节而已。减少浪费的解决办法是我们可以调节增长因子来改变chunk的大小

性能优化

1.通过-f和-n调整chunk的增长因子和第一个chunk的大小,这个要根据项目中数据大小的分布来决定,来达到内存最大化地利用,避免浪费

2.stats查看get hits、get misses计算命中率,如果命中率太低,需要查明原因

3.stats查看evictions查看LRU次数,如果频繁LRU说明内存不足了

删除机制

1.memcached不主动去删除过期的数据,而是在get的时候检查数据是否过期,如果过期了那么就不可见,然后把当前chunk加入空闲列表,这样下次有数据存入就会更新掉这块chunk的数据而达到删除的作用了,所以memcached不会在淘汰数据上面消耗CPU,这种方式称为lazy expiration(惰性删除)

2.当没有空闲的chunk可以用,又实在没有内存可以申请了,memcached会对当前slab执行LRU(least recently used 最近最少使用)来删除数据,注意是当前slab

memcached内存管理的更多相关文章

  1. memcached 内存管理 分析(转)

    Memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,便于我们理解memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用.这里简单谈一下我对me ...

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

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

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

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

  4. Memcached内存管理模型分析

    Memcached 是一个高性能的分布式内存对象缓存系统,它通过在内存中缓存数据和对象来减少读取数据库的次数,从而减轻RDBMS的负担,提高服务的速度.提升可扩展性.本文将基于memcached1.4 ...

  5. Memcached 内存管理详解

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

  6. memcached内存管理机制[未整理]

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

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

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

  8. memcached内存管理机制分析

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

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

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

随机推荐

  1. OpenWRT添加模块 Makefile和Config.in

    添加模块编译 在网上找了一下,很多关于编译Openwrt系统的资料,不过这些事情芯片厂商提供的开发包都已经办得妥妥了,但是没有找到系统介绍的资料,添加一个包的介绍有不多,其中有两个很有参考价值: ht ...

  2. keepalived实现nginx高可用

    keepalived是什么 keepalived直译就是保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,用来防止单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构的不可用)的发 ...

  3. Oracle学习笔记之游标详解

    游标 游标存在意义:解决"select *"返回空.多行记录问题,但凡select,就可能多行结果集,也就需要用游标. 游标分4步走:cursor.open.fetch.close ...

  4. 《剑指Offer》附加题_用两个队列实现一个栈_C++版

    在<剑指Offer>中,在栈和队列习题中,作者留下来一道题目供读者自己实现,即"用两个队列实现一个栈". 在计算机数据结构中,栈的特点是后进先出,即最后被压入(push ...

  5. Myeclipse10连接SqlServer2012

    本文纯手打!!!! 对于我们这些刚学java的小白,可是真费劲啊!!!! 要用java连接数据库  首先是要通过JDBC驱动 要先去下载一个sqljdbc4.jar,我这里放百度云盘了, 下载地址:链 ...

  6. LINUX 笔记-crontab命令

    用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下: minute   hour   da ...

  7. Java基础总结--Java编程环境变量配置

    1.jdk--bin--都是命令行程序(图形化是对命令行的封装)eg javac&java执行javac必须切换到其所在目录--太麻烦---想在任意目录下使用要执行一个命令--先在当前目录下找 ...

  8. Yii2之事件

    众所周知,yii的三大特性是:属性.事件.行为,上一篇博文简单讲解了yii中的属性,本文接着讲讲yii的事件. 事件是代码解耦的一种方式,设计业务流程的一种模式.在yii2.0中,通过Yii\base ...

  9. asp.net 第三方UI控件 Telerik KendoUI 之 TreeVIew 的用法记录

    一.前台显示 备注:一次性取出所有节点 function loadTreeData() { $.ajax({ type: 'POST', url: '@(Html.UrlHref("Scri ...

  10. 利用cookies+requests包登陆微博,使用xpath抓取目标用户的用户信息、微博以及对应评论

    本文目的:介绍如何抓取微博内容,利用requests包+cookies实现登陆微博,lxml包的xpath语法解析网页,抓取目标内容. 所需python包:requests.lxml 皆使用pip安装 ...