Memcached之内存利用率提升经验分享

news/2024/7/4 0:51:53 标签: memcached, class, 存储, allocation, cache, user
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

在使用Memcached的时候,大部分人可能很少关注内存利用率,因为Cache毕竟是Cache,那么对于存储数据的可靠性要求就不高,丢了也不心疼,总之能够从DB中Reload回来即可,话是不错!但是在我们的项目中,却遇到了一个棘手的问题,就是希望数据能够被Memcached 100%的Cache起来,那么如何让容量规划做到位呢,加多大内存才是合理的,问题就随之而来了!在我们的测试过程中,想要放入20G的数据(5000万)到开了25G的Memcached中,本想是没有问题的,结果才放到45%的容量的时候,数据就发生了“Evict”的现象,后续再继续追加数据,直到全部加完,Memcached的利用率始终维持在50%左右,丢了40%左右的数据,难道说需要开个50G的Memcached才能搞定20G的数据存储?这个也是不确定的,资源浪费太严重了,所以我们就开始着手分析原因了,目的就为两点:

① 100%将数据Cache起来

② 提高Memcached的内存利用率,节省不必要的成本,将利用率稳定在一定合理值,这样便于将来我们预警容量问题,也能做好容量规划

1、 首先:我们需要了解Memcached的内存分配机制:

Memcached采用了Slab Allocation机制,这种机制的好处是预先分配好内存,无需在使用时Malloc和Free,解决了内存碎片问题,分配好的内存也可以重复使用,所以可以减轻内存管理的负担。

分配过程:先初始化若干个Slab,为每个Slab分配一个Page的内存空间,Page缺省为1MB,每个Page根据Slab规格被划分为若干个相同Size的Chunk,每个Chunk里保存一个Item,每个Item同时包含了Item结构体、k和V,相同Size的Chunk合成一组Slab Class,如图例:

clip_image002

我们可以使用Growth Factord对分配策略进行调优,默认值是1.25,Growth Factor的值不同,分配的Chunk的Size就不同,且不同Slab Class中的Chunk数量也会不同,根据需要调整才是。

n 缺省值F=1.25的情况下,Slab分配情况如下:

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

n 若F=2的情况下,Slab分配情况如下:

slab class 1: chunk size 128 perslab 8192

slab class 2: chunk size 256 perslab 4096

slab class 3: chunk size 512 perslab 2048

slab class 4: chunk size 1024 perslab 1024

slab class 5: chunk size 2048 perslab 512

slab class 6: chunk size 4096 perslab 256

slab class 7: chunk size 8192 perslab 128

slab class 8: chunk size 16384 perslab 64

slab class 9: chunk size 32768 perslab 32

slab class 10: chunk size 65536 perslab 16

2、 其次,了解数据存储的原理:

Memcached在收到需要存储的数据后,先计算数据的Size,最大存入1M的数据,然后选择适合的Slab Class中的Chunk(当然Memcached会记录哪些Chunk是空闲的),,如图例:

clip_image004

在数据存入选中的Slab Class,可能有以下两种情况:

n 若该Slab Class未满(free_chunks > 0),则成功存入;

n 若该Slab Class满了(free_chunks=0),有可能发生以下两种情况:

l 有可用内存,则新增一个Page的内存给该Slab,该Page也是被当前Slab的同样规格进行划分若干Chunk,然后将数据存入新增的Chunk中;

l 无可用内存,有可能发生以下两种情况:

u 启用LRU(LRU的Scope只是针对Slab的,而非全局),将新数据替换老数据,老数据丢失

u 禁用LRU(追加Memcached的启动参数-M),发生Out Of Memory错误

由于分配的都是定长Chunk,在内存利用率上也有天然的缺陷,如图例:

clip_image006

n 不仅仅存在单个Chunk上浪费现象

n 而且会存在整个Slab Class浪费的现象,因为有时遇到的数据Size根本落不到这个Slab Class上都是可能的

总之,Memcached可谓用心良苦,用空间换取性能,当然应用在使用时需要注意到这点特性,才能用好Memcached。

