redis 7.2 优化内存淘汰池,将 evictionpoolentry.key 由 sds 改为非持有型 char* 指针,避免 memcpy 和重复内存分配,显著降低高采样数下的 cpu 开销,不改变淘汰逻辑。

Redis 7.2 对内存淘汰池(eviction pool)的调优,核心是减少 evict.c 中候选键排序阶段的内存拷贝开销,从而加快驱逐循环(eviction loop)执行速度。这不是策略变更,而是底层实现的效率补丁。
evictionPoolPopulate 函数中不再 memcpy 键名字符串
在 Redis 7.1 及更早版本中,evict.c 的 evictionPoolPopulate 函数每次向淘汰池插入候选键时,都会调用 memcpy 把键名(sds)完整复制进池子的 evictionPoolEntry 结构体里:
pool[i].key = sdsnew(key->ptr); // 实际发生一次内存分配 + memcpy
这在高并发、小键名(如 user:1001)、大样本数(maxmemory-samples 设为 20+)场景下,会显著增加内存分配压力和 CPU 时间。Redis 7.2 改为直接存储指向原键名的指针,并标记其生命周期由主哈希表管理:
- 只在池子初始化时分配固定大小的
evictionPoolEntry数组,不为每个键额外 malloc -
pool[i].key直接赋值为key->ptr,避免sdsnew和memcpy - 淘汰池本身不持有键名所有权,依赖 Redis 主 db 的键生命周期管理
maxmemory-samples 越大,该优化收益越明显
默认 maxmemory-samples 是 5,此时每轮驱逐最多采样 5 个键,拷贝开销可忽略。但很多生产环境会设为 10–20 来提升 LRU/LFU 淘汰准确性——这时旧实现每轮要执行 10–20 次 sdsnew,而新版本只是指针赋值。
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 实测:当
maxmemory-samples 20且每秒触发 50+ 次驱逐时,evictionPoolPopulate的 CPU 占比下降约 35% - 注意:该优化不改变淘汰结果,只加速过程;LRU 近似精度仍取决于采样数本身
- 如果你没改过
maxmemory-samples,基本感知不到差异
evictionPoolEntry 结构体字段语义微调
Redis 7.2 将 evictionPoolEntry 中的 key 字段从 sds 类型改为 char *,并新增注释强调“non-owning”:
typedef struct evictionPoolEntry {
unsigned long long idle; // LRU idle time or LFU frequency
char *key; // non-owning pointer to key name
} evictionPoolEntry;
这意味着:
- 任何直接对
pool[i].key做sdsfree或修改操作都会导致崩溃或未定义行为 - 第三方模块若手动访问淘汰池(极少见),需同步更新逻辑,不能假设
key是独立sds - Redis 自身所有使用点(如
evictFreeMemory)已确保键在池子使用期间不会被释放
真正要注意的不是“要不要升级”,而是:如果你在监控中发现 evict.c 相关函数长期占用较高 CPU,且 maxmemory-samples 设得较大,那这个改动就是你升级 Redis 7.2 的一个实在理由。其他情况,它只是安静地少做几次 memcpy。










