土法炼钢 · 系统与基础设施

【Ceph RADOS】可观测:如何读懂 ceph status、pg dump 与 OSD perf

文章导航

分类入口
storagedistributed
标签入口
#ceph#observability#pg-states#osd-perf#prometheus#squid#v19.2.5

目录

「集群能写」与「集群健康」不是同一件事。Ceph 对外暴露的可观测接口覆盖了从 MON quorum 到 OSD 级提交延迟的多个层级,但每个字段的语义并不直观——active+clean 不代表没有慢 op,recovery 状态不代表前台已经受影响,slow_request 计数上升可能来自 BlueStore WAL 也可能来自网络。

本文是系列第 15 篇,目标是:给出每个关键字段的确切含义、正常/异常的判断依据、以及在 Prometheus 中对应的 metric 名,不虚构命令输出。

本文是「Ceph / RADOS 存储内核」系列第 15 篇(共 18 篇)。→ 系列目录

篇目 核心内容
第 14 篇 · RGW 索引/数据池、S3→RADOS 映射
第 15 篇 · 可观测 ceph status / pg dump / OSD perf 口径
第 16 篇 · 排障坐标系 slow ops、peering、满盘、恢复拖死、checksum

版本锚定:Ceph Squid v19.2.5docs.ceph.com/en/squid/rados/operations/monitoring/;源码 src/mon/src/mgr/ @ v19.2.5)。


一、先选观测层,再动命令

集群层:  ceph -s / ceph status / ceph health detail
服务层:  ceph osd tree / ceph osd df / ceph df
PG 层:   ceph pg dump / ceph pg {pgid} query
OSD 层:  ceph osd perf / ceph daemon osd.X perf dump
应用层:  ceph tell osd.X dump_ops_in_flight
Metrics: mgr Prometheus module / ceph-exporter

不同层级的刷新频率不同:ceph -s 的数据来自 MON 聚合,约 5 秒刷新一次;ceph daemon osd.X perf dump 直接查询 OSD 进程,实时;pg dump 是当前 PGMap 快照,数据完整但量大。


二、ceph status 字段语义

ceph status / ceph -s 是 MON 聚合快照,不是瞬时示波器。读它之前先记住:刷新约数秒一级;字段之间不共享同一时钟边沿。

health

ceph health 返回 HEALTH_OK / HEALTH_WARN / HEALTH_ERR

ceph health detail 展开具体 OSD/PG。汇聚逻辑在 src/mon/HealthMonitor.cc 等模块;detail 里没有的告警,不代表 OSD 本地 log 没有——只是还没汇到 MON。

mon / mgr / osd 行

pg / io / data 行


三、PG 状态机:关键状态含义

PG state 是标志位组合。读 pg dump 时先拆组合,再下结论:

