`
yanghuidang
  • 浏览: 950459 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

在使用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,如图例:


我们可以使用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是空闲的),,如图例:


在数据存入选中的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,在内存利用率上也有天然的缺陷,如图例:


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,选择一项“适合的”技术保障可用性才是王道。

分享到:
评论

相关推荐

    Memcached源码分析之内存管理

    Memcached源码分析之内存管理Memcached源码分析之内存管理

    memcached的内存分配代码

    memcached采用了一种特殊的内存分配策略,名为Slab Allocation,以避免频繁的内存碎片和提高内存利用率。 1. Slab Allocation原理: Slab Allocation的核心思想是将内存分为多个大小不等的chunk(块),每个chunk...

    Memcached内存分析、调优、集群

    这种机制减少了内存碎片,并提高了内存利用率。 - **Slab**:预分配的内存块,用于存储多个固定大小的chunks。 - **Page**:在某些实现中,slab由多个page组成,每个page包含多个chunk。 - **Item**:存储在slab中...

    Memcached 内存分析、调优、集群

    ### Memcached内存分析、调优、集群 #### 1. Memcached背景 Memcached是一款高性能的分布式内存对象缓存系统,旨在通过减轻数据库负载来加速动态Web应用的响应速度。它通过在内存中缓存数据和对象来减少读取数据库...

    Memcached内存对象缓存

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

    Memcached内存分配与SLAB机制

    这种机制能够有效地提高内存利用率并减少内存碎片,从而提高系统的整体性能。 **SLAB机制概述:** - **SLAB(Class)定义**:可以将SLAB视为一个“无底”的容器,用于存储固定大小的数据块(Chunk)。每个SLAB都有...

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

    这种方式避免了内存碎片,提高了内存利用率。 四、Memcached的过期策略 Memcached支持为每个键值对设置过期时间,一旦超过这个时间,数据会被自动删除。同时,它也使用LRU(Least Recently Used)算法,当内存满时...

    PHP内存缓存技术memcached 的安装和工作原理介绍

    它通过存储数据在内存中,避免了反复查询数据库,显著提升了网站性能。memcached设计简洁,易于部署,支持多种编程语言的客户端,包括PHP。 ### 一、PHP内存缓存技术memcached简介 memcached的核心功能是提供临时...

    memcached 64位 window

    **标题与描述解析** ...总的来说,Memcached 64位 window为Windows环境提供了强大的内存缓存解决方案,可以有效提升依赖数据库的应用性能。正确配置和使用Memcached,能显著改善用户体验,降低服务器压力。

    Memcached内存分析、调优、集群.ppt

    这种设计减少了内存碎片,提高了内存利用率。Memcached在内存不足时,会根据LRU(Least Recently Used)策略淘汰最近最少使用的数据。 【Memcached内存调优】 内存调优主要包括以下几个方面: 1. `-m`参数:用于...

    memcached 分布式内存

    **Memcached 分布式内存详解** Memcached 是一套由 danga.com 开发的高效、分布式的内存对象缓存系统,其主要目标是在高流量的动态应用程序中减轻数据库的负载,从而提升整体系统的性能。这套系统的工作原理是将...

    memcached1.4.31

    - **内存管理**:Memcached 使用Slab Allocation机制,将内存划分为多个大小固定的Slabs,每个Slab存储相同大小的对象,避免了内存碎片,提高了内存利用率。 - **预分配内存**:为了避免频繁的内存分配和释放,...

    基于内存的K-V数据平台(Memcached)

    **基于内存的K-V数据平台——Memcached** Memcached是一款高性能、分布式内存对象缓存系统,主要用于加速动态Web应用,通过将数据存储在内存中,减少数据库的访问次数,从而提高应用性能。它是一个轻量级的服务,...

    安装Memcached及Memcached配置

    - 在实际应用中,你可以根据需求调整Memcached的配置,例如调整内存分配、设置过期时间、优化缓存策略等,以最大化性能和资源利用率。 - 与其他系统集成,例如PHP、Python、Java等,可以使用相应的客户端库进行...

    memcached安装包以及MemCachedClient

    `commons-pool-1.5.6.jar` 是 Apache Commons Pool 库,它是对象池设计模式的实现,Spymemcached 使用它来管理连接池,以优化资源利用率。 `slf4j-api-1.6.1.jar` 和 `slf4j-simple-1.6.1.jar` 是 Simple Logging ...

    memcached高性能内存k-v缓存服务器

    memcached介绍 memcached安装 memcached操作 内存存储机制 数据过期与删除机制 php操作memcached 多服务器集群算法 缓存无底洞效应 缓存雪崩 老数据被踢现象 结课作业

    memcached服务器端memcached.exe 下载

    Memcached是一款高性能、分布式内存对象缓存系统,常用于减轻数据库负载,提高Web应用的性能。它通过在内存中存储数据来快速访问,避免了反复读取硬盘上的数据,从而提高了应用程序的响应速度。 标题“memcached...

Global site tag (gtag.js) - Google Analytics