memcached内存模型
基本概念page/slab/chunk
Chunk属于slab,在一个slab里面有多个chunk
Slab里面也有多个page。
1slab class(slab分类) = n slab
1page=1slab = n chunk(统一长度)
page
内存分配是以page单位,默认一个page是一M,也可以通过-I参数在启动的指定。
memcached分配一个新的page后,将不会被回收或者重新分配。
Slab
避免大量重复的初始化工作,清理工作,减轻内存管理器负担
避免频繁malloc/free导致系统内存碎片
Chunk
第一列slab的类型,第二列chunk 长度,第三列预分配chunk个数
第三列*第二列=page大小=slab的大小
内存申请分配机制
memcached内存回收
memcached 不会释放内存,也不会重新分配。只是重新利用
懒清理
memcached的回收机制不是根据key的生命周期自从清理。
- 存放key的时候,新对象请求入驻这段内存空间。
- 当这个key被get的时候
当memcached内存用光后,有两个策略:1.报错 2.使用LRU
Growth factor 调大,slab数量降低,LRU频率降低,造成空间浪费会上升
Growth factor 调小,slab数据增长,LRU频率上升,造成空间浪费会降低
memcached数据过期
1.Lazy expriation
memcached内部不会监控记录是否过期,而是在get的时候检查时间戳,检查是否过期。
2.LRU
遵循最近最少使用原则。当内存不足时候,清楚最近未被使用的。
memcached客户端UI
memadmin(PHP) ---安装麻烦,要配置php运行
treeNMS(tomcat)---安装比较快,但是使用起来没memadmin好
memcached客户端程序
- memached client for java
- Spymemcached
- Xmemcached(NIO的客户端)
POM.xml 的配置
<!-- xmemcached -->
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.4.2</version>
</dependency>
<!-- memcached client for java-->
<dependency>
<groupId>com.whalin</groupId>
<artifactId>Memcached-Java-Client</artifactId>
<version>3.0.2</version>
</dependency>
如果需要使用spring并且让缓存正常工作,那么必须配置一个CacheManager;
memcached分布式
Hash和取模
余数计算分散法
- 求取Key的CRC值
- 用CRC在和服务器数量进行取模
- 根据结果存放到相应的服务器
一致性Hash
- 计算服务器的Hash值
- 根据hash值把服务节点分配到0——2^32次方的圆环上。
- 计算key的hash值,并映射到圆环上。
- 找到顺时针的第一台服务器上。
缺点:导致数据分布不均匀
引入虚拟节点解决一致性hash数据分布不均匀的问题。
memcached特性和限制
- 可以保存的item数量是没有限制的,只要内存足够
- memcached单进程最大内存是2G,可以开多个memcached进程
- 最大键长度是250字节,大于这个长度无法存储。
- 单个item的最大数据是1M,超过1m也无法存储
- 最大同时连接数是200个,最大的软连接数是1024
- Factor直接决定内存的使用情况
如何解决空间浪费问题:
1.slab空间尾部浪费
解决办法:合理规划slab和chunk之间倍数
2.slab中的使用率低:申请的slab只存放了一个item
解决办法:slab=chunk
3.chunk的空间浪费
解决办法:chunk=item