现象

一次 OSD 扩容后,集群有几十个 PG 长期处于 active+remapped+backfilling 状态,ceph -s 显示 recovery 速度只有几 MB/s,按这个速度回填几天都跑不完。本文按我自己的排查路径走一遍。

第一步:先确认是不是"真的慢"

ceph -s
ceph osd pool ls detail
ceph pg dump | awk '/active\+remapped\+backfilling/ {print $1, $15}' | head

重点看几件事:

  • 回填速度ceph -s 里的 recovery: X MiB/s 是否远低于磁盘能力
  • PG 总数 vs OSD 数:单个 OSD 上的 PG 数是否超过 200(默认 mon_max_pg_per_osd=250),上限会卡 PG 创建
  • 是否触发 backfillfull:单个 OSD 接近 90% 会停掉回填

第二步:看是不是被限流卡住了

Ceph 默认对 recovery 限流非常保守,生产经常调:

ceph config get osd osd_max_backfills
ceph config get osd osd_recovery_max_active
ceph config get osd osd_recovery_sleep_hdd

典型现象:HDD 集群 osd_recovery_sleep_hdd 默认是 0.1,意思是每个 IO 之间 sleep 100ms。临时拉高(恢复完记得改回去!):

ceph config set osd osd_max_backfills 4
ceph config set osd osd_recovery_max_active 8
ceph config set osd osd_recovery_sleep_hdd 0

NVMe/SSD 集群可以更激进,HDD 别开太高,会拖业务 IO。

第三步:是不是某几个 OSD 在拖后腿

ceph osd perf
ceph daemon osd.X dump_historic_slow_ops

一两块盘 latency 飙到几百 ms,要么 SMART 看坏块、要么这块就是慢盘,临时 ceph osd out X 把它隔离掉,让回填走完再处理。

第四步:PG 数量配比有没有问题

ceph osd df tree

如果某些 OSD 上 PG 数明显高于平均(差 30% 以上),说明 CRUSH 分布不均,可以:

  • 启用 upmap 平衡器:ceph balancer mode upmap && ceph balancer on
  • 或手动 reweight:ceph osd reweight-by-utilization

真正的坑:mClock 调度器

Reef 之后默认调度器从 WPQ 换成了 mClock,它会按 IOPS 配额自动限速。如果你发现怎么调上面的参数 recovery 都不动,多半是 mClock 在卡:

ceph config get osd osd_op_queue
# 临时切回 WPQ(需重启 OSD):
ceph config set osd osd_op_queue wpq

或者用 mClock 的 profile:

ceph config set osd osd_mclock_profile high_recovery_ops

收尾

回填完成后务必把限流改回默认,否则下次掉盘时业务 IO 会被 recovery 抢光:

ceph config rm osd osd_max_backfills
ceph config rm osd osd_recovery_max_active
ceph config rm osd osd_recovery_sleep_hdd

教训一句话:Ceph 的 recovery 速度=慢盘短板 + 限流参数 + 调度器策略,三个维度都得看。

标签: none

添加新评论