前言

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. 用linux文件处理三剑客将微信群成员导出的方法

    工具: Mac/Linux 系统 Chrome Linux命令:vi.cat. wc. grep. awk. sed.sort. uniq 步骤: 1.微信网页版登陆: https://wx.qq.c ...

  2. App 组件化/模块化之路——使用SDK的思路进行模块化设计接口

    在不久之前分享一篇<App 组件化/模块化之路——如何封装网络请求框架>文章介绍了我在项目中封装网络请求框架的思路.开发一个 App 会涉及到很多网络请求 API ,例如登录注册接口.用户 ...

  3. 最详细的浏览器css hack

    注意点: 网上很多资料中常常把!important也作为一个hack手段,其实这是一个误区.!important常常被我们用来更改样式,而不是兼容hack.造成这个误区的原因是IE6在某些情况下不主动 ...

  4. lua State加载部分库

    lua State加载部分库 在lua中,通常我们用luaL_openlibs(L)加载所有的lub标准库,但是有时候我们想只加载部分,有没有什么好的办法呢?在luaproc看到如下办法: stati ...

  5. 修改文件的所有者失(chown: changing ownership of `uploads': Operation not permitted)

    在项目开发的时候,经常需要将文件上传到指定的目录下. 例如这次用thinkphp5的时候,需要在public目录下建立uploads目录用于存放上传的资源. 首先在命令窗口下输入: mkdir upl ...

  6. DOM 遍历-同胞

    在 DOM 树中水平遍历 有许多有用的方法让我们在 DOM 树进行水平遍历: siblings() next() nextAll() nextUntil() prev() prevAll() prev ...

  7. .NET项目从CI到CD-Jenkins_Pipeline的应用

    一.罗里吧嗦 最近迁移了服务器,顺道完善下服役了一两年的Jenkins服务,主要是把Slave搭建起来,还有等等.本文只是我对Jenkins Pipeline的一些自己的理解与应用,欢迎指出错误,欢迎 ...

  8. day2--计算机基础

    一.服务器 1u服务器,1u=4.45cm 戴尔服务器种类: 电脑主机组成 主板.CPU.内存.硬盘.显卡.声卡等等. 运维关注三大部件:CPU.内存.硬盘(Disk) 电源,考虑使用双电服务器,电源 ...

  9. HTTPCLIENT 模拟登陆

    第一步构建忽略https验证的httpclient public static CloseableHttpClient getHttpClient() throws Exception { SSLCo ...

  10. C#多线程和线程同步总结

    Thread 没有参数的线程启动 Thread newThread = new Thread(new ThreadStart(DoWork)); newThread.Start(); 有参数的线程启动 ...