used_memory 不等于真实可淘汰内存,因其仅统计 redis 分配器(如 jemalloc)已申请字节数,不包含内存碎片、客户端缓冲区(受独立限流)、进程开销等;jemalloc 的 retain 行为使释放内存不立即归还 os,导致 used_memory_rss 持续偏高。

Redis 7.0 无法靠 used_memory 直接反映“实际可淘汰数据量”,必须结合 jemalloc 分配器行为和 maxmemory-clients 等新机制交叉验证。
为什么 INFO memory 的 used_memory 不等于真实可淘汰内存?
这个值只是 Redis 分配器(如 jemalloc)报告的“已申请”字节数,不等于操作系统实际归还的物理内存。尤其在以下情况偏差明显:
-
jemalloc默认启用retain行为:释放的内存块不会立即归还 OS,而是保留在 arena 中供后续复用,导致used_memory_rss居高不下 - 客户端缓冲区(输入/输出)被计入
used_memory,但它们受client-query-buffer-limit和client-output-buffer-limit单独控制,不参与 LRU 淘汰 -
maxmemory-clients限制的是所有客户端缓冲区总和,但它在getClientEvictionLimit()中被硬性下限设为128KB,哪怕你配了-1也会被拉回
怎样用 MEMORY STATS 看清 jemalloc 真实分配状态?
MEMORY STATS 是 Redis 4.0+ 提供的底层视图,比 INFO memory 更贴近 jemalloc 实际行为。重点关注这些字段:
-
allocator_allocated:jemalloc 当前认为“已分配给 Redis 使用”的内存(接近used_memory) -
allocator_active:jemalloc 当前向 OS 申请并处于活跃状态的内存(更接近used_memory_rss) -
allocator_resident:OS 实际映射给该进程的物理内存页(used_memory_rss的源头) -
allocator_fragmentation_ratio:由allocator_active / allocator_allocated计算得出 —— 这才是 jemalloc 内部碎片率,和mem_fragmentation_ratio含义不同但高度相关
当 allocator_active 明显大于 allocator_allocated,说明 jemalloc 正在 hold 大量未释放页;此时即使 used_memory 已触发淘汰,OS 级别内存压力仍可能持续。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
maxmemory-clients 怎样影响淘汰触发的实际阈值?
Redis 7.0 引入的 maxmemory-clients 不是“开关”,而是会动态修改淘汰入口函数 evictIfNeeded() 的判断逻辑。关键点:
- 它只约束客户端缓冲区总量,**不约束数据键本身的内存**;所以即使
maxmemory-clients触发限制,evictIfNeeded()仍按maxmemory+maxmemory-clients的总和做全局判断 -
CONFIG SET maxmemory-clients 512mb后,Redis 会调用applyClientMaxMemoryUsage()并触发initServerClientMemUsageBuckets()—— 这个初始化步骤一旦失败(比如内存不足),会导致后续客户端连接直接被拒绝,而非优雅降级 - 若同时设置了
maxmemory-clients -30(即 30% ofmaxmemory),而maxmemory本身是 0(无限制),该配置会被静默忽略,getClientEvictionLimit()返回 0
真正能反映“此刻是否该淘汰”的指标只有两个
不要依赖单个数字,要盯住组合信号:
-
used_memory > (maxmemory - getClientEvictionLimit()):这是 Redis 内部淘汰决策的真实分界线,可通过redis-cli info memory | grep -E "(used_memory|maxmemory)"和redis-cli config get maxmemory-clients手动估算 -
mem_fragmentation_ratio > 2.0且allocator_fragmentation_ratio > 1.8:说明 jemalloc 层面已严重碎片化,即使used_memory未超限,也可能因无法找到连续页而触发 OOM
这两个条件任意一个成立,就表示当前内存状态已脱离“理论容量”控制,必须检查客户端连接数、大 key 分布或考虑重启实例释放 jemalloc arena。










