redis内存淘汰策略按key-value对整体删除,不拆分或截断value;淘汰时原子性移除整个key及其关联value,无论类型或大小,底层等价于del命令。

Redis内存淘汰策略是按 key 删除,不是按值(value)拆分或截断。
淘汰动作发生在整个 key-value 对层面
Redis 的淘汰机制没有“只删 value 一部分”或“压缩 value”的能力。一旦某个 key 被选中淘汰,整个键及其关联的 value(无论大小、类型、是否为哈希/列表/字符串)都会被原子性地从数据库中移除。
-
DEL是底层实际执行的操作,等价于手动调用DEL key - 即使
value占用几 MB(比如一个大字符串或 zset),它也会被整块释放,不会做流式清理或碎片回收 - 淘汰不关心
value内部结构——hash的 field、list的元素、zset的 score 都随key一并消失
为什么不能按 value 拆分淘汰?
Redis 的内存管理基于对象(redisObject)粒度,每个 key 对应一个顶层对象,其 value 是另一个独立分配的对象指针。这种设计决定了淘汰只能作用于完整对象引用,无法安全地对 value 做部分释放:
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 内部数据结构(如
ziplist、quicklist、dict)不具备“部分释放”接口 - 并发访问下,部分删除
value会破坏结构一致性,引发读取崩溃或数据错乱 - LRU/LFU 统计的是
key级别的访问时间或频次,不是value子项的
容易误判的场景:大 value 导致淘汰“不生效”
你可能观察到设置了 maxmemory 和 allkeys-lru,但内存迟迟不降——这不是淘汰没发生,而是单个 key 的 value 太大,淘汰一个就释放大量内存;但 Redis 每次只淘汰固定数量(默认 maxmemory-samples = 5)的候选 key,若这些样本里恰好没选中大 value 的 key,就会显得“卡住”:
- 检查
INFO memory中的mem_fragmentation_ratio和used_memory_peak - 用
MEMORY USAGE key找出真正吃内存的key - 增大
maxmemory-samples(比如设为 10 或 20)可提高命中大 valuekey的概率,但会略微增加 CPU 开销
真正影响淘汰效率的,从来不是 value 怎么删,而是你有没有让 Redis 知道哪些 key 可以被删——比如该设 EXPIRE 的没设,就等于把所有 key 都塞进 allkeys-* 的候选池,而其中大量是不该被淘汰的长期缓存。










