过期策略与淘汰策略

本文详细介绍了Redis的过期策略,包括懒惰删除和定时遍历机制,以及如何设置过期时间防止大批key同时过期导致的问题。此外,还深入探讨了Redis的淘汰策略,如noeviction、volatile-lru、allkeys-lru等,并解释了它们的工作原理及应用场景。

过期策略与淘汰策略

过期策略

为key设置过期时间:expire key 5(5s过期)

查看key的剩余时间:ttl key(未设置超时返回-1,已超时返回-2)

redis的过期实现通过两种方式,分别是懒惰删除和定时遍历。

懒惰删除就是用到某个key的时候再去查它是否过期,如果过期就删除。

定时遍历是一个集中处理的方式,redis会把所有设置了过期时间的key放到同一个字典中,默认每秒10次过期扫描,每次随机查字典中的20个key,然后删除,如果其中过期的比例超过四分之一就重复这个动作,为了防止循环过度规定扫描时间的上限是25ms。不过即使如此,客户端如果设置超时的话,连接失败就会报出大量异常。

redis只能单线程处理,为了避免不产生大批key同时过期卡死,要给过期时间设置一个随机范围,一般用固定活动过期时间+随机冗余时间来防止。

从库的过期策略是被动的,只能等待主库删除key时将操作写进AOF日志文件,然后同步到从库。这种异步同步可能带来不一致的风险。

淘汰策略

可以设置maxmemory来限制最大使用内存,如果超出了还可以选择几种策略来应对:

noeviction:不会继续服务写请求,读请求可以继续进行,这是默认的淘汰策略

volatile-lru:淘汰已经过期的,最少使用的key

volatile-ttl:淘汰已经过期的,剩余寿命最短的

volatile-random:随机淘汰一些已经过期的

allkeys-lru:淘汰那些最少使用的key

allkeys-random:随机淘汰一些key

如果redis只起缓存功能,那么用allkeys就可以,如果想使用持久化功能,那么就必须使用volatile,保证永久的key不被淘汰。

在4.0版本中淘汰策略增加了两项:

volatile-lfu和allkeys-lfu分别是对已经过期的key和所有key进行LFU淘汰,开启了这个选项之后还能获得对象的LFU计数。LFU是根据访问频率来计算热度,优先淘汰热度低的。redis的LFU热度是分钟级的,redis缓存了系统时间戳(因为获取属于系统调用很费时间)。

淘汰的算法

redis采用的是一种近似LRU算法,因为严格的需要消耗大量内存,数据结构很复杂。这种近似LRU为每一个key增加了一个最后一次被访问的时间戳信息,如果发现内存超过maxmemory就会执行LRU,随机选择一些key,然后淘汰掉最旧的key,然后循环进行,直到内存低于maxmemory为止。在redis3.0中还增加了淘汰池来提升这个算法的效果,每次循环出来的key都会放入淘汰池中,然后再选择最旧的key淘汰,剩余保留在淘汰池中。

转载于:https://www.cnblogs.com/shizhuoping/p/11525764.html

### Redis 的过期策略淘汰策略 #### 过期策略 Redis 的过期策略主要用于处理设置了生存时间(TTL)的键。当一个键被设置为在某个时间点后自动删除时,Redis 并不会立即删除该键,而是采用惰性删除和定期删除两种机制来管理这些过期键。 - **惰性删除**:只有当客户端尝试访问一个键时,Redis 才会检查该键是否已过期。如果已过期,则删除该键[^1]。 - **定期删除**:Redis 会在后台周期性地检查数据库中是否存在过期键,并主动删除它们。这种机制可以减少内存占用,但也会增加 CPU 负载。定期删除的频率和每次删除的键数量由 Redis 配置决定[^1]。 #### 淘汰策略 Redis 的淘汰策略用于解决内存不足的问题。当 Redis 内存达到最大限制时,它会根据配置的淘汰策略选择一些键进行删除,以释放内存空间。常见的淘汰策略包括: - **LRU (Least Recently Used)**:删除最近最少使用的键。此策略假设最近未使用的键在未来也不太可能被使用[^2]。 - **LFU (Least Frequently Used)**:删除最不常使用的键。此策略基于访问频率,认为访问频率低的键在未来也不太可能被频繁使用[^3]。 - **TTL (Time To Live)**:删除剩余生存时间最短的键。此策略适用于那些设置了较短生存时间的键[^4]。 - **Random**:随机删除键。此策略简单粗暴,但可能导致重要数据被删除[^5]。 #### 使用场景 不同的淘汰策略适用于不同的使用场景: - **LRU**:适合缓存场景,尤其是当数据访问模式具有明显的局部性时,例如网页缓存、API 响应缓存等[^2]。 - **LFU**:适合需要长期保存某些数据的场景,例如分布式系统中的元数据存储,其中某些数据可能长时间未被访问但仍然重要[^3]。 - **TTL**:适合短期任务或临时数据存储,例如会话管理、验证码存储等[^4]。 - **Random**:适合对数据丢失敏感度较低的场景,例如日志存储、统计分析等[^5]。 #### 示例代码 以下是一个简单的 Redis 配置示例,展示如何设置淘汰策略: ```bash # 设置 Redis 的最大内存限制 maxmemory 100mb # 设置淘汰策略为 LRU maxmemory-policy allkeys-lru ``` #### 注意事项 - 在生产环境中,建议根据实际需求选择合适的淘汰策略,并监控 Redis 的内存使用情况。 - 对于关键数据,避免使用容易被淘汰的策略,如 Random 或 TTL。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值