"帮我们规划一套存储,大概 500 TB。"这是存储工程师最常收到、也最危险的需求。500 TB 是裸容量还是可用容量?三副本还是纠删码?坏一台机器以后还剩多少?三年后要多少?IOPS 和延迟有没有要求?这些问题不问清楚,结果往往是两种之一:上线半年就触发 nearfull 被迫紧急扩容,或者花了两倍预算买了一堆永远用不满的盘。
这一课把规划拆成可以照着做的步骤:先把业务需求翻译成容量、IOPS、带宽、延迟、可用性五个数字;再把裸容量一步步折算成"日常可以放心用"的容量;然后估算性能、设计节点形态;最后用一个 Ceph RBD 私有云和一个 AI 训练集群两个完整例子把公式走一遍。本课的公式也可以直接用站内的 容量计算器 来算。最后一节讨论一个同样重要的问题:什么时候根本不该选 Ceph。
第一步:把需求翻译成数字
业务方不会跟你说"4K 随机写 p99 延迟 2 ms",他们说的是"虚拟机要流畅""训练别卡"。规划的第一步是和业务方一起填下面这张表,填不出来的格子就是需要继续追问的地方:
| 维度 | 要问的问题 | 示例答案 |
|---|---|---|
| 有效容量 | 现在实际写了多少数据?(不是分配了多少) | 100 TiB |
| 增长率 | 过去一年涨了多少?有没有已知的新业务? | 每年 30% |
| 规划周期 | 这批硬件要撑多久才扩容? | 2 年 |
| 访问接口 | 块、文件还是对象? | RBD(虚拟机系统盘和数据盘) |
| I/O 特征 | 读写比例、块大小、随机还是顺序? | 70% 读,4K~64K 随机为主 |
| IOPS 目标 | 峰值多少? | 20 万 |
| 带宽目标 | 峰值多少?备份窗口里呢? | 5 GB/s |
| 延迟目标 | 看平均还是 p99?多少算合格? | 4K 随机写 p99 < 5 ms |
| 可用性目标 | 一年能容忍停多久? | 99.95%(每年约 4.4 小时) |
| 故障域 | 要扛住坏一台机器、一个机柜,还是一个机房? | 一台机器 |
几个追问的技巧:
- 有效容量问"已写入",不问"已分配"。RBD 默认精简置备,虚拟机分配 1 TB 可能只写了 200 GB。按分配量规划会多买好几倍。反过来,如果业务会开启厚置备或定期写满,就必须按分配量算。
- 延迟目标一定要问百分位。"平均 1 ms"和"p99 1 ms"对硬件的要求差一个档次,方法论回顾 性能指标。
- 有些延迟要求直接决定了"不能用网络存储"。比如 etcd 要求 WAL
fsync的 p99 小于 10 ms,团队的 K8s 部署规范里明确禁止把 etcd 放在 Ceph RBD、NFS、iSCSI 上,一律用本地 NVMe。这类负载不应该出现在存储集群的需求表里。
可用性目标换算成停机时间更直观:
| 可用性 | 每年允许停机 | 对存储意味着什么 |
|---|---|---|
| 99.9% | 约 8.8 小时 | 单集群、主机级故障域即可 |
| 99.95% | 约 4.4 小时 | 单集群,变更和升级必须滚动、不停服 |
| 99.99% | 约 53 分钟 | 机柜级故障域,或者双集群 + 复制 |
第二步:裸容量到可用容量
厂商报价单上的"总容量"和你最终能放心写进去的数据量之间,隔着一长串折扣。一项一项看。
1. TB 与 TiB
硬盘按十进制卖(1 TB = 10¹² 字节),操作系统和 Ceph 按二进制显示(1 TiB = 2⁴⁰ 字节)。1 TB ≈ 0.909 TiB,一块"7.68 TB"的盘在 ceph osd df 里只有约 6.98 TiB。这一项常年被漏掉,一上来就差 9%。
2. 冗余开销
| 冗余方式 | 空间效率 | 最少故障域(推荐) | 适用 |
|---|---|---|---|
| 三副本 | 33.3% | 3(推荐 4 以上) | RBD、CephFS 元数据、小对象、延迟敏感负载 |
| EC 4+2 | 66.7% | 6(推荐 7 以上) | 对象存储、CephFS 数据、冷数据 |
| EC 8+3 | 72.7% | 11(推荐 12 以上) | 大规模对象存储、归档 |
"推荐"那一列比"最少"多一个故障域,原因在后面的 N-1 余量里讲。原理回顾 副本与纠删码。
3. BlueStore 与文件系统开销
BlueStore 的 RocksDB 元数据、分配粒度、对象元数据都要占空间。DB/WAL 放在独立 NVMe 上时,数据盘上的开销很小;和数据共用一块盘时,RBD 负载大约要预留 1%~2%,小对象很多的 RGW 负载更多。本课统一按 2% 估算。有的商业发行版用"每个 OSD 固定扣 23 GiB"这类经验值,思路相同。
其他系统也有类似的"内部预留":Weka 在扣除纠删码和热备后再预留 10% 给系统内部使用,GPFS ECE 要给重建留备用空间。用哪个系统就查哪个系统的规划文档。
4. 水位线:85% 不是装饰
Ceph 有三道水位线,针对的是单个 OSD,不是集群平均值:
| 参数 | 默认值 | 触发后 |
|---|---|---|
mon_osd_nearfull_ratio | 0.85 | HEALTH_WARN OSD_NEARFULL,提醒扩容 |
mon_osd_backfillfull_ratio | 0.90 | 拒绝把数据回填到这个 OSD,恢复可能卡住 |
mon_osd_full_ratio | 0.95 | OSD_FULL,整个存储池拒绝写入 |
ceph osd dump | grep ratio
# full_ratio 0.95
# backfillfull_ratio 0.9
# nearfull_ratio 0.85所以规划的目标是:任何时候、任何 OSD 都不超过 85%。
5. N-1 恢复余量
坏一台机器以后,它上面的数据会在剩下的 N-1 台上重建,每台的使用率会从 u 涨到 u × N/(N-1)。要保证重建后仍不超过 85%:
日常水位上限 = 0.85 × (N-1) / N
N = 5 → 68%
N = 10 → 76.5%
N = 20 → 80.75%节点越少,为 N-1 预留的比例越大。这也是为什么 5 台以下的 Ceph 集群"很不划算":花钱买的盘有三分之一只能看不能用。
把折扣串起来
日常可用容量 = 裸容量(TB) × 0.909 × (N-1)/N × 冗余效率 × (1 - 2% 开销) × 85%写成 Python 函数,后面两个例子都用它:
TB_TO_TIB = 1e12 / 2**40 # 0.9095
def usable_tib(nodes, disks, disk_tb, efficiency, overhead=0.02, fill=0.85, spare_nodes=1):
"""nodes 台、每台 disks 块 disk_tb(TB) 的盘,返回日常可安全使用的有效容量 TiB"""
raw_tib = nodes * disks * disk_tb * TB_TO_TIB
return raw_tib * (nodes - spare_nodes) / nodes * efficiency * (1 - overhead) * fill
# 例 1:10 台 × 10 块 7.68 TB NVMe,三副本
print(f"{usable_tib(10, 10, 7.68, 1/3):.1f} TiB") # 174.6 TiB
# 例 2 冷层:12 台 × 18 块 20 TB HDD,EC 8+3
print(f"{usable_tib(12, 18, 20, 8/11):.1f} TiB") # 2181.9 TiB第三步:性能估算
容量算的是"放得下",性能算的是"跑得动"。估算公式:
集群读 IOPS ≈ OSD 数 × 单 OSD 读 IOPS × 效率系数
集群写 IOPS ≈ OSD 数 × 单 OSD 写 IOPS ÷ 写放大 × 效率系数
集群带宽 ≈ min(盘带宽之和 ÷ 写放大, 网络带宽之和 ÷ 网络放大) × 效率系数
写放大:三副本 = 3;EC k+m 大块顺序写 = (k+m)/k;EC 小块随机写要读-改-写,远大于 (k+m)/k
效率系数:0.6 ~ 0.8,包含软件开销、负载不均、PG 分布不均关键在"单 OSD 能力"这个输入。对 HDD 来说它基本等于盘的能力;对 NVMe 来说,瓶颈是 OSD 进程的 CPU,而不是盘。一块 PCIe 4.0 NVMe 裸盘 4K 随机读能到几十万 IOPS,一个 Ceph OSD 只能用掉其中一小部分:
| 介质 | 裸盘 4K 随机读 | 裸盘顺序读 / 写 | 单 OSD 规划值(经验量级) |
|---|---|---|---|
| 7.2K HDD | 150~200 IOPS | 200~270 MB/s | 约等于裸盘 |
| SATA SSD | 5~9 万 IOPS | 约 500 MB/s | 读 2 |
| PCIe 4.0 NVMe | 50~100 万 IOPS | 6 | 读约 4 万 / 写(后端)约 2.5 万 IOPS |
这张表只能用来做采购前的粗估。真正的输入必须是你自己硬件上的基线:先用 fio 测单盘,再用 rados bench 和 rbd bench 测单 OSD 和整个集群,方法见 基准测试。没有基线的性能规划和没有基线的调优一样,都是玄学。
另外两条经验:
- IOPS 规划按 50% 利用率算。集群跑到理论上限附近时延迟会急剧上升(排队论,回顾 性能指标 里的 Little 定律),有延迟目标的业务要留一半余量。
- 网络经常先于盘成为瓶颈。三副本下每写 1 字节,主 OSD 要在 cluster 网上再发出 2 字节;恢复和回填流量也走 cluster 网。这就是 public 网和 cluster 网要分开、cluster 网要不小于 public 网的原因。
第四步:节点形态设计
同样的裸容量,可以是 6 台大机器,也可以是 12 台小机器。节点形态影响故障半径、恢复时间、EC 可选宽度和单位成本。
| 设计项 | 经验值 | 说明 |
|---|---|---|
| 每节点盘数 | NVMe 8 | 单节点容量不宜超过集群的 10%~15%,否则坏一台的恢复量太大 |
| 节点数 | ≥ 5,EC 集群 ≥ k+m+1 | 太少则 N-1 余量浪费大、EC 宽度受限 |
| DB/WAL(HDD 集群) | 1 块 NVMe 带 8~12 块 HDD | 这块 NVMe 坏了,它带的所有 OSD 一起失效,所以不能带太多 |
| DB 容量 | RBD 为数据盘的 1%~2%,RGW 不小于 4% | 放不下的元数据会溢出到慢盘,性能断崖 |
| CPU(每 OSD) | HDD 1 核;SATA SSD 2 核;NVMe 4~6 线程 | NVMe 集群要追 IOPS 时越多越好 |
| 内存(每 OSD) | osd_memory_target 默认 4 GiB,规划 6~8 GiB | 另加操作系统、MON/MGR 的内存 |
| 网络 | HDD 集群 2×25G;NVMe 集群 2×100G 起 | public 网与 cluster 网分离,各自跨两台交换机做 bond |
| MON | 3 个(大集群 5 个),放在不同机柜 | 数据目录放 SSD |
团队的规划文档里有个很典型的混闪配置:每台 32 块 14.6 TB HDD 配 4 块 1.6 TB NVMe 做 DB/WAL,也就是 1 块 NVMe 带 8 块 HDD,每块 HDD 分到约 200 GB 的 DB,大约是数据盘的 1.4%,对 RBD 足够、对小对象密集的 RGW 偏紧。
例一:Ceph RBD 私有云
需求
就用第一步里那张表:虚拟机平台,有效数据 100 TiB,年增长 30%,规划 2 年,RBD 三副本,峰值 20 万 IOPS(70% 读),4K 随机写 p99 < 5 ms,扛住坏一台机器。
容量
2 年后有效数据 = 100 × 1.3² = 169 TiB候选节点:每台 10 块 7.68 TB NVMe(单台裸容量 76.8 TB)。代入公式,每增加一台节点能多提供约 19.4 TiB 日常可用容量:
76.8 TB × 0.909 × 1/3 × 0.98 × 0.85 ≈ 19.4 TiB (乘以 N-1)
所需 N-1 ≥ 169 ÷ 19.4 ≈ 8.7 → N = 10验算 10 台:
裸容量 10 × 10 × 7.68 TB = 768 TB = 698.5 TiB
N-1 余量 × 9/10 = 628.6 TiB
三副本 × 1/3 = 209.5 TiB
BlueStore × 0.98 = 205.4 TiB
85% 水位 × 0.85 = 174.6 TiB ≥ 169 TiB ✓余量只有 3%,意味着第二年年底必须扩容。这很正常,存储本来就该按增长节奏分批买;关键是采购时就预留好机柜位、电力和交换机端口,扩容时只加节点不动网络。
性能
100 个 NVMe OSD,按上表的规划值、效率系数 0.7:
读 IOPS 上限 ≈ 100 × 40,000 × 0.7 = 280 万
写 IOPS 上限 ≈ 100 × 25,000 ÷ 3 × 0.7 ≈ 58 万
需求:读 14 万 + 写 6 万
利用率 ≈ 14/280 + 6/58 ≈ 5% + 10% = 15% 远低于 50% ✓带宽同理:峰值 5 GB/s,而 10 台节点的 public 网合计 10 × 2 × 100G ≈ 250 GB/s(理论值),100 块 NVMe 的顺序写能力按 3 GB/s × 100 ÷ 3 × 0.7 ≈ 70 GB/s 计也绰绰有余。
结论:全闪 RBD 集群通常是容量先到瓶颈,IOPS 余量很大。这时候真正要关心的是延迟:单个虚拟机 QD1 的 4K 同步写,要经过"客户端 → 主 OSD → 两个副本 OSD → 确认"两跳网络加三次 BlueStore 提交,在 NVMe + 25G 以上网络上通常在 0.5~1 ms 量级。5 ms 的 p99 目标没问题,要是业务要求 p99 < 0.5 ms,就该看最后一节了。
节点形态与网络
| 项目 | 配置 | 依据 |
|---|---|---|
| 数据盘 | 10 × 7.68 TB NVMe | 单节点占集群 10% |
| CPU | 2 × 32 核 | 10 OSD × 6 线程 = 60 线程,留出余量 |
| 内存 | 192 GiB | 10 OSD × 8 GiB + 系统、MON/MGR |
| public 网 | 2 × 100G bond | 虚拟机流量 |
| cluster 网 | 2 × 100G bond | 副本复制与恢复流量 |
| MON / MGR | 3 个,分散在 3 个机柜 | 与 OSD 共节点 |
最后估算坏一台机器后的恢复时间,这决定了"风险窗口"有多长:
单节点数据量 = 76.8 TB × 0.909 × 76.5% 日常水位 ≈ 53.4 TiB ≈ 58.7 TB
按限流后 3 GB/s 的恢复速度:58.7 TB ÷ 3 GB/s ≈ 19,600 s ≈ 5.4 小时5 个多小时内再坏一台机器,部分 PG 就只剩一个副本。可以接受吗?这要写进规划说明,让业务方知情。
例二:AI 训练集群
需求
128 台 GPU 服务器、1024 张卡。按 AI 训练存储选型 一课的方法拆出需求:
| 指标 | 推导 | 目标(含 50% 余量) |
|---|---|---|
| 读带宽 | 约一半卡跑多模态训练,512 卡 × 200 MB/s ≈ 102 GB/s | 150 GB/s |
| 写带宽 | 70B 模型 checkpoint 980 GB,54 s 内写完 ≈ 18.1 GB/s | 30 GB/s |
| 热层容量 | 活跃数据集 250 TiB + checkpoint 约 36 TiB(4 个作业 × 10 份 × 0.98 TB)+ home/实验 80 TiB,再加 10% | 约 400 TiB |
| 冷层容量 | 原始数据与历史 checkpoint | 2 PB |
| 延迟 | 元数据操作毫秒级以内 | 并行文件系统 + RDMA |
架构按三层来:GPU 节点本地 NVMe 做缓存,热层用全闪并行文件系统,冷层用 Ceph RGW 对象存储。
热层:两种节点形态对比
热层以 Weka 类的分布式纠删码全闪文件系统为例,容量公式换成它的规则:扣一个节点的热备、扣纠删码、再扣 10% 系统预留。每节点 2 × 200G 网卡,理论 50 GB/s,按 80% 计实际约 40 GB/s。单盘性能用厂商按盘给出的集群级估算:读约 3.67 GB/s、写约 1.0 GB/s(已计入纠删码和软件开销)。
| 项目 | 方案 A:6 台 × 12 × 15.36 TB | 方案 B:10 台 × 12 × 7.68 TB |
|---|---|---|
| 裸容量 | 1105.92 TB = 1005.8 TiB | 921.6 TB = 838.2 TiB |
| 纠删码 | 4+2 | 6+2 |
| 可用容量 | 1005.8 × 5/6 × 4/6 × 0.9 ≈ 502.9 TiB | 838.2 × 9/10 × 6/8 × 0.9 ≈ 509.2 TiB |
| 85% 水位后 | 427.5 TiB ≥ 400 ✓ | 432.8 TiB ≥ 400 ✓ |
| 读带宽 | min(72 盘 × 3.67, 6 × 40) = 240 GB/s ✓ | min(120 盘 × 3.67, 10 × 40) = 400 GB/s ✓ |
| 写带宽 | 72 × 1.0 = 72 GB/s ✓ | 120 × 1.0 = 120 GB/s ✓ |
| 坏一台损失 | 1/6 的带宽,重建 184 TB 裸数据 | 1/10 的带宽,重建 92 TB 裸数据 |
两个方案容量几乎一样,都满足带宽目标。方案 A 用的服务器少,但单盘更贵、EC 效率更低(66.7% vs 75%)、故障半径更大;方案 B 裸盘少买 184 TB,EC 更宽,也满足厂商"推荐 8 台以上"的建议,代价是多 4 台服务器的 CPU、网卡和交换机端口。团队会选 方案 B,理由是故障半径小、以后扩容时每台节点的增量更平滑。
CPU 按"每块盘 1 个 drive 核 + 2 个 compute 核"计算,12 块盘要 36 个专用核,加上 frontend 和系统,配 2 × 24 核(关闭超线程)、384 GB 内存。
冷层:EC 宽度决定节点数
冷层要 2 PB 有效容量,即 2000 TB × 0.909 ≈ 1819 TiB,用 EC 8+3 提高空间效率。先看一个"只算容量"的方案:6 台 4U 机器、每台 36 块 20 TB HDD,裸容量 4320 TB,看起来足够。但 8+3 以 host 为故障域至少要 11 台、推荐 12 台,6 台根本建不出这个存储池。
同样的 4320 TB 裸容量,换成 12 台 × 18 块 20 TB:
裸容量 12 × 18 × 20 TB = 4320 TB = 3929.0 TiB
N-1 × 11/12 = 3601.6 TiB
EC 8+3 × 8/11 = 2619.3 TiB
BlueStore × 0.98 = 2567.0 TiB
85% 水位 × 0.85 = 2181.9 TiB ≥ 1819 TiB ✓每台节点:18 块 HDD 配 2 块 7.68 TB NVMe 做 DB/WAL(每块 NVMe 带 9 块 HDD,每块 HDD 分到 800 GB,正好是 20 TB 的 4%,满足 RGW 的建议),CPU 按每 HDD OSD 2 线程算需要 36 线程,内存 18 × 6 GiB + 系统 ≈ 128 GiB,网络 2 × 25G(18 块 HDD 顺序吞吐约 3.6 GB/s,接近 29 Gb/s)。
本地缓存层
每台 GPU 服务器配 4 块 7.68 TB NVMe 做数据集缓存,128 台合计约 3.9 PB 缓存容量、每台 20 GB/s 以上的本地读带宽。这一层不花存储预算,却能挡住数据集第二个 epoch 以后的绝大部分读流量,是整个方案里性价比最高的部分。
什么时候不该选 Ceph
Ceph 是很好的通用分布式存储,但不是万能的。以下几种情况,选 Ceph 往往是给自己挖坑:
| 场景 | 为什么不合适 | 更好的选择 |
|---|---|---|
| 规模太小(< 5 台、< 100 TB) | N-1 余量和三副本吃掉大半容量,MON/MGR/OSD 的运维成本却一点不少 | 双控 NAS / SAN、ZFS 单机加异地复制、云盘 |
| 极致低延迟(p99 < 0.5 ms 的 OLTP 数据库、etcd) | 网络两跳 + 副本确认 + 软件栈,延迟很难压到亚毫秒 | 本地 NVMe + 应用层复制(MySQL 组复制、TiKV、etcd 自身的 Raft) |
| 团队没有运维能力 | 出问题时需要懂 PG、CRUSH、BlueStore 的人在场,否则小故障容易变成数据事故 | 商业一体机、托管服务、厂商驻场 |
| AI 训练高带宽 / 单客户端高吞吐 | 生产环境基本没有 RDMA,单客户端带宽几 GB/s,CephFS 元数据在海量小文件下吃力 | GPFS、Weka、VAST、3FS 等(见 AI 训练存储选型) |
| 跨广域网强一致 | RADOS 要求同步复制,跨城延迟会拖慢每一次写 | 每个站点独立集群 + 异步复制(RBD mirroring、RGW multisite) |
反过来说,Ceph 最擅长的是:几百 TB 到几十 PB、块 / 文件 / 对象都要、有一个愿意长期投入的运维团队、对成本敏感。满足这几条,它几乎总是正确答案。
动手练习
- 用本课的
capacity.py(或站内 容量计算器)算一下:5 台、每台 12 块 3.84 TB SATA SSD、三副本的集群,日常可用容量是多少?如果改成 8 台同样的机器呢?每 TB 裸容量对应的可用容量提升了多少? - 在测试集群上执行
ceph osd dump | grep ratio查看三道水位线,再用ceph osd df tree观察 OSD 之间的使用率差异(%USE和VAR两列),看看 balancer 是否开启(ceph balancer status)。 - 用 fio 在一块空闲盘(或 loop 设备)上测 4K 随机读、4K 随机写和 4M 顺序读三组基线,填进本课的"单 OSD 规划值"表格,和经验值做对比。
- 为你所在团队的一个真实业务填写第一步的需求表,找出至少两个"业务方答不上来"的格子,写下你打算怎么追问。
- 例一中如果把故障域改成机柜(4 个机柜、每柜 2~3 台),N-1 余量的公式应该怎么改?重新估算日常水位上限。
自测
10 台节点的 Ceph 集群,日常使用率应该控制在多少以内?为什么?
0.85 × (10-1)/10 = 76.5%。坏一台节点后,它的数据会在剩下 9 台上重建,每台使用率变为原来的 10/9 倍;要保证重建后任何 OSD 仍不超过 nearfull_ratio 85%,日常就要控制在 76.5% 以内。如果 OSD 之间分布不均,还要再留余量。
6 台主机上创建以 host 为故障域的 EC 4+2 存储池,有什么问题?
每个 PG 的 6 个分片正好占满 6 台主机。坏一台后没有空闲主机来放重建的分片,PG 会一直处于降级状态直到那台主机恢复,期间再发生故障就可能丢数据。EC 的 k+m 应该至少比故障域数量少 1,即 4+2 至少用 7 台主机。
为什么 NVMe 集群估算 IOPS 时不能直接用裸盘标称值?
NVMe 裸盘能提供几十万甚至上百万 IOPS,但一个 Ceph OSD 进程受 CPU、网络往返和 BlueStore 提交路径限制,只能用掉其中一小部分,瓶颈在软件而不在盘。估算时要用单 OSD 的实测基线(或保守经验值),再除以写放大、乘以效率系数。
一块 7.68 TB 的 NVMe,三副本、2% 开销、10 台集群、85% 水位,折算成日常可用的有效容量约多少?
7.68 × 0.909 ≈ 6.98 TiB;× 9/10 ≈ 6.29;× 1/3 ≈ 2.10;× 0.98 ≈ 2.05;× 0.85 ≈ 1.75 TiB。也就是说买一块 7.68 TB 的盘,最终只能放心写入约 1.75 TiB 的业务数据,不到标称值的四分之一。
什么样的需求说明你不该选 Ceph?举两个例子。
例如:总容量只有几十 TB、只有 3 台机器(余量和运维成本不划算);业务要求 p99 延迟低于 0.5 ms(网络和副本确认很难做到);AI 训练需要单客户端几十 GB/s 和 RDMA(CephFS 做不到);团队没有能处理 PG 异常的运维人员。