- 存储
- 分布式文件系统
- 对象存储
- 后端
- 高可用
【免费下载链接】ceph
Ceph is a distributed object, block, and file storage platform
Ceph 是一个分布式对象、块与文件存储平台,其高可用与高可靠性建立在容错式的软硬件故障管理之上。本指南围绕 Ceph 集群中两个最关键的监控对象——OSD(Object Storage Daemon,对象存储守护进程)与 PG(Placement Group,放置组)——展开,系统讲解 OSD 的in/out、up/down状态语义、PG 的完整状态机(从creating到active+clean)、Acting Set / Up Set 集合、Peering 过程以及 stuck 问题 PG 的识别方法。读完本文,你将掌握一套可直接落地的监控命令集(ceph osd stat、ceph osd tree、ceph pg stat、ceph pg dump_stuck、ceph osd map等),并能结合相关配置参数(mon_osd_down_out_interval、osd_max_backfills、osd_recovery_max_active等)读懂集群健康状态、定位故障根源并做出初步处置。
先记住一条原则:集群某处发生故障,可能使你无法访问某个特定对象,但这并不代表你无法访问其他对象。遇到故障时不要惊慌,按本文的步骤依次监控 OSD 和放置组,再开始故障排查。Ceph 具备自我修复能力,但当问题持续存在时,监控 OSD 和 PG 将帮助你定位问题所在。
OSD 状态模型:in/out与up/down的四象限
Ceph 中每个 OSD 都同时具有两个正交的状态维度:
in/out(服务状态):OSD 是否在集群服务范围内。in表示该 OSD 处于服务中,客户端可以读写其上的数据;out表示该 OSD 已退出服务,CRUSH 不会再为其分配 PG。up/down(运行状态):OSD 守护进程是否正在运行且可被访问。up表示运行中且可达,down表示未运行或不可达。
两者组合形成如下状态矩阵(原文档 ditaa 示意图的文本版):
+----------------+ +----------------+ | OSD #n In | | OSD #n Up | +----------------+ +----------------+ ^ ^ | | v v +----------------+ +----------------+ | OSD #n Out | | OSD #n Down | +----------------+ +----------------+需要理解的关键语义:
- 若 OSD 曾是
in,后因故障或人工操作被置为out,Ceph 会将 PG 迁移到其他 OSD 以维持配置的冗余度。 - 若 OSD 是
out,CRUSH 将不再向其分配 PG;若 OSD 是down,它必然同时是out。 down且in是一个异常组合:一旦出现这种情况,说明该 OSD 未运行却在服务范围内,集群处于不健康状态。
何时集群不显示HEALTH OK是正常的?
运行ceph health、ceph -s或ceph -w时,你可能会发现集群并不总是显示HEALTH OK。以下情形属于预期内、正常的非健康状态,无需恐慌:
- 集群尚未启动。
- 集群刚启动或重启,PG 正在创建、OSD 正在 Peering,尚未就绪。
- 刚刚添加或移除了 OSD。
- 刚刚修改了集群地图(cluster map)。
监控 OSD:确认每个in的 OSD 都在运行
OSD 是否up且正在运行,是监控 OSD 的重要方面:只要集群处于运行状态,每个处于in状态的 OSD 都应当是up的。检查全部 OSD 运行状态,执行:
ceph osd stat输出格式为x osds: y up, z in; epoch: eNNNN,含义如下:
| 字段 | 含义 |
|---|---|
x | 集群中 OSD 的总数 |
y | 处于up状态的 OSD 数 |
z | 处于in状态的 OSD 数 |
eNNNN | 当前 osdmap 的 epoch(地图版本号) |
若in的数量大于up的数量,说明有ceph-osd守护进程未运行。用以下命令找出具体是哪些:
ceph osd tree示例输出:
#ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF -1 2.00000 pool openstack -3 2.00000 rack dell-2950-rack-A -2 2.00000 host dell-2950-A1 0 ssd 1.00000 osd.0 up 1.00000 1.00000 1 ssd 1.00000 osd.1 down 1.00000 1.00000ceph osd tree以 CRUSH 层次结构(pool → rack → host → osd)展示每个 OSD 的STATUS列(up/down)、REWEIGHT与PRI-AFF(主亲和性)。排查技巧:善用设计良好的 CRUSH 层次结构来定位特定 OSD 的物理位置,能显著加速故障定位。
若某个 OSD 处于down状态,用 systemd 启动它(以osd.1为例):
sudo systemctl start ceph-osd@1对于 OSD 已停止或无法重启的问题,参见 OSD Not Running 排查文档。
PG 集合:Acting Set 与 Up Set
当 CRUSH 将 PG 分配给 OSD 时,会根据池所需的副本数,把每个副本分配到不同的 OSD上。例如池要求 3 个副本时,CRUSH 可能将三个副本分别分配给osd.1、osd.2、osd.3。CRUSH 追求的是考虑了你所设置的故障域的伪随机放置,因此在大型集群中,PG 的各个副本很少落在相邻的 OSD 上。
Ceph 用两组集合描述 PG 与 OSD 的关系:
- Acting Set(执行集合):当前持有该 PG 分片完整且可用版本、负责处理客户端请求的 OSD 集合。
- Up Set(上行集合):包含该 PG 某一分片的 OSD 集合。数据正在被迁移、或计划被迁移到 Up Set。
更多背景参见 Placement Group 概念。
何时 Acting Set 与 Up Set 不一致?通常情况下两者完全相同。当它们不一致时,可能意味着:
- Ceph 正在迁移 PG(即 PG 被 remapped);
- 某个 OSD 正在恢复(recovering);
- 集群存在问题(此时 Ceph 通常会显示
HEALTH WARN并伴随 "stuck stale" 消息)。
另一种常见情形是 Acting Set 中的某个 OSDdown或无法服务请求,例如:
- 你添加或移除了 OSD,CRUSH 将 PG 重新分配给其他 OSD,重组了 Acting Set,并通过backfill(背填)流程触发数据迁移;
- 某个 OSD
down后重启,正处于recovering状态; - Acting Set 中某个 OSD
down或无法服务请求,另一个 OSD 临时接管了它的职责。
列出集群所有 PG:
ceph pg dump查看某个 PG 的 Acting Set 与 Up Set:
ceph pg map {pg-num}输出提供 osdmap epoch(eNNN)、PG 编号({pg-num})、Up Set(up[])与 Acting Set(acting[]):
osdmap eNNN pg {raw-pg-num} ({pg-num}) -> up [0,1,2] acting [0,1,2]注意:若 Up Set 与 Acting Set 不匹配,可能意味着集群正在自我再平衡,也可能意味着集群存在问题。
Peering:PG 进入active状态的前提
在向 PG 写入数据之前,PG 必须处于active状态,且最好处于clean状态。为了确定 PG 的当前状态,必须执行Peering(对等):即 PG 的 primary OSD(Acting Set 中的第一个 OSD)与 secondary 及其后续 OSD 进行对等协商,就 PG 的当前状态达成共识。下图假设池有 3 个副本:
+---------+ +---------+ +-------+ | OSD 1 | | OSD 2 | | OSD 3 | +---------+ +---------+ +-------+ | | | | Request To | | | Peer | | |-------------->| | |<--------------| | | Peering | | | | | | Request To | | Peer | |----------------------------->| |<-----------------------------| | Peering |OSD 同时也会向 monitor 上报自身状态,相关机制参见 Monitor/OSD 交互配置。Peering 故障排查参见 failures-osd-peering。
监控 PG 状态
运行ceph health、ceph -s或ceph -w时,集群可能不显示HEALTH OK。在确认 OSD 运行正常之后,还应当检查 PG 状态。以下与 PG 对等相关的场景中,集群不显示HEALTH OK是正常现象:
- 刚刚创建了池,PG 尚未完成 Peering;
- PG 正在恢复(recovering);
- 刚刚向集群添加或移除了 OSD;
- 刚刚修改了 CRUSH 地图,PG 正在迁移;
- PG 的不同副本之间存在不一致数据;
- Ceph 正在对 PG 的副本执行 scrub(清理/校验);
- Ceph 没有足够的存储容量完成背填(backfill)操作。
这些情形导致HEALTH WARN时不必恐慌,多数情况下集群会自行恢复;但某些情况下需要人工介入。监控 PG 的重点是检查其状态是否为active且clean:即集群运行时,所有 PG 都应处于active状态,且最好是clean。
查看每个 PG 的状态:
ceph pg stat输出格式为x pgs: y active+clean; z bytes data, aa MB used, bb GB / cc GB avail,含义:
| 字段 | 含义 |
|---|---|
x | PG 总数 |
y | 处于某特定状态(如active+clean)的 PG 数 |
z | 已存储的数据量 |
aa | 已使用的存储容量 |
bb | 剩余可用存储容量 |
cc | PG 总存储容量 |
注意:Ceph 经常为一个 PG 同时报告多个状态,例如
active+clean、active+clean+remapped、active+clean+scrubbing等。
容量信息(已用aa、剩余bb、总量cc)在以下场景中尤其重要:
- 集群正接近
near full ratio(接近满阈值)或full ratio(满阈值); - 由于 CRUSH 配置错误,数据未能在集群中均匀分布。
PG ID 的构成
PG ID 由池编号(注意是编号而非池名)加句点.加十六进制数组成。通过ceph osd lspools可查看池编号与池名的对应关系。例如第一个创建的池对应池编号1。完整的 PG ID 形式为:
{pool-num}.{pg-id}典型示例:
1.1701b查询 PG 的常用命令
列出所有 PG:
ceph pg dump以 JSON 格式输出并保存到文件:
ceph pg dump -o {filename} --format=json查询特定 PG 的详细信息(Ceph 以 JSON 格式输出):
ceph pg {poolnum}.{pg-id} query例如查询池1中 PG1701b的详情:ceph pg 1.1701b query。
常见 PG 状态详解
Ceph 在源码 src/osd/osd_types.h 中以位掩码定义了各 PG 状态(如PG_STATE_ACTIVE、PG_STATE_CLEAN、PG_STATE_DEGRADED、PG_STATE_RECOVERING、PG_STATE_BACKFILL_WAIT、PG_STATE_BACKFILLING、PG_STATE_INCOMPLETE、PG_STATE_STALE、PG_STATE_REMAPPED),多个状态位可同时置位,这正是active+clean、active+clean+remapped这类组合状态名称的由来。以下按 PG 生命周期逐个讲解。
Creating(创建中)
创建池时即创建 PG:创建池的命令会指定该池的 PG 总数,池创建后所有 PG 一并创建。创建期间 Ceph 会回显creating。PG 创建完成后,其 Acting Set 中的 OSD 开始 Peering;Peering 完成后,PG 状态应变为active+clean,此时 Ceph 客户端开始向该 PG 写入数据。
/-----------\ /-----------\ /-----------\ | Creating |------>| Peering |------>| Active | \-----------/ \-----------/ \-----------/Peering(对等中)
PG 对等时,存储其数据副本的 OSD 就 PG 内的数据与元数据收敛到一致状态。对等完成后,这些 OSD 对该 PG 的状态达成共识。但需要注意:对等过程完成并不意味着每个副本都已拥有最新内容。
关于**权威历史(Authoritative History)**的机制说明:
- 在 Acting Set 中每个 OSD 都持久化了某次写操作之前,Ceph 不会向客户端确认(acknowledge)该写操作。这保证了自上次成功对等以来,Acting Set 中至少有一个成员保留着每一次已确认写操作的记录。
- 凭借准确的已确认写操作记录,Ceph 可以构造出该 PG 的新的权威历史——即一整套完整且全序的操作序列,按序执行即可让某个 OSD 上的 PG 副本追上最新状态。
Active(活跃)
Ceph 完成对等后,PG 应变为active。active状态意味着该 PG 中的数据在 primary 和副本 OSD 上通常可进行读写操作。
Clean(干净)
PG 处于clean状态时,所有持有其数据与元数据的 OSD 都已成功对等,且不存在 stray(游离)副本;Ceph 已将该 PG 中的所有对象复制了正确次数。
Degraded(降级)
客户端向 primary OSD 写入对象后,primary 负责把副本写到副本 OSD。在 primary 将对象写入存储后,PG 会保持degraded状态,直到 primary 收到副本 OSD 确认成功创建副本对象的回执。
PG 可能处于active+degraded的原因:OSD 即使尚未持有 PG 的全部对象也可以保持active。若某 OSDdown,Ceph 会将该 OSD 上每个 PG 标记为degraded;该 OSD 恢复上线后,PG 必须重新对等。但只要 PG 是active的,客户端仍可向其写入新对象。
down到out的自动转换:若 OSDdown且degraded状态持续存在,Ceph 可能将该down的 OSD 标记为out,并把数据从它 remap 到其他 OSD。从标记down到标记out的时间由mon_osd_down_out_interval决定,默认600 秒(10 分钟)。在源码 src/common/options/mon.yaml.in 中该参数定义明确为 "mark any OSD 'out' that has been 'down' for this long (seconds)",默认值10_min,服务对象为 monitor。与之配合的还有mon_osd_down_out_subtree_limit(默认rack,即整个机架子树全挂时不自动标记 out)与mon_osd_min_up_ratio(up 比例过低时不自动标记 out),这些防御性参数可避免级联故障时 OSD 被批量踢出集群。
另一种进入degraded的途径:PG 中存在一个或多个 Ceph 期望找到却找不到的对象(unfound objects)。虽然无法读写这些 unfound 对象,但degradedPG 中的其他对象仍可正常访问。
Recovering(恢复中)
Ceph 天生为容错而设计,硬件与其他服务器问题被视作常态。当 OSDdown时,其内容可能落后于 PG 中其他副本的当前状态;OSD 回到up后,必须将 PG 内容更新到当前状态,此期间 OSD 可能处于recovering状态。
恢复并非总是轻而易举:一次硬件故障可能引发多个 OSD 的级联故障。例如某个机架或机柜的交换机故障,可能导致多台主机上的 OSD 同时落后于集群当前状态。此类场景下,只有每个 OSD 都在故障解除后恢复,整体恢复才可能完成。
Ceph 提供多个参数来权衡"处理新服务请求"与"恢复数据对象、把 PG 恢复到最新状态"之间的资源竞争:
| 参数 | 作用 | 默认值(源码依据) |
|---|---|---|
osd_recovery_delay_start | 允许 OSD 重启、重新对等、处理部分 replay 请求后再启动恢复 | 0(osd.yaml.in) |
osd_recovery_thread_timeout | 确定恢复线程的超时时长(多个 OSD 可能以交错速率失败、重启、重新对等) | 文档描述值 |
osd_recovery_max_active | 限制 OSD 同时处理的恢复请求数,防止 OSD 无法继续服务 | 0(非零才生效;实际按磁盘类型取 hdd/ssd 值,osd.yaml.in) |
osd_recovery_max_active_hdd | 机械盘(rotational)主设备 OSD 的同时恢复请求数 | 3(osd.yaml.in) |
osd_recovery_max_active_ssd | SSD(非旋转介质)主设备 OSD 的同时恢复请求数 | 10(osd.yaml.in) |
osd_recovery_max_chunk | 限制恢复数据块的大小,防止网络拥塞 | size 类型(osd.yaml.in) |
其中osd_recovery_max_active默认值为0,此时实际生效的是按主设备类型区分的osd_recovery_max_active_hdd/osd_recovery_max_active_ssd;只有显式设为非零值时才覆盖二者。另外注意:mClock 调度器激活时,这些恢复/背填上限通常不可修改(详见下文 Backfilling 一节的说明)。
Backfilling(背填)
新 OSD 加入集群时,CRUSH 会把集群中已有 OSD 上的 PG 重新分配给新 OSD。若强制新 OSD 立即接受被重新分配的 PG,会给它带来过大负载;backfill(背填)允许该过程在后台进行。背填完成后,新 OSD 一旦就绪即可开始服务请求。
背填期间可能看到的状态:
backfill_wait:背填操作已排队但尚未开始;backfilling:背填操作正在进行中;backfill_toofull:请求了背填但因存储容量不足无法完成。该状态可能是暂时性的——随着 PG 被搬移腾出空间,条件变化后即可继续,这与backfill_wait类似;- 当 PG 无法被背填时,可能被视为
incomplete(不完整)。
Ceph 提供多个参数管理 PG 重新分配(尤其是新 OSD)带来的负载尖峰:
| 参数 | 作用 | 默认值(源码依据) |
|---|---|---|
osd_max_backfills | 指定单个 OSD 并发背填(进/出)的最大数量 | 1(osd.yaml.in) |
backfill_full_ratio | OSD 接近 full ratio 时拒绝背填请求 | 90%,可用ceph osd set-backfillfull-ratio修改 |
osd_backfill_retry_interval | 背填被拒绝后的重试间隔 | 30秒(osd.yaml.in) |
osd_backfill_scan_min | 每次背填扫描的最小对象数 | 64(osd.yaml.in) |
osd_backfill_scan_max | 每次背填扫描的最大对象数 | 512(osd.yaml.in) |
关于osd_max_backfills与 mClock:若 mClock 调度器 处于激活状态,默认情况下不能修改osd_max_backfills(同理还有osd_recovery_max_active_hdd与osd_recovery_max_active_ssd),除非设置osd_mclock_override_recovery_settings = true——源码 osd.yaml.in 明确记录了这一限制。mClock 下的背填调优参见 mClock recovery/backfill 选项。
backfill_full_ratio命令存在于ceph osd set-backfillfull-ratio,在 src/mon/MonCommands.h 中定义,参数类型为CephFloat,取值范围0.0|1.0,语义为 "set usage ratio at which OSDs are marked too full to backfill"。
Remapped(重映射)
当服务某 PG 的 Acting Set 发生变化时,数据从旧 Acting Set 迁移到新 Acting Set。由于新 primary OSD 开始服务请求可能需要时间,旧 primary 可能被要求继续服务请求,直到 PG 数据迁移完成。数据迁移完成后,映射使用新 Acting Set 的 primary OSD。
Stale(陈旧)
Ceph 使用心跳(heartbeat)确保主机与守护进程在运行,但ceph-osd守护进程可能进入stuck(卡住)状态,无法及时上报统计信息(例如发生临时网络故障)。默认情况下,OSD 守护进程每0.5 秒上报一次 PG、up-through、boot 与失败统计,频率高于心跳阈值定义的报告间隔。若 PG 的 Acting Set 中 primary OSD 未能向 monitor 上报,或其它 OSD 已上报该 primarydown,monitor 就会将该 PG 标记为stale。
集群启动时看到stale状态很常见,直到对等过程完成。但集群运行一段时间后仍出现stale,则说明这些 PG 的 primary OSD 已down或未向 monitor 上报 PG 统计信息。
识别问题 PG:stuck 状态排查
如前所述,PG 状态不是active+clean并不代表一定有问题。但当 PG卡住(stuck)时,可能意味着 Ceph 无法执行自我修复。三种 stuck 状态:
| 状态 | 含义 |
|---|---|
| Unclean(不干净) | PG 包含未按期望次数复制的对象。正常情况下可假定这些 PG 正在恢复(recovering)。 |
| Inactive(不活跃) | PG 无法处理读写,因为它在等待持有最新数据的 OSD 回到up。 |
| Stale(陈旧) | PG 处于未知状态,因为托管它们的 OSD 在特定时间段(由mon_osd_report_timeout决定)内未向 monitor 集群上报。 |
mon_osd_report_timeout在源码 src/common/options/global.yaml.in 中的语义是"OSD 未向 mons 上报则被标记为 down 的宽限时间(秒)",默认值15_min(15 分钟),服务对象为 monitor。
识别卡住的 PG:
ceph pg dump_stuck [unclean|inactive|stale|undersized|degraded]更多背景参见 Placement Group 子系统(ceph pg命令总览)。stuck PG 的完整排查流程参见 failures-pg-stuck。
定位对象位置:从对象名到 PG 再到 OSD
要在 Ceph Object Store 中存储对象数据,Ceph 客户端必须:
- 设定对象名(object name);
- 指定一个池(pool)。
Ceph 客户端获取最新集群地图后,CRUSH 算法先计算如何把对象映射到 PG,再计算如何把 PG 动态分配到 OSD。仅凭对象名与池名即可定位对象:
ceph osd map {poolname} {object-name} [namespace]练习:定位一个对象
第一步,用rados put创建对象,指定对象名、测试文件路径与池名:
rados put {object-name} {file-path} --pool=data rados put test-object-1 testfile.txt --pool=data验证对象已存入 Ceph Object Store:
rados -p data ls定位对象的存放位置:
ceph osd map {pool-name} {object-name} ceph osd map data test-object-1Ceph 应输出对象位置,例如:
osdmap e537 pool 'data' (1) object 'test-object-1' -> pg 1.d1743484 (1.4) -> up ([0,1], p0) acting ([0,1], p0)该输出依次给出:osdmap epoch(e537)、池名与池编号('data' (1))、对象名、对象所属的 PG(完整 PG ID1.d1743484与短形式1.4)、以及该 PG 的 Up Set([0,1],primary 为p0)与 Acting Set([0,1],primary 为p0)。
清理测试对象:
rados rm test-object-1 --pool=data随着集群演进,对象位置可能动态变化。Ceph 动态再平衡的一大好处,就是省去了人工执行迁移的负担,相关机制详见 架构文档。这种"对象 → PG → OSD"的两级间接映射,也正是数据放置(data placement)的核心设计:数据不直接绑定到特定 OSD,因此故障时只需在 PG 与底层 OSD 层面追踪问题即可。
监控实战小结
把整套监控动作串成一条排查主线:
- 看全局:
ceph -s/ceph health/ceph -w,确认是否为HEALTH_OK之外的预期状态; - 查 OSD:
ceph osd stat对比in与up数量,ceph osd tree定位down的 OSD,必要时sudo systemctl start ceph-osd@N; - 查 PG:
ceph pg stat查看状态分布,ceph pg dump/ceph pg dump -o {file} --format=json导出明细,ceph pg {poolnum}.{pg-id} query深查单个 PG; - 找卡住的 PG:
ceph pg dump_stuck [unclean|inactive|stale|undersized|degraded],对照mon_osd_report_timeout(默认 15 分钟)与mon_osd_down_out_interval(默认 600 秒)等参数判断是"正在自我恢复"还是"需要人工介入"; - 定位对象:
ceph osd map {poolname} {object-name}把对象、PG、OSD 三层映射关系串起来,结合 troubleshooting-osd 与 troubleshooting-pg 进行根因分析。
理解 OSD 状态四象限、PG 生命周期状态机以及 Acting Set / Up Set 的含义,是读懂上述所有命令输出的基础。Ceph 是自修复系统,多数非HEALTH OK状态会随对等、恢复、背填的完成而自行消退;只有当 PG 长期 stuck、副本持续 degraded 或容量达到阈值时,才需要依据本文的参数调优与排查路径进行人工干预。
- 存储
- 分布式文件系统
- 对象存储
- 后端
- 高可用
【免费下载链接】ceph
Ceph is a distributed object, block, and file storage platform
相关推荐
Ceph RADOS 故障排查完全指南:从动态日志调试到 Monitor/OSD/PG 深度排障与性能剖析
Ceph RADOS 故障排查完全指南:从动态日志调试到 Monitor/OSD/PG 深度排障与性能剖析 本文基于 Ceph 官方 RADOS 故障排查文档体
存储分布式文件系统对象存储后端高可用Ceph 集群运维实战指南:启动、健康监控、数据放置与故障排查
Ceph 集群运维实战指南:启动、健康监控、数据放置与故障排查 Ceph 是分布式对象、块和文件存储平台,其集群运维工作分布在四个层次:以 systemd 启停
存储分布式文件系统对象存储后端高可用Rook Ceph 在 OpenShift 上的存储监控启用与故障排查指南
Rook Ceph 在 OpenShift 上的存储监控启用与故障排查指南 OpenShift 控制台(Storage Dashboard)依赖 OpenShi
云原生存储容器编排运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考