一次Redis缓存引发的生产事故排查与反思
上周生产环境经历了一次系统”惊魂”——抢购期间系统严重卡顿,带宽瞬间被打满,但各节点的 CPU 和内存指标却一切正常。
现象:带宽打满,资源正常
活动开始的瞬间,监控系统告警频发:
- 系统响应超时,用户无法下单
- 带宽占用率瞬间跑满
- 奇怪的是:CPU、内存、磁盘 IO 全部正常
第一反应是遭到了 DDoS 攻击,但阿里云控制台并没有触发任何攻击警报。
排查:一步一步缩小范围
第一步:排除外部攻击
登录阿里云安全控制台查了一圈,没有发现异常流量特征。排除 DDoS。
第二步:内部流量分析
在服务器上用 iftop、nethogs 等工具查看各进程的网络流量,发现流量最大的竟然是 Redis 服务。
第三步:追根溯源
深入检查 Redis 配置,发现了一个致命问题——
Redis 被配置成了公网地址,而非阿里云内网地址。
这意味着所有 Redis 通信都要走公网链路,带宽限制极低。而最近为了”提高系统可用性”,大范围引入了缓存策略,但实现方式非常粗暴——直接把整个对象塞进 Redis,没有任何优化。
用 Redis GUI 工具看了一下,单个商品列表的缓存体积竟然达到了 1.4MB。
根因分析
- 网络配置错误:Redis 公网暴露 + 低带宽限制 = 性能瓶颈
- 缓存策略粗暴:全量缓存、无差别存储、字段冗余
- 缺乏压力测试:上述问题在上线前均未暴露
解决措施
短期:修复网络配置
将 Redis 地址更换为阿里云内网地址,立即缓解了公网带宽压力。
中期:优化缓存粒度
对缓存进行了精细化改造:
| 优化项 | 优化前 | 优化后 |
|---|---|---|
| 单个列表缓存大小 | 1.4 MB | ~30 KB |
| 缓存内容 | 全量字段 | 仅必要字段 |
| 缓存策略 | 全量静态缓存 | 用户访问驱动的条件缓存 |
长期:建立压测机制
这次事故最深刻的教训是——如果提前做过压力测试,网络配置问题和缓存策略的问题大概率能在上线前发现。
反思
缓存是把双刃剑。用得好是加速器,用得不好就是定时炸弹。
几个关键感悟:
- 内网通信优先:云服务之间的通信务必使用内网地址,不仅更安全,也避免不必要的性能损耗
- 缓存要精打细算:不是所有数据都适合缓存,缓存也要考虑体积和时效性
- 压测是上线前的必修课:别等到用户量上来才发现问题
希望这个事故复盘对你有帮助,欢迎留言交流。
附:Redis 缓存优化建议清单
- 检查 Redis 地址配置,确保使用内网地址
- 评估每个 Key 的缓存价值,拒绝”塞进去就不管”的心态
- 限制单 Key 的最大体积(建议 < 100KB)
- 对缓存数据设置合理的 TTL
- 上线前务必进行压力测试,模拟真实流量场景