3、 最后,就必须要对自己应用的数据Size分布做个透彻的分析,才能将Memcached物尽其用:

根据经验所得:

n 数据Size的分布尽量集中可以提高Memcached的内存利用率

以我遇到的问题做为例: 我们需要在Memcached里保存User的操作记录,为了贪图查询的方便,我们就Key<UserID> = Value<List<操作记录>>,当每位User的操作记录数量从1到n都有分布,那么n较大的数据就会选择了Size较大的Chunk进行储存,若出现17193bytes大小的数据,那么只能从以下两个Slab中选择Slab Class 25进行存储

slab class 24: chunk size 17192 perslab 60

slab class 25: chunk size 21496 perslab 48

如果这样Size的数据非常多的话,那就非常杯具了,浪费的内存成(21496-17193)*m线性增长;因此我们改变了存储策略,使用Key<操作记录ID> = Value<操作记录>, Key<UserId> = Value<List<操作记录 ID>>进行存储,这样操作记录的每对K/V的Size都在200bytes左右,结果内存利用了提升到90%左右;

n 根据Value的Size分布,适当调整的Growth Factor也是可以提升内存利用率

n 最后,Memcached本身就是解决不可靠数据的存取服务的,做为二级缓存是不错的选择,可以很大程度的提升性能,但是要想存取可靠的数据,就不能选择Memcached,选择一项“适合的”技术保障可用性才是王道。

转自:http://code.alibabatech.com/blog/experience_954/class="tags" href="/tags/MEMCACHED.html" title=memcached>memcached-the-memory-utilization-to-enhance-experience-sharing.html




http://www.niftyadmin.cn/n/761382.html

相关文章

php empty函数测试

$a1 null; $a2 false; $a3 0; $a4 ; $a5 0; $a6 null; $a7 array(); $a8 array(array()); echo empty($a1) ? true : false; echo <hr />; echo empty($a2) ? true : false; echo <hr />; echo empty($a3) ? true : false; echo <hr />; echo …

php引用测试

function get_arr($arr){unset($arr[0]); } $arr1 array(1, 2); $arr2 array(1, 2); get_arr(&$arr1); get_arr($arr2); echo count($arr1); echo count($arr2);exit;结果是&#xff1a;1,2

安装Bumblebee解决Ubuntu笔记本发热量大问题

Bumblebee实现linux下双显卡切换&#xff0c;之后基于Bumblebee开发ironhide&#xff0c;但是ironhide效果也不是很好&#xff0c;有时候发热还是 大。现在终于等来了新版的Bumblebee 3.0 “Tumbleweed”&#xff0c;拯救了广大在双显卡水深火热之中的用户。本人通过翻译&#…

linux 电源管理

Problem&#xff1a;当我安装Ubuntu12.04后&#xff0c;不管系统是不是在做密集的数据处理&#xff0c;笔记本电脑的风扇时刻都处于高速旋转状态。运气很好&#xff0c;StackOverflow上找到了这个问题的解决方法。 Solution&#xff1a;在终端运行下列三条命令&#xff1a;sudo…

thinkpad-X200恢复系统问题

恢复系统时一定要把硬盘模式调成AHCI 如果用兼容模式恢复的系统&#xff0c;使用一段时间会蓝屏

php设计模式学习

http://www.ibm.com/developerworks/cn/opensource/os-php-designptrns/

接口 抽象类 继承 区别

接口是公开的&#xff0c;里面不能有私有的方法或变量&#xff0c;是用于让别人使用的&#xff0c;而抽象类是可以有私有方法或私有变量的&#xff0c; 另外&#xff0c;实现接口的一定要实现接口里定义的所有方法&#xff0c;而实现抽象类可以有选择地重写需要用到的方法&…

zend studio 9 字体,颜色,快捷键

由于zend又出新版的 studio&#xff0c;为了感受一下所说的快速&#xff0c;安装了zend studio 9 特意感受一把。一直以来&#xff0c;都不觉得zend studio比dreamweaver好用。可能是先入为主的观念&#xff0c;我把zend studio8的代码着色风格全改成了DW风格&#xff0c;哈哈。…