1. 课程导入

Redis 以内存为核心存储介质,这既是它高性能的根源,也是它最容易被忽视的风险点。很多团队在业务初期把 Redis 当作"无限大的缓存",直到某天凌晨收到 OOM(Out Of Memory)告警、写入被拒绝、主从复制中断,才意识到内存是一种需要被主动管理的稀缺资源。本课程要解决的,正是"如何让 Redis 的内存始终处于可控、可观测、可预测的状态"这一工程问题。

一、学习目标:从"会用"到"会治理"

本课程不满足于讲清几个配置项的含义,而是希望建立一套完整的容量治理能力。学完之后,你应当能够独立完成以下几件事:

  • 算得清:能够根据业务数据规模、键值结构、过期策略,估算 Redis 实例的内存占用,而不是靠"先上线再看"。
  • 看得见:能够读懂 INFO memory、MEMORY USAGE、MEMORY STATS 等命令的输出,区分 used_memory、used_memory_rss、mem_fragmentation_ratio 等指标的真实含义。
  • 控得住:能够合理设置 maxmemory 与 maxmemory-policy,在缓存命中率与写入可用性之间做出有依据的取舍。
  • 查得明:当内存异常增长时,能够通过 bigkey 扫描、内存采样、键空间分析定位到具体的数据来源。
  • 防得早:能够设计容量水位、监控告警与扩容预案,把内存问题从"故障"降级为"日常运维事件"。

二、核心问题域:内存治理到底在治理什么

Redis 的内存问题从来不是单一维度的。它至少涉及四个相互纠缠的问题域,理解它们的边界,才能避免"头痛医头"。

第一是数据本身的内存开销。一个看似简单的 SET user:1001 "tom",实际占用的内存远不止 3 个字节的字符串。Redis 需要为每个键维护 dictEntry、redisObject、SDS 头、哈希表桶位等结构,一个短字符串键值对的真实开销可能达到 60~100 字节。当键数量达到千万级时,这部分"看不见的元数据"往往比数据本身还大。

第二是内存淘汰与过期策略。设置了 maxmemory 并不等于内存就不会满,关键在于淘汰策略是否与业务匹配。allkeys-lru 会无差别淘汰,volatile-ttl 只淘汰设置了过期时间的键,noeviction 则直接拒绝写入。选错策略的后果,可能是热点数据被误删,也可能是写入全面失败。

第三是内存碎片与分配器行为。Redis 默认使用 jemalloc,长期运行、频繁增删后会产生内存碎片,表现为 used_memory_rss 远大于 used_memory。碎片率过高时,即使逻辑内存还有余量,物理内存也可能已经吃紧。

第四是持久化与复制带来的额外内存。RDB 的 fork 会触发写时复制(COW),AOF 重写同样需要 fork 子进程,主从全量同步时主节点要生成 RDB 并缓冲增量命令。这些操作在内存紧张时可能成为压垮实例的最后一根稻草。

Redis 内存治理的四个问题域与治理闭环 ① 数据内存开销 键值结构 / 元数据 SDS / dictEntry bigkey 与键数量 ② 淘汰与过期 maxmemory 水位 8 种淘汰策略 TTL 与惰性删除 ③ 碎片与分配器 jemalloc 行为 碎片率指标 碎片整理开关 ④ 持久化与复制 fork 与 COW AOF 重写缓冲 主从全量同步 治理闭环:容量估算 → 指标观测 → 策略配置 → 异常定位 → 水位告警 → 扩容/优化 每一环都对应可执行的命令、参数与判断依据 实战路线图(本课程推进顺序) 基础认知 内存模型 / 指标 容量估算 键值开销 / 规模测算 策略配置 淘汰 / 过期 / 碎片 定位与告警 bigkey / 水位监控 扩容 预案 目标:让内存从"事后救火"变为"事前可控、事中可观测、事后可复盘"

三、整体知识框架:三条主线

本课程的内容围绕三条主线展开,它们分别回答"占多少""怎么控""出问题怎么办"。

主线一:内存构成与度量。这条线解决"内存到底花在哪"。你需要理解 Redis 的内存由数据内存、进程开销、缓冲内存、内存碎片四部分组成。数据内存是键值本身,进程开销包括代码段、共享库、客户端连接缓冲,缓冲内存涵盖复制积压缓冲区、AOF 缓冲区、客户端输出缓冲区,碎片则是分配器留下的空洞。只有把 INFO memory 中的 used_memory、used_memory_overhead、used_memory_dataset、used_memory_rss 对应到这四部分,才能判断问题出在哪一层。

主线二:容量规划与策略配置。这条线解决"如何提前算、如何设阈值"。容量规划的核心是估算单键开销乘以键数量,再叠加副本、持久化和安全余量。策略配置的核心是 maxmemory 与 maxmemory-policy 的组合选择,以及 maxmemory-samples 对淘汰精度的影响。这里没有万能答案,只有与业务读写模式匹配的取舍。

主线三:监控、定位与应急。这条线解决"线上出问题怎么快速收敛"。包括如何用 redis-cli --bigkeys 和 MEMORY USAGE 定位大键,如何用 SLOWLOG 和延迟监控发现内存操作引发的抖动,如何设置内存水位告警,以及扩容、缩容、数据迁移的标准动作。

四、实战路线图:从认知到落地

课程按"基础认知 → 容量估算 → 策略配置 → 定位与告警 → 扩容预案"的顺序推进,每一阶段都配有可执行的命令与判断依据。下面给出一份贯穿全课程的容量治理检查清单,你可以把它当作学习过程中的对照表,也可以直接用于实际项目的自查。

治理环节 关键动作 核心命令 / 参数 判断依据(示例阈值)
内存观测 采集内存指标,区分逻辑内存与物理内存 INFO memory used_memory_rss / used_memory 比值持续 > 1.5 需关注碎片
容量估算 抽样测量单键开销,乘以预估键数量 MEMORY USAGE key 预留 30% 以上安全余量,避免逼近 maxmemory
淘汰策略 按业务容忍度选择淘汰算法 maxmemory-policy 纯缓存可用 allkeys-lru;有持久数据用 volatile-*
大键排查 定期扫描 bigkey,拆分或异步删除 redis-cli --bigkeys 单键 > 10KB 或元素数 > 5000 建议拆分
水位告警 设置内存使用率与碎片率双阈值告警 监控系统 + INFO 使用率 > 75% 预警,> 85% 严重
扩容预案 明确扩容触发条件与数据迁移方式 集群扩槽 / 主从切换 连续 3 个采集周期超过严重阈值即触发
学习建议:每学完一个环节,就在自己的测试实例上执行一次对应命令,记录真实输出。内存治理是一门"看数据说话"的手艺,只看文档不摸实例,很难建立对数量级的直觉。
常见误区:把 maxmemory 设置为物理内存的 100%。Redis 在 fork、AOF 重写、主从同步时会产生额外内存开销,若不留余量,极易触发系统 OOM Killer 导致实例被杀。生产环境通常建议 maxmemory 不超过物理内存的 70%~75%。

接下来的章节会逐一展开这些环节。你现在需要建立的,是一个整体判断:Redis 内存治理不是某一个配置项的问题,而是"度量—估算—配置—监控—应急"的完整链条。链条上任何一环缺失,都会让内存从可控资源变成随机故障源。