PG 状态 含义
active+clean PG 有完整 acting set,所有对象副本完整无降级,可正常读写
active+degraded acting set 完整(可读写),但某些对象的副本数少于 min_size(未达到 size 但 ≥ min_size
active+undersized PG 的 acting set 大小 < 期望(size),因为可用 OSD 数不足;若仍 ≥ min_size 则可写入
active+degraded+undersized acting set 既不完整又有对象降级,处于临界可写区域
peering PG 正在进行 peering 协议(建立 acting set、核对 PG log),期间客户端 I/O 被 hold
activating peering 完成,PG 准备进入 active 状态(replaying log, applying backlog)
recovering PG 在 active 状态下后台恢复缺失副本(primary push 对象给降级的 replica)
backfilling PG 在 active 状态下全量同步(新加入或替换 OSD 时,从头同步所有对象,区别于 recovery 只补日志差量)
backfill_wait 等待 backfill reservation(mClock 限速,排队中)
recovery_wait 等待 recovery reservation(mClock 限速,排队中)
stale MON 长时间(默认 5 分钟)未收到该 PG 的 primary OSD 上报,认为 PG 失联
inconsistent scrub/deep-scrub 发现副本间对象内容不一致(校验错误或位翻转),需要 repair
incomplete PG peering 失败(可用的 OSD 子集没有足够 PG log 还原到一致状态),该 PG 不可读写
remapped PG 的目标 acting set 已改变(CRUSH map 更新),但数据迁移(backfill)尚未完成,读写仍走旧 acting set
forced_recovery / forced_backfill ceph pg force-recovery 提升优先级

incomplete 是最严重的 PG 状态,意味着该 PG 的数据在逻辑上不可访问(不是硬件损坏,但日志不足以重建一致状态)。修复路径需要管理员手动介入(见第 16 篇)。

last_epoch_started 与 peering 完成条件

PG peering 时,每个 OSD 上报其本地 PG 版本与 last_epoch_startedlast_epoch_started(LES)标记了该 OSD 上该 PG 最后一次完整 active 的 epoch,用于确认 acting set 中谁的 PG log 最权威(详见第 5 篇)。ceph pg {pgid} query 输出中包含每个 peer 的 LES 值,用于诊断 peering 为何卡住(某个 OSD 的 LES 太旧)。


四、ceph pg dump:关键字段

ceph pg dump 输出格式为若干列,关键字段含义:

字段 含义
pgid PG 标识符,格式 {pool_id}.{pg_id_hex}
state PG 当前状态(见上节)
up CRUSH 计算出的 OSD 列表(期望 acting set)
acting 实际参与该 PG 读写的 OSD 列表;若 OSD down,acting 比 up 小
acting_primary acting set 中 Primary OSD 的 ID
stat_sum PG 内各类对象计数(num_objects、num_bytes、num_degraded_objects 等)
last_change PG 状态最后变更的 epoch
reported_epoch OSD 上报该 PG 状态时的 osdmap epoch

ceph pg dump_stuck 是一个更聚焦的命令,只列出 stuck(状态无法推进超过阈值的)PG,可按 uncleaninactivestale 过滤,适合快速识别问题 PG。

ceph pg {pgid} query 输出该 PG 的详细内部状态(来自 Primary OSD),包含 peering 历史、log 条目范围、每个 peer 的状态,是 peering 问题的一线诊断工具。该命令向 Primary OSD 发 RADOS 消息,不经 MON 缓存,返回实时状态。


五、ceph osd perf:延迟口径

ceph osd perf 每 OSD 两列核心均值:

字段 语义 常见误读
commit latency 写路径上客户端可感知的提交延迟:Primary 收齐副本 ACK(及本地持久语义)后回客户端的平均时间,含 BlueStore WAL/journal 与副本网络 「等于端到端应用延迟」——缺了客户端→Primary 的第一跳与上层队列
apply latency 数据真正落到设备(含 deferred 刷盘)的平均时间,通常 ≥ commit 「apply 高就一定写失败」——deferred 模型下 commit 可先返回;apply 积压伤的是读 miss 与崩溃窗口

若 commit 正常、apply 飙高:看 deferred 队列与磁盘;若 commit 与 apply 同飙:磁盘或网络已在前台路径上。ceph osd df treeUSE% / WEIGHT 是容量轴,不要和 perf 延迟轴混成一张图解读。

均值陷阱:SSD/HDD 混部或冷热 PG 混部时,滑动平均会抹平 P99——必须下钻 ceph daemon osd.X perf dump 的 histogram。


六、OSD 内部 perf dump

ceph daemon osd.{id} perf dump 直接向 OSD 进程查询内部计数器。关键子树:

子树 典型关键字 含义
osd op_w_in_bytesop_r_in_bytes 客户端读写字节计数
osd op_wip 当前进行中的 op 数量
osd op_latency op 延迟分布(histogram)
osd slow_ops 慢操作累计计数
bluestore kv_sync_lat RocksDB sync 延迟(journal/WAL 落盘)
bluestore state_kv_queued_latstate_io_done_lat BlueStore 各状态停留时长
msgr lossless_tx_bytes Messenger 层发送字节
recoverystate_perf peering 各状态停留 counter 诊断 peering stuck 时间分布

slow_ops 的触发阈值由 osd_op_complaint_time(默认 30 秒)控制:一个 op 在 OSD 队列/处理中停留超过此时长,即被计入 slow_ops 并写入 OSD log(WRN 0 slow requests)。

ceph tell osd.{id} dump_ops_in_flight 列出当前 OSD 上所有进行中的 op 及其已停留时长,可用于判断是否存在「少量特定 op 拖慢整体」的模式(例如针对特定 PG 的 op 被 peering block)。


七、mgr Prometheus module:长期指标

Squid v19.2.5 的 mgr Prometheus module(ceph mgr module enable prometheus)在 {mgr_host}:9283/metrics 暴露 Prometheus 格式指标。关键 metric 家族:

Metric 含义
ceph_health_status 0=OK、1=WARN、2=ERR
ceph_osd_up / ceph_osd_in per-OSD up/in 状态
ceph_osd_commit_latency_ms commit 延迟(毫秒,per-OSD gauge)
ceph_pg_total 总 PG 数
ceph_pg_active / ceph_pg_clean active/clean PG 数
ceph_pg_degraded 降级 PG 数
ceph_pg_recovering 恢复中 PG 数
ceph_pool_rd / ceph_pool_wr per-pool 读写 ops/s
ceph_pool_bytes_used per-pool 已用字节
ceph_cluster_total_bytes / ceph_cluster_total_used_bytes 集群容量

告警建议: - ceph_health_status > 0 持续 5 分钟 → 告警。 - ceph_pg_degraded > 0 持续超过预期恢复时间(根据副本数与容量估算)→ 告警。 - ceph_osd_commit_latency_ms 某 OSD 的 P99 超过阈值(取决于硬件,SSD 100ms 以上通常是异常信号)→ 告警。 - ceph_cluster_total_used_bytes / ceph_cluster_total_bytes > 0.75 → nearfull 警戒线。

mgr Prometheus module 的数据来自 MON 聚合的 PGMap/OSDMap,刷新频率默认 15 秒(scrape_interval 不应低于 MON 聚合周期 5 秒,建议 10–30 秒)。

另有 ceph-exporter sidecar 进程(Quincy 引入,Squid 继续维护)可以更高频率采集 per-OSD 内部 perf dump,适合需要 sub-15s 精度的场景。


八、ceph df 与容量规划的口径

ceph df 输出两个层级的容量信息:

集群级(RAW 字节): - TOTAL:所有 OSD 的裸容量总和。 - AVAIL:当前可用裸容量(TOTAL - 已用 - 系统预留)。 - USED:已写入数据的裸字节数(含副本 overhead)。 - RAW USED %:已用裸字节占总裸字节的百分比。

Pool 级(逻辑字节): - STORED:该 pool 中存储的逻辑数据量(去重前)。 - OBJECTS:对象数量。 - USED:该 pool 占用的裸字节数(= STORED × 副本数,或 EC 编码后的裸量)。 - QUOTA OBJECTS / QUOTA BYTES:pool 级 quota(若设置)。

容量规划的关键:AVAIL 与 nearfull/full 触发的是 per-OSD 阈值,不是集群整体。若某个 OSD 的使用率已超过 nearfull ratio,但集群 RAW USED % 仍在 70%,告警仍会触发(见第 16 篇轴三)。因此 ceph osd df treeceph df 对容量规划更有价值——需要看每个 OSD 的 USE%,而不只是集群均值。

对 EC 池,USED / STORED 的比值反映 EC overhead(3+2 EC 的 overhead ≈ 1.67,与副本 3x 相比略低);对副本池,USED / STORED ≈ replica_count。跨 pool 的 STORED 加总是逻辑数据量,USED 加总是裸占用量;二者之差就是冗余代价。

九、CephFS 与 RGW 专项观测

CephFS 的 MDS 可观测

ceph fs status 显示文件系统的 MDS daemon 状态、每个 active rank 的缓存使用量(Capacity 字段)、客户端数量(Clients)、以及进行中的 MDS op 速率(Ops)。

ceph tell mds.{rank} perf dump 输出 MDS 内部计数器,关键字段: - mds_mem.ino:内存中 inode 数量(与 mds_cache_memory_limit 对比)。 - mds_server.cap_revoke_eviction:cap revoke 超时后强制驱逐客户端的次数(非零说明有客户端 cap 响应慢)。 - mds_log.ev:MDS journal event 速率(与 journal replay 时间估算相关)。

MDS journal 积压是 MDS 健康的关键信号:若 ceph tell mds.0 get perf dumpmds_log.segmented 持续增加而 mds_log.trimmed 不追,说明 journal flush 速度低于写入速度,元数据池 I/O 可能是瓶颈,直接影响 MDS 操作延迟与 failover 时 replay 时间。

RGW 的可观测

RGW 可通过以下方式监控: - radosgw-admin gc list:查看待 GC 条目数量(估算磁盘空间释放的延迟)。 - radosgw-admin sync status:多站点场景,查看 bi-log 同步落后量(以 entry 数量和时间戳差表示)。 - radosgw-admin bucket stats {bucket}:查看单 bucket 的对象数、字节数、最后修改时间。 - mgr Prometheus module 中 ceph_rgw_* 指标族:包含 RGW 请求速率、错误率、延迟分布(须 mgr rgw module 启用)。

同时,对 RGW 日志接口({zone}.rgw.log 池的 op_log.* RADOS 对象,若 rgw_enable_ops_log=true 开启),可回溯特定时间段的 S3 请求记录(含 error code、延迟、对象名),但开启 ops_log 会对每次 S3 操作额外写入一次 RADOS,高并发场景有明显 overhead,默认关闭。在排障时可临时开启,使用后应关闭。

十、观测口径的常见误判

下列误判在 on-call 里重复出现;每条都对应「字段语义 ≠ 业务口语」。

  1. active+degraded ≠ 数据丢失:副本数不足期望但仍 ≥ min_size 时可读写。不可读对应 incomplete / 长期 inactive peering。
  2. recovery_wait ≠ 前台已死:PG 仍 active;排队的是后台 reservation。前台变慢时,先看 recovering OSD 的 commit latency 与磁盘 %util,不要先怪 mClock「限错了」。
  3. slow_ops 累计 ≠ 此刻仍慢:超 osd_op_complaint_time(默认 30s)计一次。当前慢看 dump_ops_in_flight
  4. osd perf 均值 ≠ P99:混速介质或混负载时必须看 histogram。
  5. ceph df RAW USED% 低 ≠ 无 nearfull:阈值按 单 OSDosd df tree 才是容量轴主视图。
  6. MGR Prometheus 绿 ≠ OSD 内部绿:mgr 指标来自 MON 聚合,默认十余秒级;kv_sync_lat 尖刺可能根本没进 scrape 窗口——亚秒问题用 perf dump / ceph-exporter
  7. client io 下降 ≠ 集群坏了:也可能是客户端限流、业务低峰、或 peering 只打中少数 PG 而汇聚被平均掉。

十一、把字段接到排障轴

第 16 篇五轴的入口字段可压缩成:

先看的字段 / 命令
Slow ops health detaildump_ops_in_flightkv_sync_lat
Peering pg dump_stuckpg query(LES / blocked_by)
满盘 osd df tree USE%,不是只看 ceph df
恢复拖死 recovering/backfilling + 同 OSD commit latency
Checksum inconsistent + OSD log digest 字段,再谈 repair

无真实集群时,只保留上述语义与误判;不要粘贴伪造的集群状态截图。字段会随版本微调,但「聚合层均值掩盖尾延迟、单盘阈值不等于集群均值」这类误读模式在 Squid 仍然成立。


十二、谱系、争论与开放问题

谱系

Ceph 的可观测面从来不是单一「metrics SDK」:Classic 路径是 MON 聚合的 PGMap/OSDMap + OSD 本地 perf_counters +(可选)mgr 导出。这与 Weil 等人在 OSDI 2006 / PDSW 2007 里强调的「OSD 自治、客户端算放置」一致——控制面只保证 map 与健康摘要,细粒度延迟与卡点必须回到 OSD/MDS/RGW 进程内计数。Squid 的 mgr Prometheus module 把聚合层做成长期趋势;亚秒故障仍依赖 perf dump / dump_ops_in_flight(本篇第五–六节)。

争论:聚合层够不够做 SLO

A 侧:用 mgr Prometheus + 外部告警即可运维——运维成本低,适合容量与健康态。
B 侧:RBD/CephFS 的尾延迟 SLO 必须以 OSD commit/apply histogram 与 in-flight op 阶段为准;只看 ceph -sclient io 会把局部磁盘饱和平均掉。
双方都对,但适用层不同:容量/健康走 A;「业务写超时」走 B。把 A 的绿当成 B 的绿,是本篇第七条误判的学术化表述。

开放问题

  1. MGR scrape 窗口与 RocksDB stall 是否可对齐:在默认 scrape 间隔下,kv_sync_lat 尖刺能否稳定进入告警?可检验实验:人为制造短于 scrape 周期的 compaction stall,比较 Prometheus 序列与 perf dump 采样是否同时报警。
  2. slow_ops 累计计数能否支持 SLO:累计型计数适合「是否发生过」,不适合「此刻违约比率」。是否应在 Squid 路径上强制以 in-flight 直方图为主指标,仍开放(入口:monitoring/ 与 OSD perf_counters 源码)。

参考资料

官方文档(A 级)

系列内

上一篇:RGW · 系列目录 · 下一篇:排障坐标系

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。


By .