上周生产环境经历了一次系统”惊魂”——抢购期间系统严重卡顿,带宽瞬间被打满,但各节点的 CPU 和内存指标却一切正常。

现象:带宽打满,资源正常

活动开始的瞬间,监控系统告警频发:

  • 系统响应超时,用户无法下单
  • 带宽占用率瞬间跑满
  • 奇怪的是:CPU、内存、磁盘 IO 全部正常

第一反应是遭到了 DDoS 攻击,但阿里云控制台并没有触发任何攻击警报。

排查:一步一步缩小范围

第一步:排除外部攻击

登录阿里云安全控制台查了一圈,没有发现异常流量特征。排除 DDoS。

第二步:内部流量分析

在服务器上用 iftop、nethogs 等工具查看各进程的网络流量,发现流量最大的竟然是 Redis 服务。

第三步:追根溯源

深入检查 Redis 配置,发现了一个致命问题——

Redis 被配置成了公网地址,而非阿里云内网地址。

这意味着所有 Redis 通信都要走公网链路,带宽限制极低。而最近为了”提高系统可用性”,大范围引入了缓存策略,但实现方式非常粗暴——直接把整个对象塞进 Redis,没有任何优化。

用 Redis GUI 工具看了一下,单个商品列表的缓存体积竟然达到了 1.4MB。

根因分析

  1. 网络配置错误:Redis 公网暴露 + 低带宽限制 = 性能瓶颈
  2. 缓存策略粗暴:全量缓存、无差别存储、字段冗余
  3. 缺乏压力测试:上述问题在上线前均未暴露

解决措施

短期:修复网络配置

将 Redis 地址更换为阿里云内网地址,立即缓解了公网带宽压力。

中期:优化缓存粒度

对缓存进行了精细化改造:

优化项 优化前 优化后
单个列表缓存大小 1.4 MB ~30 KB
缓存内容 全量字段 仅必要字段
缓存策略 全量静态缓存 用户访问驱动的条件缓存

长期:建立压测机制

这次事故最深刻的教训是——如果提前做过压力测试,网络配置问题和缓存策略的问题大概率能在上线前发现。

反思

缓存是把双刃剑。用得好是加速器,用得不好就是定时炸弹。

几个关键感悟:

  1. 内网通信优先:云服务之间的通信务必使用内网地址,不仅更安全,也避免不必要的性能损耗
  2. 缓存要精打细算:不是所有数据都适合缓存,缓存也要考虑体积和时效性
  3. 压测是上线前的必修课:别等到用户量上来才发现问题

希望这个事故复盘对你有帮助,欢迎留言交流。

附:Redis 缓存优化建议清单

  • 检查 Redis 地址配置,确保使用内网地址
  • 评估每个 Key 的缓存价值,拒绝”塞进去就不管”的心态
  • 限制单 Key 的最大体积(建议 < 100KB)
  • 对缓存数据设置合理的 TTL
  • 上线前务必进行压力测试,模拟真实流量场景