# Redis过期策略
# Redis过期键执行流程
Redis 之所以能知道哪些键值过期,是因为在Redis维护了一个字典,存储了所有 设置 了过期时间的键值,我们称之为过期字典。
过期键判断流程如下图所示:
# 过期策略
常见过期策略:
- 定时删除
在设置键值过期时间时候,创建一个定时时间,当过期时间到达时,由时间处理器自动执行键的删除操作
- 惰性删除
不主动删除过期键,每次从数据库获取键值时判断是否过期,如果过期则删除键值,并返回 null。
- 定期删除
每隔一段时间检查一次数据库,随机删除一些过期键。(Redis 默认每秒进行 10 次过期扫描)
定期删除过程:
- 从过期字典中随机取出 20 个键;
- 删除这 20 个键中过期的键;
- 如果过期 key 的比例超过 25%,重复步骤 1。
同时为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,默认不会超过 25ms。
# 内存淘汰机制与算法
Redis过期策略指的是Redis使用那种策略,来删除已经过期的键值对;
Redis内存淘汰机制指的是当Redis运行内存已经超过了Redis设置的最大内存之后,将采用什么策略来删除符合条件的键值对
# 常用命令
查询最大运行内存: config get maxmeory (当 maxmemory 为 0 时,表示没有内存大小限制。)
查看Redis使用的内存淘汰策略:config get maxmemory-policy
# 内存淘汰策略
- noeviction: 不淘汰任何数据,当内存不足时,新增操作会报错(Redis默认淘汰策略)
- allkeys-lru:淘汰整个键值中最久未使用的键值;
- allkeys-random:随机淘汰任意键值;
- allkeys-lfu:淘汰整个键值中最少使用的键值。
- volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值;
- volatile-random:随机淘汰设置了过期时间的任意键值;
- volatile-ttl:优先淘汰更早过期的键值。
- volatile-lfu:淘汰所有设置了过期时间的键值中,最少使用的键值;
# 内存淘汰算法
# LRU算法
LRU 全称是 Least Recently Used 译为最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。
# Redis中LRU算法实现
Redis shying的是一种近似LRU算法,目的是为了更好的节约内存,它的实现方式是给现有的数据结构添加一个额外的字段,用于记录此键值的最后一个访问时间,Redis内存淘汰时,会使用随机采样的方式来淘汰数据,它是随机取5个值,然后淘汰最久没有使用的那个。
# LFU算法
LFU 全称是 Least Frequently Used 翻译为最不常用的,最不常用的算法是根据总访问次数来淘汰数据的,它的核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。
在 Redis 中 LFU 存储分为两部分,16 bit 的 ldt(last decrement time)和 8 bit 的 logc(logistic counter)。
- logc 是用来存储访问频次,8 bit 能表示的最大整数值为 255,它的值越小表示使用频率越低,越容易淘汰;
- ldt 是用来存储上一次 logc 的更新时间。