cat case/PM-2013-FS01.md

MongoDB 内存耗尽致 17 小时宕机

P1 · 主站宕机约 17h,跨两日

摘要

2013 年,Foursquare 的 MongoDB 工作集超过可用 RAM,触发频繁磁盘换页(thrashing)。其查询访问模式局部性差,数据难以留在内存,数据库响应急剧恶化直至 OOM 崩溃,主站宕机约 17 小时,跨越两个自然日。

# 数据长大了,内存装不下,磁盘跟不上——经典容量墙。

时间线

故障前数据集增长逼近内存上限
某日工作集超 RAM,换页剧增,延迟飙升
随后OOM 崩溃,服务不可用
~17h 后完成数据分片 / 扩容恢复

根因

Foursquare 当时采用单分片 MongoDB,所有热数据依赖一台机器的物理内存。随着用户与签到数据增长,数据库的「工作集」(频繁访问的数据页 + 索引)逐渐超过可用 RAM,MongoDB 被迫频繁从磁盘换页(page fault / thrashing),查询延迟急剧恶化;而业务的查询访问模式局部性差,数据难以驻留内存缓存,换页进一步加剧,最终触发 OOM 崩溃,主站不可用。

  • 单分片架构无水平扩展能力,工作集上限被单机内存锁死。
  • 内存是硬约束:工作集超 RAM 必触发换页 → 延迟雪崩 → OOM。
  • 查询访问模式局部性差,缓存命中率低,加剧换页。
  • 容量规划未随数据增长提前扩容 / 分片,监控也未对内存使用设阈值告警。

放大因素

单分片架构无水平扩展;读放大 + 换页形成正反馈;恢复需长时间数据平衡(分片 / 迁移),拖长 MTTR。

缓解措施

  • 提前分片,保证工作集可放入内存。
  • 容量监控与预测,设定内存使用阈值告警。
  • 优化查询局部性 / 加缓存层。

经验教训

内存是数据库的硬约束,工作集超 RAM 必崩;容量规划必须前置,不能等宕机才分片。

检查清单

  • 确认工作集 vs 可用内存
  • 检查换页 / 磁盘 IO 是否异常
  • 验证分片与扩容策略
  • 复盘容量监控阈值
  • 评估查询局部性优化空间