「集群能写」与「集群健康」不是同一件事。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.5(
docs.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。
HEALTH_ERR:常与 MON 失 quorum、大量 PG 不可服务、严重 inconsistent 等相关——不等于「已经丢数据」,但等于「先别扩容、先别做危险 repair」。HEALTH_WARN:nearfull、degraded、slow_request、clock skew 等;集群往往仍可写。
ceph health detail 展开具体
OSD/PG。汇聚逻辑在 src/mon/HealthMonitor.cc
等模块;detail 里没有的告警,不代表 OSD 本地 log
没有——只是还没汇到 MON。
mon / mgr / osd 行
mon: N daemons, quorum {ids}:quorum \(< \lfloor N/2\rfloor+1\) 时写路径停。mgr: {active}, {standbys}:MGR 挂掉影响 Prometheus/Dashboard,不挡 RADOS 数据面。osd: total / up / in:up≠in。up+out= 进程在但不承载;down+in= 权重仍在、数据待迁移——后者才是 recovery 风暴的常见前奏。
pg / io / data 行
pg:汇总状态串。全部active+clean才是完整健康态;active+*其它组合见下节。client io:近期吞吐/IOPS,MON 汇聚,平滑后的数——不能当微基准。data: used / avail:裸字节。逻辑容量大致avail / size(副本)或按 EC 比率折算;用 raw 当「还能存多少业务数据」是经典误读。
三、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_started。last_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,可按
unclean、inactive、stale
过滤,适合快速识别问题 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 tree
的 USE% / 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_bytes、op_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_lat、state_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 tree 比
ceph 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 dump 中
mds_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 里重复出现;每条都对应「字段语义 ≠ 业务口语」。
active+degraded≠ 数据丢失:副本数不足期望但仍 ≥min_size时可读写。不可读对应incomplete/ 长期 inactive peering。recovery_wait≠ 前台已死:PG 仍 active;排队的是后台 reservation。前台变慢时,先看 recovering OSD 的 commit latency 与磁盘%util,不要先怪 mClock「限错了」。slow_ops累计 ≠ 此刻仍慢:超osd_op_complaint_time(默认 30s)计一次。当前慢看dump_ops_in_flight。osd perf均值 ≠ P99:混速介质或混负载时必须看 histogram。ceph dfRAW USED% 低 ≠ 无 nearfull:阈值按 单 OSD;osd df tree才是容量轴主视图。- MGR Prometheus 绿 ≠ OSD 内部绿:mgr
指标来自 MON 聚合,默认十余秒级;
kv_sync_lat尖刺可能根本没进 scrape 窗口——亚秒问题用perf dump/ceph-exporter。 client io下降 ≠ 集群坏了:也可能是客户端限流、业务低峰、或 peering 只打中少数 PG 而汇聚被平均掉。
十一、把字段接到排障轴
第 16 篇五轴的入口字段可压缩成:
| 轴 | 先看的字段 / 命令 |
|---|---|
| Slow ops | health detail →
dump_ops_in_flight →
kv_sync_lat |
| Peering | pg dump_stuck → pg 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 -s 的
client io 会把局部磁盘饱和平均掉。
双方都对,但适用层不同:容量/健康走
A;「业务写超时」走 B。把 A 的绿当成 B
的绿,是本篇第七条误判的学术化表述。
开放问题
- MGR scrape 窗口与 RocksDB stall
是否可对齐:在默认 scrape
间隔下,
kv_sync_lat尖刺能否稳定进入告警?可检验实验:人为制造短于 scrape 周期的 compaction stall,比较 Prometheus 序列与perf dump采样是否同时报警。
slow_ops累计计数能否支持 SLO:累计型计数适合「是否发生过」,不适合「此刻违约比率」。是否应在 Squid 路径上强制以 in-flight 直方图为主指标,仍开放(入口:monitoring/与 OSDperf_counters源码)。
参考资料
官方文档(A 级)
- Ceph Squid — Monitoring
a Cluster
(
docs.ceph.com/en/squid/rados/operations/monitoring/) - Ceph Squid — Placement Group States
- Ceph Squid — mgr Prometheus module
- 源码:
src/mon/PGMap.cc(PG 聚合)、src/osd/OSD.cc(slow_request 上报)@ v19.2.5
系列内
- 第 5 篇 ·
PG 与 Peering(
last_epoch_started、PG log 与 peering 状态机机制) - 第 10 篇 · Recovery / Backfill / Scrub(mClock 限速与 reservation)
- 第 16 篇 · 排障坐标系(将本节字段映射到具体故障轴)
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【Ceph RADOS】RADOS 内核全景:五轴坐标系与 18 篇路线
补齐站内 distributed/38 之上的 RADOS 内核层缺口;定义 Map 传播、通信、一致性、本地存储、接入代价五条坐标系,给出 18 篇阅读路线与系列边界。
【Ceph RADOS】MON/MGR 与 Map:quorum、epoch 传播与客户端可见性
拆解 Ceph MON Paxos quorum、OSDMap/PGMap 结构与 epoch 传播机制;说明 MGR 主备模型与模块框架;分析客户端 epoch 缓存与可见性窗口的边界条件。
【Ceph RADOS】OSD 与 Messenger:daemon 结构、msgr2 协议与 Op 入队路径
拆解 ceph-osd daemon 内部结构、msgr2 Frame 格式与握手阶段,追踪 Op 从 TCP socket 经 AsyncMessenger、OSD::dispatch_context 到 ShardedOpWQ 的完整入队路径。
【Ceph RADOS】CRUSH 加深:rule/bucket/weight 机制与失败域语义
相对 distributed/38 的 CRUSH 算法概览,深入 bucket 类型的算法复杂度差异、rule step 语义、weight 体系与 primary_affinity,分析 chooseleaf 与失败域的精确定义及 CRUSH 与一致性哈希的本质区别。