内存淘汰策略
约 852 字大约 3 分钟
2025-09-01
Redis 的内存淘汰策略(Eviction Policies)用于在内存达到 maxmemory 配置的上限时,决定如何释放内存以存储新的数据。
策略分类
内存淘汰策略主要分为两类:针对设置了过期时间(TTL)的 Key 进行淘汰,以及针对所有 Key 进行淘汰。
只针对设置了过期时间(TTL)的 Key 进行淘汰:
volatile-lru(Least Recently Used):从所有设置了过期时间的 Key 中,淘汰最近最少使用的 Key。volatile-fgu(Least Frequently Used):从所有设置了过期时间的 Key 中,淘汰访问频率最低的 Key。volatile-random:从所有设置了过期时间的 Key 中,随机选择一个 Key 进行删除。volatile-ttl:从所有设置了过期时间的 Key 中,选择剩余生存时间(Time To Live)最短的 Key 进行删除。
针对所有 Key 进行淘汰:
allkeys-lru(Least Recently Used):从所有 Key 中,淘汰最近最少使用的 Key。判断依据是 Key 的最后一次访问时间。allkeys-lfu(Least Frequently Used):从所有 Key 中,淘汰访问频率最低的 Key。判断依据是 Key 的访问次数统计。allkeys-random: 从所有 Key 中,随机选择一个 Key 进行删除。
3. 不淘汰策略:
noeviction:当内存使用达到maxmemory上限时,不淘汰任何 Key。对于写操作(如SET、LPUSH等),Redis 会直接返回错误信息。读操作(如GET)仍然可用。
策略选择建议
选择合适的内存淘汰策略取决于具体的应用场景和数据特性。
- 纯缓存场景:如果 Redis 主要用作缓存,且所有数据都可以被淘汰,建议使用
allkeys-lru或allkeys-lfu。这可以最大化缓存命中率,并避免因内存写满导致的服务不可用。allkeys-lru更侧重于新数据的接收,而allkeys-fgu更侧重于热点数据的保留。 - 混合数据场景(部分数据需要长期保存):如果 Redis 中存在一部分数据是永久性的(未设置过期时间),而另一部分数据是可淘汰的(设置了过期时间),则应使用
volatile-lru或volatile-lfu。这样可以确保关键的、未设置过期时间的数据不会被误删。 - 严格数据保护场景:如果对数据丢失有非常严格的要求,即使内存写满也绝不允许自动淘汰任何数据,则应使用
noeviction策略。但在此策略下,务必配合完善的内存监控和扩容机制,以避免因内存不足导致写入失败。
内存淘汰流程
当客户端执行写入命令时,Redis 会触发内存检查和淘汰流程:
- 触发内存检查:客户端执行写入命令(如
SET、LPUSH)时,Redis 检查当前内存使用量是否超出maxmemory(配置文件定义的值)。 - 根据策略选择待淘汰键:如果内存超出限制,Redis 会根据配置的内存淘汰策略,从数据集中选择一个或多个 Key 进行淘汰。
- 删除键并触发事件:被选中的 Key 将从数据集中删除。同时,Redis 会触发相关的事件通知,例如通过
Keyspace Notifications发布evicted事件,通知客户端该 Key 已被淘汰。