您的位置:首页 > 数据库 > Memcache

memcache与redis lru 一致性hash 缓存雪崩 缓存无底洞 永久数据被踢现象

2016-03-16 17:41 671 查看
memcache的细节讨论:

1、生命周期的问题:

生命周期设置方式有两种:

第一种是:秒数,但是有限制,不能超过 2592000秒(30天)。

第二种是:时间戳,比如我们要设置超过1个月,则如下设置

$mem->add('name1','yangguang',MEMCACHE_COMPRESSED,time()+3600*24*31);

如果设置为0,则表示永不过期。

存储到memcache里面的数据,什么情况下会丢失:

(1)生命周期到了

(2)关闭memcache服务
(3)关机,重启。

memcached 的内存管理与删除机制
http://www.open-open.com/lib/view/open1376034527667.html 
Memcached 的内存分配以page为单位,默认情况下一个page是1M,可以通过-I参数在启动时指定 

Memcached 并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列slabs,每个slab只负责一定范围内的数据存储

 

Chunk 是一系列固定的内存空间,这个大小就是管理它的slab的最大存放大小

Slab的内存分配。

Memcached在启动时通过-m指定最大使用内存,但是这个不会一启动就占用,是随着需要逐步分配给各slab的。

         如果一个新的缓存数据要被存放,memcached首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如 果没有则要进行申请。slab申请内存时以page为单位,所以在放入第一个数据,无论大小为多少,都会有1M大小的page被分配给该slab。申请到 page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,在从这个chunk数组中选择一个用于存储 数据。如下图,slab 1和slab 2都分配了一个page,并按各自的大小切分成chunk数组

 

综合上面的介绍,memcached的内存分配策略就是:按slab需求分配page,各slab按需使用chunk存储。

这里有几个特点要注意,

Memcached分配出去的page不会被回收或者重新分配

Memcached申请的内存不会被释放

slab空闲的chunk不会借给任何其他slab使用

内存的碎片化

如果用c 语言直接malloc,free 来向操作系统申请和释放内存时,

在不断的申请和释放过程中,形成了一些很小的内存片断,无法再利用.

这种空闲,但无法利用内存的现象,---称为内存的碎片化.

memcached 的过期数据惰性删除

 

1: 当某个值过期后,并没有从内存删除, 因此,stats 统计时, curr_item 有其信息

2: 没有get过这个过期的值,,将不会自动删除;当某个新值去占用他的位置时,当成空chunk 来占用.

3: 当get 值时,判断是否过期,如果过期,返回空,并且清空, curr_item 就减少了.

即--这个过期,只是让用户看不到这个数据而已,并没有在过期的瞬间立即从内存删除.

这个称为lazy expiration, 惰性失效.

好处--- 节省了cpu 时间和检测的成本(不主动检查,你来get我才检查)

memcached 此处用的lru 删除机制.

分布式集群 一致性hash

缓存雪崩 缓存无底洞 永久数据被踢现象

redis

1)架构方式:c/s   客户端和服务器

(2)memcache存储数据的位置:内存中。

redis:可以存储到内存中,可以把数据同步 到硬盘中,达到数据的存储持久化。

(3)memcache存储数据类型的格式:键值对。没有行和列的概念

redis:数据存储是,键值对存储,只不过存储的值的类型比较丰富,有五种类型,string(字符串),hash(哈希),list(链表),set(集合),zset(有序集合)

 redis和memcache比较

 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

 Redis支持master-slave(主—从)模式应用。

 Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

 Redis单个value的最大限制是1GB, memcached只能保存1MB的数据

快照持久化

快照是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb.可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key修改就自动做快照。

 append only file (AOF持久化)

aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

aof方式 

当然由于os会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样aof方式的持久化也还是有可能会丢失部分修改。 

可以通过配置文件告诉reids我们想要通过fsync函数强制os写入到磁盘的时机

本质:把用户执行的每个“写”指令(添加、修改、删除)都备份到文件中,还原数据的时候就是执行具体指令而已。

key设计技巧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php