memcached内存管理
前言
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内存管理的更多相关文章
- memcached 内存管理 分析(转)
Memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,便于我们理解memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用.这里简单谈一下我对me ...
- 简述 Memcached 内存管理机制原理?
早期的 Memcached 内存管理方式是通过 malloc 的分配的内存,使用完后通过 free 来回收内存,这种方式容易产生内存碎片,并降低操作系统对内存的管理效 率.加重操作系统内存管理器的负担 ...
- 分布式缓存技术memcached学习(三)——memcached内存管理机制
几个重要概念 Slab memcached通过slab机制进行内存的分配和回收,slab是一个内存块,它是memcached一次申请内存的最小单位,.在启动memcached的时候一般会使用参数-m指 ...
- Memcached内存管理模型分析
Memcached 是一个高性能的分布式内存对象缓存系统,它通过在内存中缓存数据和对象来减少读取数据库的次数,从而减轻RDBMS的负担,提高服务的速度.提升可扩展性.本文将基于memcached1.4 ...
- Memcached 内存管理详解
Memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,便于我们理解memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用. 首先需要我们先了解两 ...
- memcached内存管理机制[未整理]
memcached默认采用的是Slab Allocator的机制分配管理内存的,在此之前,内存的分配是通过对所有的记录简单地进行malloc和free来进行的,但这种方式容易造成很多内存碎片,加重操作 ...
- 分布式缓存技术memcached学习系列(三)——memcached内存管理机制
几个重要概念 Slab memcached通过slab机制进行内存的分配和回收,slab是一个内存块,它是memcached一次申请内存的最小单位,.在启动memcached的时候一般会使用参数-m指 ...
- memcached内存管理机制分析
memached是高性能分布式内存对象系统,通过在内存中存储数据对象来减少对磁盘的数据读取次数,提高服务速度. 从业务需求出发.我们通过一条命令(如set)将一条键值对(key,value)插入mem ...
- 分布式缓存系统 Memcached 内存管理机制
在前面slab数据存储部分分析了Memecached中记录数据的具体存储机制,从中可以看到所采用的内存管理机制——slab内存管理,这也正是linux所采用的内存高效管理机制,对于Memchached ...
随机推荐
- Java调度线程池ScheduledThreadPoolExecutor源码分析
最近新接手的项目里大量使用了ScheduledThreadPoolExecutor类去执行一些定时任务,之前一直没有机会研究这个类的源码,这次趁着机会好好研读一下. 该类主要还是基于ThreadPoo ...
- 在unity3d游戏中添加中文语音控制
最近打算尝试一下OLAMI在游戏中应用的可能性,这里做一下记录. unity官方教程中的几个项目很精简,但看起来很不错,里面有全套的资源.最后我选择了tanks-tutorial来做这个实验. 下载和 ...
- Spring Cloud官方文档中文版-Spring Cloud Config(上)
官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http ...
- LeetCode 572. Subtree of Another Tree (是否是另一个树的子树)
Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and no ...
- swift之函数式编程(五)
文章内容来源于<Functional Programing in Swift>,详情请看原著 The Value of Immutability swift 对于控制值改变有一些机制.在这 ...
- 出现Unreachable code问题的原因
在Java中出现Unreachable code这种错误,一般是出现在循环当中,当循环结束时,循环体内却还有代码不能执行,换句话说就是这句话在循环题中执行不到.比如 while(true) { int ...
- rsync 服务部署详解
第1章 rsync 软件介绍 1.1 什么是rsync rsync 是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据同步备份的优秀工具. http://www.samba.org/ft ...
- BootStrap Table使用小结
1.在当前表格的最后新增数据 $("#data_module_table").bootstrapTable('append', data.data);//data.data---- ...
- Android 开发笔记___drawable
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- 行内脚本的位置放置----css阻塞行内脚本
行内脚本:避免放置在css和其他资源之间. 若在head中,最好放在css样式表之前,如果放置在样式表之后,会引起css阻塞. css阻塞:由于浏览器要保证css和JavaScript的执行顺序,cs ...