登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  Redis

淘汰策略 怎样选择 volatile 或 allkeys

来源:17golang原创

时间:2026-10-25 11:19:35 464浏览 收藏

Redis 淘汰策略先选候选范围,再选候选中的排序方式:allkeys-* 把所有键纳入范围,适合整实例都可丢失并重建的缓存;volatile-* 只从带过期时间的键中选择,适合有明确 TTL 分类约定的场景。volatile 并不等于“等过期后才删”,带 TTL 的键仍可能在到期前被内存淘汰。

官方地址:https://redis.io/docs/latest/develop/reference/eviction/。先用下面的只读命令确认当前配置,再按资产、风险、控制和观测记录作选择。本文命令与配置均为未执行的原创示例,未对任何 Redis 实例修改策略或做容量实验。

# 只读获取当前容量阈值和淘汰策略,逐项查询兼容更多客户端环境。
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy

# 查看实例内存、命中及淘汰累计统计,不读取业务值。
redis-cli INFO memory
redis-cli INFO stats
redis-cli INFO keyspace

先界定资产:哪些键丢失后能重建

把键按“丢失后如何恢复”分类,比按“是否设置 TTL”分类更可靠。商品详情缓存通常有数据库来源;任务进度、去重记录、限流状态或会话可能承担业务约束。它们即使有 TTL,也不一定允许提前消失。先列出重建来源、允许丢失窗口和恢复成本,再决定是否让它们成为淘汰候选。

如果某实例同时保存可重建缓存和不能随意丢失的状态,优先考虑实例隔离。不同逻辑 DB 或键名前缀不构成独立内存淘汰边界。给重要键换一个前缀,也不会使 allkeys 自动忽略它。

找出风险路径:TTL 约定失效会怎样

以混合实例为例:团队规定可淘汰缓存必须有 TTL,不可提前丢失的键不设置 TTL。如果缓存写入漏了过期参数,它就退出 volatile 的候选集合,却继续占内存。反过来,若重要状态被误设 TTL,它会进入候选范围,可能提前消失。

即使 TTL 约定全部正确,非 TTL 数据持续增长仍会挤压可淘汰空间。当没有足够候选可以释放容量时,volatile 无法保证继续接收写入。因此它是候选过滤规则,不能替代配额、容量规划或业务隔离。

带TTL和不带TTL键在两类淘汰候选范围中的关系
图1:候选范围结构说明图。volatile 范围只关联带 TTL 键,allkeys 范围包含全部键;这描述策略范围,不表示具体淘汰次序。

按候选范围选择 volatile 或 allkeys

业务条件优先判断需要接受的后果
整实例均为可重建缓存考虑 allkeys-lru 或 allkeys-lfu无 TTL 键也可能被淘汰
TTL 可靠标记可丢失缓存可评估 volatile 范围候选不足时可能拒绝增加内存的命令
有 TTL 的键也不能提前丢失volatile 不符合保护要求应另设隔离与容量方案
任何键均不允许自动淘汰评估 noeviction 及限流扩容容量不足会体现在写入错误中

前缀选好之后才比较 LRU、LFU 或 TTL 排序。LRU 倾向淘汰近期较少访问的键,LFU 根据访问频率估计热度;它们并不提供“重要业务键永不删除”的语义。volatile-ttl 关注剩余 TTL 较短的候选,不是对所有键自动补 TTL。

举例说,给纯缓存实例选 allkeys-lru,可以避免某个漏设 TTL 的缓存键永久退出候选范围;但把同一配置直接复制到保存唯一任务状态的实例,会改变其丢失风险。策略不是脱离数据用途的统一性能开关。

把策略、容量与权限控制一起配置

# 独立测试实例的 redis.conf 示例,512mb 仅为示意容量。
maxmemory 512mb

# 仅当实例所有键均可丢失并重建时,才使用全键候选范围。
maxmemory-policy allkeys-lru

上面是纯缓存的配置示意,不是通用内存建议。maxmemory 应根据部署限制、复制与持久化开销以及业务容量设定,不能简单填满容器可用内存。进程总内存与用于淘汰判断的内存口径也不完全相同。

# 另一种独立测试配置;与上一方案二选一,不是追加叠加。
maxmemory 512mb

# 仅有设置过期时间的键参与候选选择,非TTL键仍会占用容量。
maxmemory-policy volatile-lru

两个方案按实例用途二选一。通过配置管理或平台控制台发布时,保留变更前策略、容量、应用错误基线与回退方案。应用账号负责正常读写,不应因需要排查缓存而取得随意修改 CONFIG 的权限;托管平台可能提供不同的参数入口,应遵守对应产品方式。

策略配置、容量阈值、权限与业务恢复边界结构
图2:控制边界说明图。候选范围与容量阈值共同约束淘汰,业务重建能力和运维权限属于独立责任,不能由一个策略名替代。

策略回退也不会复原已经被淘汰的键。发生误淘汰后,需要按业务重建来源恢复,而不是只把配置改回去。对无法可靠重建的数据,应在上线前排除依赖自动淘汰回退的设计。

用观测记录判断淘汰是否伤到业务

记录 INFO stats 中的 evicted_keys、expired_keys、keyspace_hits 和 keyspace_misses。它们多为累计计数,应按采样窗口计算差值,并处理实例重启导致计数重置。自然过期与内存淘汰需要分别解释,不能只把所有缺失键归因于策略。

INFO keyspace 的键数与带过期键数量可帮助发现 TTL 分布变化,但它描述数量,不说明这些键各自占用了多少空间。volatile 候选数量很多,也可能不足以释放某个大对象写入所需的容量。

观测最终要回到业务:缓存回源是否压垮数据库,关键状态缺失是否导致重复执行,拒写错误是否被应用记录并正确处理。命中率不是唯一指标;稳定的错误处理与重建速度同样决定方案是否可用。

上线前的选择清单与常见疑问

明确列出候选键可丢失性、TTL 写入约定、最大对象、非 TTL 数据增长趋势和应用拒写处理方式。然后在独立环境以代表性负载观察策略效果。本文只提供选择方法,没有声称任何配置已通过实测。

所有键都设置了 TTL,两种范围还有区别吗?

在这一时刻候选集合可能接近,但以后漏设 TTL 或移除 TTL 会让范围分化。选择依据应覆盖写入约定与变更,而不是只看一次快照。

volatile 能保证不丢未过期键吗?

不能。TTL 是候选资格,未到期也可以被淘汰;需要保留到期限的业务状态不能靠 volatile 获得保证。

noeviction 就能保证数据安全吗?

它只改变内存压力下的自动淘汰行为,不能替代持久化、备份、复制和应用错误处理。容量不足时仍需应对写入失败。

参考资料:内存淘汰 https://redis.io/docs/latest/develop/reference/eviction/;配置读取 https://redis.io/docs/latest/commands/config-get/;统计口径 https://redis.io/docs/latest/commands/info/。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>