
这篇指南帮助你排查 Ceph(一种分布式存储系统)RBD(RADOS Block Device,块设备)延迟问题:从 OSD(Object Storage Daemon,对象存储守护进程)状态、PG(Placement Group,归置组)分布到网络延迟,逐层定位根因。RBD 延迟直接影响云服务器上数据库和虚拟机的 I/O 性能,排查比单机存储复杂,需要理解 Ceph 的多副本写入和恢复流程。
如果你的云服务器跑 Kubernetes 或 KVM 虚拟机,后端存储常用 Ceph RBD。Hostease 中文博客的 WordPress 数据库优化关注查询层面,VPS 入侵应急关注安全层面,本文聚焦存储层面:怎么定位 RBD 延迟的根因,怎么判断是 OSD 异常还是网络瓶颈。Ceph 集群相比单机存储复杂,因为它涉及多副本同步和恢复机制,排查时要理解主 OSD 和副本 OSD 的写入确认流程,才能准确定位是哪一环拖慢了延迟。同时要把 Ceph 延迟纳入业务 SLA 监控,避免成为隐性故障点。
一、Ceph RBD 的写入路径
Ceph RBD 写入采用多副本机制。客户端写入 RBD 时,数据先到主 OSD(Primary OSD),主 OSD 写入完成后同步到副本 OSD(Replica OSD),所有副本确认后才返回客户端。这个流程涉及的环节:客户端到主 OSD 的网络延迟、主 OSD 的写入吞吐、副本同步的网络延迟、副本 OSD 的写入吞吐。任何一环异常都会导致延迟增加。
默认配置下 Ceph 使用 PG 数量 = 副本数 × OSD 数量 / 100 计算。PG 过少会导致每个 OSD 上的 PG 分布不均,单个 PG 压力大;PG 过多会增加 PG 状态同步开销。建议 PG 数量在 100 到 300 之间,单个 OSD 上的 PG 数量控制在 100 以内。

二、查看 OSD 状态
OSD 状态异常是 RBD 延迟的最常见原因。先用 ceph osd tree 查看 OSD 树形结构,确认所有 OSD 都是 up 和 in 状态。
ceph osd tree ceph health detail ceph osd perf
如果某个 OSD 显示 down 或 out,说明该 OSD 上的数据不可用,写入会等到副本恢复或超时返回。需要立即查看 OSD 进程状态:
systemctl status ceph-osd@0 journalctl -u ceph-osd@0 -n 100
OSD 进程异常退出的常见原因包括磁盘故障、内存不足、网络抖动。如果是磁盘故障,OSD 节点需要更换磁盘后重新加入集群。如果只是进程崩溃,重启后会触发数据恢复,期间延迟会更高。可以用 smartctl -a /dev/sdX 检查磁盘健康状态,关注 ReallocatedSectorCount 和 CurrentPendingSector 等指标是否增长,这些指标反映磁盘是否开始出现物理坏道。坏道增多会导致写入延迟升高,最终触发 OSD 自动下线保护数据。
还有一种常见情况是 OSD 没崩溃但变慢。磁盘使用时间变长后,I/O 性能会逐渐下降,特别是 HDD 机械硬盘。用 fio 测试裸盘性能,和 RBD 上的 fio 测试结果对比。如果裸盘正常但 RBD 异常,问题在 Ceph 层;如果裸盘也异常,需要更换或升级磁盘。OSD 节点本身的 CPU 和内存也会影响延迟,OSD 进程是高 CPU 密集型应用,复制和恢复时 CPU 消耗显著,CPU 资源不足会让延迟飙升。
三、检查 PG 分布
PG 分布不均会导致部分 OSD 压力过大,表现为这些 OSD 上的延迟高于平均水平。用 ceph pg dump 查看每个 PG 的状态和主 OSD。
ceph pg dump | head -20 ceph pg dump_stuck
关注 stuck(卡住)的 PG:如果 PG 长时间处于 active+clean 之外的状态(比如 active+remapped、stale),说明数据迁移或恢复未完成,延迟会持续升高。常见卡住原因是 backfill(数据回填)速度过低或恢复优先级设置不当。可以通过 ceph config set osd_recovery_max_active_hdd 3 限制并发恢复任务数,避免恢复和写入互相挤占资源。
四、网络延迟排查
多副本 Ceph 集群对网络延迟非常敏感。OSD 节点之间的网络延迟直接决定副本同步速度。用 iperf3 和 fio 分别测试网络带宽和存储延迟。
iperf3 -c osd-node-2 -t 30 fio --name=randwrite --filename=/dev/rbd0 --rw=randwrite --bs=4k --size=1G --runtime=30 --time_based --direct=1 --ioengine=libaio
如果网络带宽低于预期(如千兆网卡实际只跑 500Mbps),检查交换机配置和网卡绑定状态。如果 fio 测试的 RBD 延迟远高于本地磁盘延迟,说明 Ceph 网络层引入的开销过大。可以尝试调整 ms_dispatch_throttle_low 和 ms_dispatch_throttle_high 参数优化请求分发。
| 组件 | 健康指标 | 异常信号 |
|---|---|---|
| OSD 进程 | 全部 up 且 in | down 或 out |
| OSD 磁盘 | smartctl 健康 | ReallocatedSectorCount 增长 |
| PG 状态 | active+clean | stale、incomplete |
| 网络延迟 | 小于 1ms(同 IDC) | 大于 5ms 或抖动 |
| 延迟分布 | P99 小于 10ms | P99 大于 50ms |
五、客户端缓存与配置优化
RBD 客户端缓存可以减少直接命中 Ceph 后端的频率。用 rbd config pool 查看池级别配置,调整 rbd_cache_size 和 rbd_cache_max_dirty 提升读性能。
rbd config pool set rbd rbd_cache_size 256MiB rbd config pool set rbd rbd_cache_max_dirty 128MiB
写延迟优化可以从副本数入手:3 副本提供高可用但延迟高,2 副本延迟低但容错差。对于读多写少的场景,可以用 cache tiering(缓存分层)把热数据放在 SSD(固态硬盘)池,冷数据放在 HDD(机械硬盘)池。如果你的存储后端是 多层缓存架构里的某一层,Ceph RBD 本身的缓存参数需要和上层缓存策略协调,避免缓存失效导致穿透到底层存储。

六、监控与告警
长期监控 RBD 延迟和 OSD 健康指标。用 Prometheus 抓取 Ceph 自带的 mgr exporter,配置告警阈值:当 P99 延迟超过 50ms 持续 5 分钟告警、当 OSD down 数大于 0 立即告警、当 stuck PG 数量增长告警。告警触发后按本文的排查顺序定位根因:先看 OSD 状态、再看 PG 分布、最后看网络延迟。如果你在 多层缓存架构中运行 Ceph,监控告警还需要和上层缓存层打通,避免上层缓存失效时 Ceph 延迟无法被及时发现。
总结
Ceph RBD 延迟排查要从 OSD 状态、PG 分布、网络延迟、客户端缓存四个维度逐层定位。OSD 异常是最常见根因,先确认所有 OSD up 且 in;PG 卡住是恢复期的典型问题,调整恢复优先级和并发数;网络延迟多见于多机房部署,建议同 IDC 部署;客户端缓存参数影响读写延迟,按业务场景调整。长期监控和告警是预防延迟问题的关键,建议在 Hostease 这类云服务器环境部署监控告警,把 RBD 延迟纳入业务 SLA 监控范围。