14.5 缓存数据的删除和替换
14.5.1 过期数据
可以使用ttl查看key的状态。已过期的数据,redis并未马上删除。优先去执行读写数据操作,删除操作延后执行。
14.5.2 删除策略
redis中每一个value对应一个内存地址,在expires,一个内存地址,对应一个时间截,如果达到指定时间,就完成删除处理
三种删除策略
-
定时删除:创建一个定时器,当key设置过期时间已到达,删除key,同时expires中也删除
- 优点:节约内存
- 缺点:对于cpu实时处理压力影响,对redis执行的效率有影响
-
惰性删除:数据到达过期时间,先不做删除,直到下次访问该数据时,再做删除(以空间换时间)
- 执行流程:在get数据时,先执行redis中一个内部函数 expireIfNeeded(),如果没有过期,就返回,如果已过期,就删除,返回-2
- 优点:节约CPU资源
- 缺点:内存占用过大。
-
定期删除
- redis启动服务时,读取server.hz的值,默认为10,可以通过info server指令查看
- 每秒钟执行server.hz次定时轮询,调用serverCron()函数,函数中又执行databasesCron(),对16数据库进行轮询,执行了activeExpireCycle(),检测其中元素的过期情况。每次轮询都执行250ms/server.hz时长。随机从对应的库中抽取20个(默认)key进行检测
- 如果key已过期,则删除key
- 如果一轮中删除的key数量>w*25%,则再次循环刚才的过程
- 如果一轮中删除的key数量<=w*25%,则开始检查下一个库
redis中使用惰性删除和定期删除
14.5.3 逐出算法
通过 配置文件 maxmemory < bytes>来设置最大缓存容量。一般情况,建议设置为总数据的15%到30%,在实际生产环境下,可以设置50%。如果不设置,默认全部使用
redis缓存淘汰策略
淘汰策略 noevction不淘汰 进行数据淘汰 过期数据淘汰 所有数据淘汰 volatile-lru volatile-lfu volatile-ttl volatile-random allkeys-lru allkeys-lfu allkeys-random
在redis默认情况下,不进行数据淘汰noevction,一旦缓存被写满了,再有写请求,redis直接返回错误。
过期数据淘汰策略,先限定了,数据都是在过期范围。
- valotile-ttl:在进行筛选时,根据过期时间先后顺序进行一个删除,越早过期的越先被删除
- valotile-random:在设置了过期时间的键值对中,进行随机删除
- valotile-lru:会使用LRU算法筛选设置了过期的键值对
- valotile-lfu:会使用LFU算法筛选设置了过期的键值对
所有数据淘汰策略:
- allkeys-random:从所有键值对中随机筛选并删除
- allkeys-lru:从所有键值对中采用LRU算法进行筛选删除
- allkeys-lfu:从所有键值对中采用LFU算法进行筛选删除
LRU算法
算法Least Recently Used,最近最少使用原则,最近不用的数据会被筛选出来,最近频繁使用的数据会保留
lru算法,需要使用链表来管理所有缓存数据,带来内存开销。有数据被访问时,需要执行链表数据的移动,会降低redis性能。
记录数据最后一次访问的时间截,第一次会随机选出N个数据,作为一个候选集合,作一个排序,再把lru最小的数据进行淘汰
上面提到的N的配置:maxmemory-samples 5
LFU算法
算法Least Frequently Used,最不常用原则。根据历史访问频率来淘汰数据。
每个数据块都有一个引用计数,按引用计数来排序。如果引用计数相同,按照时间排序
- 新加入的数据放在队尾,引用计为1
- 当数据被访问,引用计数增加,队列重排
- 当需要淘汰数据时,将队列尾部的数据块删除
逐出算法选择:maxmemory-policy noeviction
- 优先使用allkeys-lru策略。
- 如果业务数据访问频率差别不大,可以建议使用allkeys-random。
- 首推的新闻、置顶视频,不设置过期时间,可以建议使得volatile-lru。