Memcached内存存储
早就听说过Memcached独特的内存管理方式,写着篇文章的目的就是了解Memcached的内存管理,学习其源代码.
1.什么是Slab Allocator
memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存,Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以期望完全解决内存碎片问题。而且,slab allocator还有重复使用已分配的内存的目的。 也就是说,分配到的内存不会释放,而是重复利用。
2.Slab Allocation的主要术语
Page 分配给Slab的内存空间,默认是1MB,分配给Slab之后根据slab的大小切分成chunk
Chunk 用于缓存记录的内存空间
Slab Class 特定大小的chunk的组
3.Slab初始化
在Memcached启动时候会调用slab的初始化代码(详见memcached.c中main函数调用slabs_init函数).
slabs_init函数声明:
1 |
|
其中limit表示memcached最大使用内存;factor表示slab中chunk size的增长因子,slab中chunk size的大小等于前一个slab的chunk size乘以factor;
memcached.c中main函数调用slabs_init函数:
1 |
|
其中settings.maxbytes默认值为64M,启动memcached使用选项-m设置;settings.factor默认为1.25,启动memcached时候使用-f设置;preallocate指的是启动memcached的时候默认为每种类型slab预先分配一个page的内存,默认是false;
1 |
|
slabs_init函数实现:
1 |
|
其中settings.chunk_size默认为48:
settings.chunk_size = 48; /* space for a modest key and value */
POWER_LARGEST指slab种类的最大值,默认只为200,在memcached.c中设置
#define POWER_LARGEST 200
settings.item_size_max就是每个page的大小,默认1M,在memcached.c中初始化:
settings.item_size_max = 1024 * 1024; /* The famous 1MB upper limit. */
默认不开启预分配,因为很多时候Memcached只存储一种类型的数据(即其大小相对比较固定),这时候其他类型的预分配的slab空间就会浪费.
预分配的逻辑就是从最小的slab开始,为每类slab分配一个Page大小的空间(空间不足时停止分配):
1 |
|
do_slabs_newslab的工作就是为某一个slab分配空间,并将空间划分乘固定大小的chunk:
1 |
|
split_slab_page_into_freelist的主要控制就是Page划分乘chunk并清空:
1 |
|
memcached的内存分配策略就是:按slab需求分配page,各slab按需使用chunk存储.
按需分配的意思就是某一类slab没有对象可存,就不会分配(非preallocate模式),某类slab存储对象很多,就会分配多个slab形成链表.
这里有几个特点要注意:
1.Memcached分配出去的page不会被回收或者重新分配;
2.Memcached申请的内存不会被释放;
3.slab空闲的chunk不会借给任何其他slab使用(新版本memcached有slab_reassign,slab_automove的功能);
slab内存结构图,二维数组链表:
4.往Slab中缓存记录
memcached根据收到的数据的大小,选择最适合数据大小的slab. memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk, 然后将数据缓存于其中.
代码如下:
1 |
|
参数是待存储对象的大小,根据这个大小,从最小的Chunk Size开始查找,找到第一个(即最小的)能放下size大小的对象的Chunk.找不到(size大于最大的Chunk Size)返回0(这就是为什么slab class从1开始而不是从0开始).
如果某个Slab没有剩余的Chunk了,系统便会给这个Slab分配一个新的Page以供使用,如果没有Page可用,系统就会触发LRU机制,通过删除冷数据来为新数据腾出空间,这里有一点需要注意的是:LRU不是全局的,而是针对Slab而言的.
slab内存分配示例:
5.Slab Allocator的缺点
由于Slab Allocator分配的是特定长度的内存,因此无法有效利用分配的内存。 例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。
6.Memcached减少内存浪费
4.1:调整growth factor
(1).估算我们item的大小
key键长+suffix+value值长+结构大小(48字节)
(2).逐步调整growth factor,使得某个slab的大小和我们的item大小接近(必须大于我们item的大小)
7.过期数据
(1).LRU过期策略;
(2).在slab级别上执行LRU策略;
(3).查看是否过去是在get的时候,即懒惰(lazy)检查;
8.memcached-tool脚本
memcached-tool脚本可以方便地获得slab的使用情况 (它将memcached的返回值整理成容易阅读的格式),可以从下面的地址获得脚本: http://www.netingcn.com/demo/memcached-tool.zip
使用方法也极其简单:
1 |
|
比如:
1 |
|
输出示例:
1 |
|
各列的含义为:
# slab class编号
Item_Size Chunk大小
Max_age LRU内最旧的记录的生存时间
1MB_pages 分配给Slab的页数
Count Slab内的记录数
Full? Slab内是否含有空闲chunk
Memcached内存存储的更多相关文章
- memcached全面剖析–2. 理解memcached的内存存储
Slab Allocation机制:整理内存以便重复使用 最近的memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存. 在该机制出现以前,内存的分配是通过对所有记录简 ...
- memcached全面剖析--2.理解memcached的内存存储
下面是<memcached全面剖析>的第二部分. 发表日:2008/7/9 作者:前坂徹(Toru Maesaka) 原文链接:http://gihyo.jp/dev/feature/01 ...
- memcached 内存初始化与key-value存储
本次笔记未涉及到slab的动态重新平衡分配 /**首先介绍一下一个跟内存相关的非常重要的概念,内存块类型数据结构:*/ typedef struct { unsigned int size; /* c ...
- Memcached内存分配优化及使用问题
前几天做了个Memcached的思考,并测试了一些数据,是关于如何提高Memcached内存使用率的问题.在启动memcached的时候可以加-f参数和-n参数.-f指定各slab里面chunk大小的 ...
- memcached内存管理机制[未整理]
memcached默认采用的是Slab Allocator的机制分配管理内存的,在此之前,内存的分配是通过对所有的记录简单地进行malloc和free来进行的,但这种方式容易造成很多内存碎片,加重操作 ...
- memcached内存分配机制
memcached的内存分配没有用到c语言中自带的malloc函数,因为这个函数分配内存的时候效率很低,对于这种要求快速响应,对效率要求非常高的缓存软件来说非常不合适. memcached用的是自己的 ...
- Memcached内存缓存技术
Memcached是什么,有什么作用? Memcached是一个开源的.高性能的内存缓存软件,从名称上看Mem就是内存的意思,而Cache就是缓存的意思. Memcached通过在事先规划好的内存空间 ...
- 03 Memcached内存分布机制
一:Memcached 内存分布机制 (1)把内存分配成slab 和不同大小的chunk.在跟据键值的大小在选择对应的chunk.这样可以减少最小的内存浪费,内存浪费是不可避免的.[把内存划分成若干个 ...
- Redis内存存储结构分析
1 Redis 内存存储结构 本文是基于 Redis-v2.2.4 版本进行分析. 1.1 Redis 内存存储总体结构 Redis 是支持多key-value数据库(表)的,并用 RedisDb 来 ...
随机推荐
- Java-调用抽象类中指定参数的构造方法
abstract class person { private String name; private int age; public person(String name,int age) ...
- DEV gridcontrol 设置行数据超宽换行
第一 在main > columns 的 某个gridcolumn下的 columnEdit为新建为 repositoryitemmemoedit 第二 repositor下的optionvie ...
- 基于内容的图片检索CBIR(Content Based Image Retrieval)简介
传统的图像检索过程,先通过人工对图像进行文字标注,再利用关键字来检索图像,这种依据图像描述的字符匹配程度提供检索结果的方法,简称“以字找图”,既耗时又主观多义.基于内容的图像检索客服“以字找图”方式的 ...
- thinkpad x230i U盘启动
现在的thinkpad的笔记本真麻烦,设置个U盘启动都不好使,网上找了好多都不管用,后来打电话问的售后电话才搞定,具体步骤如下: 按F1进bios的 [Security]中最下面Secure Boot ...
- ASP.NET Zero--5.配置权限
修改角色的时候,会有一份权限列表,可以给这个角色分配哪些权限,那如何添加一个新权限呢? 这里以添加一个“测试”的权限为例 1.打开AppPermissions.cs [..\MyCompanyNa ...
- Python第一天——入门Python(2)字符串的简单操作
数据的操作 字符串的一些常用操作: 1 1 #!/usr/bin/env python 2 # #coding=utf-8 3 # 4 # test='hello world' 5 # print(t ...
- GOPS2017全球运维大会深圳站 出席嘉宾盘点!
去年,GOPS全球运维大会在深圳出发,当时门票提前几周收盘,2017年,承载着运维人的期望,GOPS全球运维大会再次来到了深圳.第六届GOPS2017全球运维大会深圳站(本次)将于2017年4月21日 ...
- Mutex的使用方法以及封装的AutoLock介绍(转载)
Mutex-互斥类 互斥类-MutexMutex是互斥类,用于多线程访问同一个资源的时候,保证一次只有一个线程能访问该资源.在<Windows核心编程>①一书中,对于这种互斥访问有一个很形 ...
- [Q]手动加载菜单方法
一般情况下,安装程序会自动安装依云软件菜单,但可能由于某些原因未能自动安装的话,您可以手动加载菜单,步骤如下: 在AoutCAD命令行输入"CUILOAD",会弹出"加载 ...
- 关于Container With Most Water的求解
Container With Most Water 哎,最近心情烦躁,想在leetcode找找感觉,就看到了这题. 然而,看了题目半天,硬是没看懂,于是乎就百度了下,怕看到解题方法,就略看了下摘要,以 ...