Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

数据库为什么不适合跑在容器

这是一个非常“值钱”的问题。

不是“能不能”,而是 “为什么在工程上不适合”。

用 硬件 / NUMA / cgroups / Linux 内核 / 容器模型 梳理。

一、先给结论(避免误解)

数据库不是“不能”跑在容器里,而是:在大多数生产场景下,容器的抽象层与数据库的性能模型是“反向的”。

换句话说:

  • 数据库追求确定性
  • 容器追求弹性与共享

两者天生冲突。

二、数据库真正依赖的是什么?

数据库(MySQL / PostgreSQL / Oracle / Redis)真正吃的不是“CPU 核数”,而是:

  1. 内存确定性
  2. IO 延迟稳定性
  3. NUMA 本地性
  4. fsync 语义可靠
  5. 调度可预期

三、核心冲突点一:内存(致命)

1️⃣ 数据库的内存模型

以 MySQL / PostgreSQL 为例:

  • Buffer Pool / Shared Buffers
  • 长时间常驻
  • 自己管理淘汰

📌 数据库不希望内核插手

2️⃣ 容器的内存模型(cgroups)

memory.max
memory.high

问题来了:

行为 后果
memory.high 频繁回收
memory.max 直接 OOM kill
swap 延迟爆炸

数据库最怕:

  • 被 OOM kill
  • 被强制回收 page cache

📌 数据库宁可慢,也不接受“突然死”

3️⃣ 真实事故模式

容器里 MySQL 看似稳定,高峰期突然被 kill,主从全挂。

四、核心冲突点二:NUMA(性能杀手)

1️⃣ 数据库极度依赖 NUMA 本地性

  • CPU ↔ 内存
  • 锁、latch、buffer

裸机:

numactl --cpunodebind=0 --membind=0 mysqld

2️⃣ 容器对 NUMA 的默认态度

  • 默认 不感知 NUMA
  • cgroups 不自动绑 mems
  • K8S NUMA 需要高级配置

📌 跨 NUMA = 延迟抖动 + QPS 不稳定

3️⃣ VM 反而更安全

  • vNUMA
  • Guest OS 感知 NUMA
  • 数据库可控

五、核心冲突点三:IO 路径太长

1️⃣ 裸机 IO

DB -> FS -> Block -> Disk

2️⃣ 容器 IO

DB -> overlay2 -> VFS -> Block -> Disk

overlay2 的问题:

  • copy-on-write
  • metadata 放大
  • fsync 成本更高

📌 数据库是 fsync 密集型应用

3️⃣ 即使用 volume,也有问题

  • shared storage
  • IO 抢占
  • noisy neighbor

六、核心冲突点四:调度不可控

1️⃣ 数据库调度特性

  • 长时间运行
  • cache 热
  • 锁敏感

2️⃣ 容器调度模型

  • CPU quota
  • CFS 调度
  • throttling
cpu.max=100000 100000

📌 throttling = TPS 抖动

七、核心冲突点五:运维语义冲突

1️⃣ 容器哲学

  • 无状态
  • 可重建
  • 快速销毁

2️⃣ 数据库现实

  • 强状态
  • 数据一致性
  • 故障恢复优先

📌 数据库重启 ≠ 应用重启

八、为什么大家“感觉能跑”?

因为:

场景 看起来没问题
测试环境 压力不够
小规模 NUMA 未显现
SSD 掩盖 IO 问题
单节点 没有争抢

📌 一上生产就暴雷

九、那为什么 Redis 常被放进容器?

因为:

特性 Redis
内存模型 简单
IO
NUMA 敏感
恢复

📌 不是所有“数据库”一样

十、那什么时候“可以”放容器?

勉强可接受的条件

  • 专用节点
  • 独占 CPU / 内存
  • 禁用 swap
  • HugePages
  • local PV
  • static pod

📌 此时已经 不像容器,更像轻量 VM

十一、推荐架构选择(经验结论)

场景 推荐
核心 OLTP 裸机
金融 / 交易 裸机
云数据库 VM
辅助库 / 测试 容器
Redis / Kafka 视规模

十二、总结

容器的本质是“共享”,而数据库的本质是“独占”。

只要记住这句话,在架构评审里就不会输。