1. memcached机制

a.  守护进程机制
     -UNIX daemon

b.   Socket事件处理机制
     -non-blocked:非阻塞
     -libevent:异步事件处理
     -epoll/kqueue

c.   内存管理机制
     -slab:内存分配机制
     -LRU:对象清除机制
     -Hash机制:快速检索item

d.  多线程处理机制:pthread(POSIX)线程模式
     -编译时开启:./configure –enable-threads
     -目前还比较粗糙,锁机制locking不够完善 
     -负载过重时,可以开启(-t线程数为CPU核数)

 

2. memcached内存管理机制

a.  SLAB内存处理机制
     -提前分配大内存slab 1MB,再进行小对象填充chunk
     -避免大量重复的初始化和清理 减轻内存管理器负担
     -避免频繁malloc/free系统碎片

b.  懒惰检测机制
     -不检测item对象是否超时
     -get时检查item对象是否应该删除

c.   懒惰删除机制
      -删除item对象时,不释放内存,作删除标记,指针放入slot回收插槽,下次分配的时候直接使用

 

3. 名词解释

a.  slab class:内存区类别(48byte-1MB)
     -slab==page:动态创建的实际内存区
     -slab classid:slab class的ID

b.  chunk:数据区块,固定大小
     -item:实际存储在chunk中的数据项

1. slab内存结构图:二维数组链表

slab是一次申请内存的最小单位

 

2. slab内存分配实例

3. 实例数据

4. 计算slab占用内存

5. slab参数

进程内存区
slabclass元信息:1.1中是21byte,1.2中是200byte
Hashtable:1.1中位41MB,1.2中位65MB

数据内存区
slab默认大小为1048576byte(1MB),大于1MB数据忽略
chunk初始大小,1.1中是1byte,1.2中是48byte

增长因子factor
1.1中,chunk大小为初始大小*2^n,n为classid,即:
id为0的slab大小1byte,id为1的slab大小2byte,id为2的slab大小4byte...
id为20的slab,每chunk大小为1MB,只有一个chunk
1.2中有一个factor值,默认为1.25
96,120,152...

 

1. Item数据格式

Item是保存在chunk中的实际数据

    

2. 新建Item分配内存过程

快速定位slab classid
计算key+value+suffix+32结构体,如90byte
如果>1MB,无法存储丢弃
取最小冗余的slab class
如:有48,96,120,存90会选择96

按顺序寻找可用chunk
slot:检查slab回收空间slot里是否有剩余chunk
delete:delete时标记到slot
exptime:get时检查的过期对象标记到slot
end_page_ptr:检查page中是否有剩余chunk
memory:内存还有剩余则开辟新的slab
LRU:Slab内部扫描Item双向链表50次

 

1. 调优的最高指示精神

提高内存利用率,减少内存浪费

提高命中率(80%,95%?)

调优方法:
f参数:factor增长因子 
n参数:chunk初始值 

低CPU消耗(瓶颈在于网络IO)
libevent事件机制
slab内存预分配机制

适合使用大量低CPU的机器搭建集群
32位机器最大2GB,64GB无限制
-m分配内存为数据区,memcached本身也需要占用内存,因此不可将物理内存全部分配
使用连接池维持连接

 

2. 内存浪费

slab尾部剩余空间
如classid=40中,两个chunk占用了1009384byte,就有1048576-1009384=39192byte被浪费
解决办法:规划slab=chunk*n整数倍

 slab中chunk利用率低:申请的slab只存放了一个Item
解决办法:规划slab=chunk

chunk存储Item浪费
如I tem是100,存到128字节chunk,就有28字节浪费
解决办法:规划chunk=Item

3. 使用合适的factor,减少浪费

-f参数:默认为1.25,曾经为2
值越小,slab中chunk size差距越小,内存浪费越小

建议:计算一下数据的预期平均长度,调整factor,以获得最恰当的设置

 

4. 根据数据分布调整factor

非均匀分布,即数据长度集中在几个区域内
如保存用户Session

更极端的状态是等长数据
如定长键值,定长数据
多见于访问、在线统计或执行锁

计算Item长度
key键长+suffix+value值长+结构大小(32字节)

Can’t dump
无法备份,重启无法恢复
Can’t iterate over keys
无法查询
Not persistent
没有持久化,重启全部丢失
Not redundant
单点故障failover
No Sessions
崩溃没法查找原因
No security
任何机器都可以telnet,需要放在防火墙后
内存问题
LRU是slab局部,没有全局
有空间浪费
日志问题
没有合理的日志
集群问题
集群增加机器成本高

 

参考推荐:

Memcached分布式

Memcache内存分配策略