1.Memcached的概念
Memcached是一个免费开源的,高性能的,具有分布式对象的缓存系统,它可以用来保存一些经常存取的对象或数据,保存的数据像一张巨大的HASH表,该表以Key-value对的方式存在内存中
2.Memecached注意的事项
- key的限制:
key 不能有空格和控制字符,memcached的key的最大长度是250个字符,注意250是memcached服务器端内部的限制(可以修改),如果您使用的客户端支持”key的前缀”或类似特性,那么key(前缀+原始key)的最大长度是可以超过250个字符的。我们推荐使用使用较短的不重复key,因为可以节省内存和带宽 - value的限制
单个item最大存储1M,当然这个是默认的,推荐不改;如果你的数据大于1MB,可以考虑在客户端压缩或拆分到多个key中 - 过期时间
如果设置过期时间的话,时间最多30天 - 最大连接数
推荐200
3.Memcached的过期策略
使用LRU(last recently used)算法淘汰数据:当向memcached存储数据时,你可能会设置一个过期时间,可以是永久也可以是一段时间,但是如果一旦给memcached分配的内存使用完毕,则首先会替换掉已失效的数据,其次是最近最少使用的数据
4.Memcached的存储机制
Memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题.
Memcached中有几个专业术语Slab,Page,Chunk 用图来说明下
Memcached在分配内存时是以Page为单位的,默认情况下一个Page是1M,内部是一个个chunk,当chunk的大小等于Page大小时也就是Memcached所能存储的最大数据大小了,可以在启动时通过-l来指定它,最大可以支持128M。
Memcached并不是将所有大小的数据都存放在一起的,而是将内存空间划分为一个个的slab,每个slab只负责一定范围内的数据。上图中,slab1只负责96bytes的数据,slab2负责120bytes的数据。
在存储数据时,如果这个item对应的slab还没有创建则申请一个page的内存,将这个page按照所在slab中chunk的大小进行分割,然后将item存入。
如果已经创建存在了,判断对应的slab是否用完,没用完直接存储。
如果对应的slab已经用完了,看内存是否用完,没用完会申请一个新的page进行分割存储,用完了则直接进行LRU
-f:增长因子,chunk的值会按照增长因子的比例增长默认是 1.25 (48*1.25=60 必须是8的倍数+4 = 64针对下图数据的说明)
-n:每个chunk的初始大小(key+value+flags),chunk大小还包括本身结构体大小.
-I:每个slab page大小
-m:需要分配的大小
typedef struct {
unsigned int size;
unsigned int perslab;
void **slots;
unsigned int sl_total;
unsigned int sl_curr;
void *end_page_ptr;
unsigned int end_page_free;
unsigned int slabs;
void **slab_list;
unsigned int list_size;
} slabclass_t;
unsigned int size = sizeof(item) + chunk_size;
可以把item当成上面的结构体 32位系统是32字节;64位系统48字节;
上图中n我们设置成了10 就是 32+10 = 42 但是必须是八的倍数,所以第一块slab的chunk是48
默认的key+value=48即chunk_size;如下图 -f设置成2 所以(48+32) =80;第二个是80*2=160
chunk_size最大尺寸是跟着page走的,默认是1M
查看Memcached使用状况
命令: stats slabs
结果参数:
chunk_size:chunk大小
chunk_per_page:每个page的chunk数量
total_pages:page数量
total_chunks:chunk数量*page数量
used_chunks:已被分配的chunk数量
free_chunks:曾经被使用,但是目前被回收的chunk数.
free_chunks_end:从来没被使用的chunk数
mem_requested:请求存储的字节数
active_slabs:活动的slabs.
total_malloced:实际已分配的内存数.
5.Memcached的分布式
Memcached是一个集中式的单点缓存系统,本身并不具备集群功能,这方面的操作主要是由客户端来完成的。所以说到Memcached的分布式就一定会提到Memcached的客户端
选择服务器算法有两种:一种是根据余数来计算分布,另一种是根据散列算法来计算分布
余数算法:
先求得键的整数散列值,再除以服务器台数,根据余数确定存取服务器,这种方法计算简单,高效,但在memcached服务器增加或减少时,几乎所有的缓存都会失效
散列算法:
先算出memcached服务器的散列值,并将其分布到0到2的32次方的圆上,然后用同样的方法算出存储数据的键的散列值并映射至圆上,最后从数据映射到的位置开始顺时针查找,将数据保存到查找到的第一个服务器上,如果超过2的32次方,依然找不到服务器,就将数据保存到第一台memcached服务器上。如果添加了一台memcached服务器,只在圆上增加服务器的逆时针方向的第一台服务器上的键会受到影响