☰
OSD不是硬盘:Ceph对象存储守护进程原理与排障实战
2026/10/3 1:27:31 网站建设 项目流程

第一次把 OSD 和一块物理磁盘混为一谈,是我刚开始接触 Ceph 时栽过的最大跟头。那时候我看文档里写“OSD 是 Ceph 的基本存储单元”,心里默认它就是一个硬盘,于是后面排障时各种自我怀疑——为什么我换了一块更大的盘,OSD 却没变大?为什么一个 OSD down 了,整个池子的数据要重新平衡?直到我把 OSD 理解成一个带状态、带计算、带网络通信能力的守护进程,而不是一颗螺丝钉,之前所有想不通的问题才串成了一条线。

这篇东西我不打算堆官方手册里的术语,只讲我多年实操 OSD 部署、排障、调优过程中保留下来的理解。适合刚接触 Ceph、总是把 OSD 和裸盘搞混的人,也适合那些集群已经跑起来、但遇到 down/恢复/性能问题不知道从哪里下手的运维。顺便把“对象存储”这个概念也揉进去讲清楚。

1. OSD 不能等同于一块磁盘:先把这个底层模型捋顺

1.1 OSD 是什么,它和磁盘是什么关系

OSD 的全称是 Object Storage Daemon,对象存储守护进程。它既是一个负责读写数据的服务进程,也是 Ceph 集群里最核心的存储组件。在 Ceph 里,一个 OSD 通常对应一块磁盘或一个逻辑卷,但它不是磁盘本身,而是运行在这块磁盘之上的管理进程。

为什么一个进程要单独对应一块盘?Ceph 的设计哲学是数据面和控制面分离:客户端不直接访问磁盘,而是通过 RADOS(Reliable Autonomic Distributed Object Store)这个自愈分布式对象存储层,把对象交给集群。OSD 就是这个 RADOS 层在每个存储节点上的具体执行者。每个 OSD 各自管理自己那块盘上的数据,同时定期向 Monitor 上报自己的状态,参与分布式数据分布和故障检测。如果只是“一块硬盘”,这些事谁来做呢?所以系统里必须存在一个软件层,这就是 OSD。

用生活中的例子打比方:一块磁盘像一个仓库库房,OSD 是管理这个库房的库管员。库管员负责收发货、登记库存、定时向总部汇报“我这个库房还活着”。Ceph 调度数据时,不是直接往哪个库房扔东西,而是找到对应库管员,库管员再把货放到自己管理的架子上。这就是“OSD 是基本存储单元”的真正含义——基本单元是管理员加上库房,而不是一个空房子。

1.2 对象、PG 和 OSD 的三角关系

讲 OSD 必然绕不开对象(Object)和归置组(Placement Group,PG)。Ceph 从客户端接收的数据,会先被切成默认 4MB(现在也常见 1MB 或按场景调整)的对象。这些对象通过 CRUSH 算法映射到一组 PG,每个 PG 再映射到一组 OSD 上。PG 是对象到 OSD 之间的中转层,它不是一个存储实体,而是一个逻辑容器,用于管理一组对象的副本分布和一致性。

我见过不少人问:既然有 OSD 就够了,为什么还要多一层 PG?这是因为如果不加 PG,每次写入一个对象,CRUSH 要直接在整个集群规模的 OSD 集合里计算副本位置,计算量太大且迁移范围不可控。加入 PG 后,对象先按哈希归到 PG,PG 的数量是固定的,CRUSH 只需要针对 PG 做映射。这相当于把对象的路由信息收敛成一张小表,数据再分散,查询和迁移的成本都可控。

如果用一句话串联:客户端写入对象 → 对象属于某个 PG → PG 分布到一组 OSD。任何一个 OSD 挂了,只影响一部分 PG,其他 PG 的读写完全不受干扰;OSD 恢复后,它管理的 PG 会通过 Peering(互相核对日志和元数据)流程自动找回数据。

这三者的关系直接决定了对“基本存储单元”的理解。Ceph 集群中,最小的数据迁移单位是 PG,最小的存储管理单位是 OSD,最小的数据对象是 Object。三者互相配合,才让 Ceph 能做到同一套集群既提供对象存储接口,也提供块设备和文件系统接口。很多人对 Ceph 的“对象存储”概念有误解,认为它只能做对象存储。实际上,RADOS 层本身就是对象存储,而上面的 RBD、CephFS、S3 网关都是在这个对象存储地基上给人不同的使用界面。

1.3 Ceph 为什么把 OSD 设计成一个进程而不是内核模块

这个点很多人不会去想,但它决定了运维方式。OSD 做成独立用户态进程,核心目的是隔离故障。一旦某个 OSD 因为底层逻辑卷异常、文件系统损坏或极端 IO 卡顿而崩溃,它只会影响自己管理的磁盘,不会拖垮整个操作系统或者同节点其他 OSD。这种进程级隔离,非常像现代微服务的设计思路。

反过来,这也带来一个新的运维要求:你必须像对待 Java 应用一样去监控 OSD 进程状态。系统里看到的ceph-osd进程,才是真正干活的东西。如果进程还在但磁盘已经有坏块,OSD 可能反复报错,却不会主动退出;如果进程退出了,Monitor 才会在心跳超时后把对应 OSD 标记为 down。所以排障时永远记得区分两层状态:进程状态和磁盘状态。后面故障排查那一节我再展开说。

2. OSD 内部构造与写入路径:理解它,才知道出错时去哪看

2.1 一次写入请求是怎么穿过 OSD 的

假设客户端要写一个对象。请求首先被 Ceph 客户端库计算出它属于哪个 PG,以及主 OSD 是哪个(Primary OSD)。Primary OSD 收到请求后,会同时做三件事:把数据写入自己的存储引擎,把日志发给同 PG 的副本 OSD,等待副本确认后向客户端返回成功。这个过程叫副本写入的 commit 语义。

在 OSD 内部,数据并不是简单 write 到一块裸盘。以现在主流的 Bluestore 存储引擎为例:对象的数据块会先被写入 Bluestore 自己管理的数据区,元数据(比如对象名到块位置的映射、扩展属性)被写入内置的 RocksDB,而 RocksDB 则放在 Bluestore 的单数块(WAL)和数据库分区里。这样做的好处是,数据部分可以是裸的 chunk,不经过本地文件系统,减少了 POSIX 文件系统带来的双重损耗;元数据则利用 LSM-Tree 的顺序写特性保证性能。

所以,一个 OSD 内部实际有三个“小房间”:

  • 数据区:存放对象主体内容,在 bluestore 管理下的 raw 块上以固定大小 chunk 分配;
  • WAL 区:预写日志,保证 crash 后元数据一致性;
  • DB 区:RocksDB 的 sst 文件,存元数据。

如果你用默认配置,这三者可以在同一块盘上按比例分配;如果性能敏感,建议 WAL 和 DB 放到 NVMe 盘,数据盘用普通 HDD。这个我们在部署选型小节里细说。

2.2 OSD 的三大日常职责

我在给团队做 Ceph 入门培训时,会把 OSD 的职责压缩成三件事:

  1. 处理 IO:响应客户端或同集群其他 OSD 发来的读写请求,执行数据写入、读取、删除、恢复等操作。
  2. 参与 Peering:当 PG 映射发生改变(OSD down/up、添加删除 OSD)时,PG 内的副本 OSD 需要协调各自的状态,选定权威日志(authoritative log),确定每个对象的最新版本。这个会话就叫 Peering。Peering 失败或者交错异常,是很多“卡在 peering”问题的根源。
  3. 心跳上报:每个 OSD 会向 Monitor 和相邻 OSD 发送心跳。Monitor 通过 OSD 的心跳判断节点存活;OSD 之间则互相感知网络状况,用于快速发现故障。OSD 还会周期性地向 Monitor 上报 PG 状态变化,比如 degraded、recovering 等。

这三个职责决定了你在查看ceph -s时看到的那些状态都有具体含义。平时最怕的不是某个 OSD down,而是 PG 出现peering、stale等中间态,因为那说明数据可用性已经处于危险的临界区。

2.3 OSD 目录结构和关键文件:排障时的地图

每个 OSD 在节点上会有一个数据目录,通常在/var/lib/ceph/osd/ceph-<osd_id>。如果你想快速确认一个 OSD 的细节,进去看这几个东西就够了:

  • fsid:集群 ID,如果这里的内容和你集群不一致,OSD 会拒绝启动。
  • ceph_fsid:也是集群标识,在早期版本里可能存在,作用类似。
  • bluefs目录:Bluestore 的元数据文件系统,里面包含 rocksdb 相关文件。
  • block:这是一个符号链接,指向 OSD 管理的 block device。
  • block.db、block.wal:如果替 WAL 和 DB 单独分配了设备,这里会有对应链接。

遇到 OSD 起不来,第一件事不是直接rm -rf,而是mount | grep确认数据盘是否已经挂载,再确认block链接指向的设备是否存在。很多人在初始化错误时把block.wal和block.db弄错成普通文件,导致 RocksDB 无法打开,OSD 一启动就疯狂报错退出。这个血的教训,我在第三节部署实操里还会特意重复一遍。

3. 部署 OSD 的选型与实操:从硬件到 ceph-volume 完整过一遍

3.1 硬件选择上最容易踩的坑

部署 OSD 并不是“插几块盘跑个命令”这么简单。先说硬件选型:

  • HDD 做主存储:现在推荐 7200 转企业级盘,千万避开 SMR(叠瓦式磁记录)盘。Ceph 的恢复和均衡会产生大量随机写,SMR 盘写入放大极其严重,用一段时间后性能会断崖式下跌。
  • SSD 做 WAL/DB:如果条件允许,给每个 OSD 分配一块独立的小容量 NVMe 或者高性能 SSD 放 WAL 和 DB。不要求大,几十 GB 的分区通常就够,但要保证低延迟。
  • 内存:Bluestore 会尽量利用内存做缓存,osd_memory_target默认是 4GB。一个节点上 OSD 数量越多,内存占用越高,规划时按“每 OSD 预留 4-5GB”起步比较稳。
  • 网络:OSD 之间的数据恢复流量会占满网络,推荐独立的管理网或者至少保证集群网络交换机有足够的缓冲。后面调优章节我会给具体建议。

很多人问要不要先做 RAID。我直接说结论:OSD 这一层不要做 RAID,尤其不要做 RAID5。Ceph 已经通过多副本实现了数据冗余,RAID 反而会把多个 OSD 变成一个大设备,丧失独立故障域。你真正需要的是直通模式(HBA/IT 模式)或每块盘做 RAID0,让上层看到一大块裸设备。Ceph 的并行恢复能力远比你依赖 RAID 卡计算的恢复能力要灵活。

3.2 为什么新版本必须用 ceph-volume

早期 Ceph 用ceph-disk初始化 OSD,它在每个盘上创建 GPT 分区并写入/etc/fstab的相应条目。但这个工具在自动化场景下越来越难用,原因有几个:分区标记容易残留、对 LVM 支持差、启动顺序不友好。所以从 Nautilus 开始官方就强烈推荐ceph-volume。

ceph-volume的厉害之处在于它基于 LVM 管理 OSD。你不需要手动操心分区表和固定 device 路径,它可以创建 lvm 卷组、逻辑卷,并将逻辑卷名、卷组名和 OSD ID 绑定。这样做的好处是换一块盘或者重新挂载时,只要 lvm 元数据还在,就能把 OSD 识别回来,不会因为/dev/sdb被系统重新排序而找不到盘。

还有一个隐藏原因:ceph-volume会为 OSD 生成必要的 systemd 单元,并正确配置ceph-osd@<id>服务。以后你重启机器,OSD 会自动按ceph-<fsid>.service启起来,不用你手工mount。

3.3 加一个 OSD 的完整操作

假设已经有一个运行正常的 Ceph 集群,新节点已经装好 ceph-common,并且已经加入集群。要加一个新 OSD,通常执行:

# 建议先看磁盘现状,确认没有被占用 lsblk lvmdiskscan # 初始化 OSD,这里使用 lvm 模式 ceph-volume lvm create --data /dev/sdb # 验证 OSD 是否创建成功并加入集群 ceph osd tree | grep -A 1 hostname ceph -s

如果数据盘是一块新盘,没有文件系统,这个命令会直接创建 OSD。如果手动分过区,建议先wipefs -a /dev/sdb清掉所有旧签名,否则ceph-volume会提示设备已被占用,拒绝继续。这是我实际工作中遇到最多的初始化失败原因之一。

如果你想给 WAL 和 DB 指定单独的 SSD,则命令会变长:

ceph-volume lvm create \ --data /dev/sdb \ --block.db /dev/nvme0n1p1 \ --block.wal /dev/nvme0n1p2

这里有个小经验:block.db和block.wal不一定都要单独给。如果你的数据盘本身是 NVMe 或高性能 SSD,重复给 WAL/DB 单独分配设备意义不大,反而浪费盘位。一般只在“数据盘是 HDD,缓存盘是 SSD/NVMe”的混插架构下才做这层优化。

3.4 OSD 数量和 PG 数量怎么定

OSD 数量直接决定集群的并行恢复能力和峰值带宽,但它和容量不是简单的线性关系。通常建议每块物理盘只做一个 OSD,即便是大容量高密度盘也不要再拆多个 OSD,拆开反而单一 OSD 故障影响面更大。

PG 数量估算有公式,推荐值大概是:

PG总数 ≈ (OSD总数 × 100) / 副本数

比如 12 个 OSD、每 PG 三副本,那么 PG 总数≈400。但这只是估算,实际操作中还要看 pool 数量。Ceph 的 PG 总数是所有 pool 的 PG 之和,如果 400 个 PG 分布到 10 个 pool 里,每个 pool 可以用 40 个 PG。PG 过少会导致单个 PG 管理的数据太多,恢复慢;过多则增加 OSD 端的内存开销和 peering 负担。设置 pool 时使用pg_num和pgp_num,pgp_num控制 PG 在 OSD 上的分布权重,两者建议保持一致,否则会出现数据分布不均的假象。

4. 日常运维:OSD 状态、摘除替换与不丢数据的注意事项

4.1 用望闻问切看 OSD 健康

老运维运维 Ceph 基本不迷信 Dashboard 的彩色图标,ceph -s才是宇宙中心。健康集群最典型的样子:

cluster: id: xxxx health: HEALTH_OK services: mon: 3 daemons, quorum a,b,c mgr: 1 daemons osd: 12 osds: 12 up, 12 in

这里12 up, 12 in就是 OSD 的两大状态。up表示 OSD 守护进程活着且能上报心跳;in表示 OSD 已纳入集群 CRUSH 映射,会被分配 PG。理解up/in的区别特别重要:一个down但in的 OSD,系统会认为它还有数据,会立即启动恢复流程把 PG 以 degraded 状态重建副本;一个up但out的 OSD,系统不会给它分配新的 PG,适合做主动维护。

再往前一步,ceph osd tree能看到每个 OSD 的weight和所属 host 或 rack。权重默认是磁盘容量(TB 数),它决定了 CRUSH 映射里 OSD 被选中的概率。手工改小某个 OSD 的 weight,可以让它慢慢把数据迁移走,这比直接停机更好用。

4.2 安全的摘除一个 OSD:out → drain → destroy

日常运维中,经常要替换坏盘或退役旧机器。我推荐这个序列:

# 1. 先把 OSD 置为 out,它就不再接受新 PG,但已有 PG 还留着 ceph osd out osd.5 # 2. 等待数据排空,此时 PG 会自动重新均衡到其他 OSD # 观察 ceph -s 里的 recovery 状态,等它回到 HEALTH_OK watch ceph -s # 3. 确认已经没有 PG 在这个 OSD 上,再停止服务 ceph osd stop osd.5 # 或 systemctl stop ceph-osd@5 # 4. 从 CRUSH 图中删除 OSD,再删除认证等记录 ceph osd crush remove osd.5 ceph osd rm osd.5 ceph auth del osd.5

这里最容易出问题的就是第二步没等完就开始停服务。如果 OSD 上还有 PG,强行停掉会导致其他 PG 进入 degraded 状态,恢复路径上又多一个故障节点,整体风险成倍上升。心急吃不了热豆腐,Ceph 的迁移就是这样——你必须等它把数据搬完,才能做下一步。

另外,如果你的ceph-volume部署的 OSD 要彻底清理盘上的 lvm 卷,可以在停掉服务后用:

ceph-volume lvm zap /dev/sdb

这个命令会清空盘上的文件系统、分区和 lvm 卷,确保这块盘可以被重新初始化使用。不过务必要小心:它会无条件销毁盘上数据,操作前再确认一次你选中的设备是真的废弃盘,而不是还有数据在里面的盘。

4.3 调整权重与 reweight:数据均衡的隐形开关

本小节内容是很多人忽略的。Ceph 的 CRUSH 算法不是根据实际使用率实时调度,它是基于 weight 概率分布。如果一段时间后某些 OSD 容量使用率比其他 OSD 明显偏高,可以用ceph osd reweight做临时调平,比如:

ceph osd reweight osd.5 0.8

注意reweight只有 0 到 1 的小数区间,它把所有 PG 从指定 OSD 搬离的概率放大,让部分 PG 迁移到别的 OSD。这个操作比直接改 CRUSH weight 要轻量,适合临时调平。但不要把它当成长期方案,长期负载不均是写入倾斜引起的,应该从 pool、客户端 IO 模型或 CRUSH map 的 fault domain 入手解决。

标签操作也值得提一句。可以用ceph osd crush move或给 OSD 打 class:

ceph osd crush set-device-class hdd osd.0 osd.1

这样可以把盘类型信息传入 CRUSH,让不同性能的盘天然承担不同性质的 pool。比如对随机读写敏感的 MySQL 块设备池可以指定 NVMe 设备 class,把备份类的对象存储池放到 HDD 的 OSD 上。这是生产集群做到分级存储的基础。

5. OSD 故障排查实录:那些真正让我熬夜的问题

5.1 OSD down 最常见的几个触发点

先说结论,最近几年我遇到的 OSD down 原因,按概率排大概是:节点内存不足引发 OOM 杀掉 OSD、数据盘 IO 错误或卡死、网络抖动导致心跳超时、kernel 升级后的驱动不能正常识别 NVMe、磁盘控制器/RAID 卡策略异常。这些都指向同一个特点:Ceph 对底层稳定性极度敏感,因为 OSD 之间做的是强一致的复制协议,任何一个节点的心跳中断都会立刻拉响恢复流程。

一个典型的例子:某次集群每天晚上 2 点就有一个 OSD down,白天又自动 up。最后查下来是那个节点的内存只有 16GB,但部署了 4 个 OSD,还有一堆其他容器,凌晨任务高峰触发 OOM,把ceph-osd进程杀了。所以看到 OSD down,不要急着重装,先journalctl -u ceph-osd@4 --since today看看是不是 OOM 或被 systemd 杀掉。

5.2 排查链路:从进程到磁盘,一层一层剥

我自己总结了一套排查链路,遇到 OSD down 直接按顺序走:

  1. 先看集群层面异常:
    ceph health detail ceph osd tree | grep down ceph pg dump_stuck inactive,unclean
  2. 再上到故障节点,看 OSD 服务状态:
    systemctl status ceph-osd@5 journalctl -u ceph-osd@5 -n 200
  3. 如果日志里出现bluestore相关 IO 错误,立刻查磁盘:
    dmesg -T | tail -100 smartctl -a /dev/sdb lsblk
  4. 如果磁盘没问题,再看 OSD 进程是否假死:
    ceph daemon osd.5 status ceph daemon osd.5 perf dump
    ceph daemon命令能直接和 OSD 内部通信,拿到心跳、peering、op 处理延迟等指标,很多时候比top更直接。

这一套链路里最容易犯的错是:在第一步还没完成时就直接对故障 OSD 做ceph osd out和systemctl stop。你还没搞清楚它是网络问题还是磁盘问题,就把它摘出集群,会让集群陷入不必要的恢复风暴。当然,如果 OSD 已经反复crash且数据有风险,该摘就摘,不要因噎废食。

一个关于排障的小认识:OSD 的日志远比ceph -s的输出诚实。比如ceph -s只显示osd.5 is down,但日志会告诉你到底是bluestore write error、还是heartbeat timeout、还是failed to load bluestore。做运维不能只看聚合状态,更要看单独的服务日志。

5.3 一直卡在 peering 的 PG 怎么救

PG 卡在 peering,是我觉得比 OSD down 更麻烦的问题,因为它意味着这个 PG 里的数据目前无法同时提供多副本一致性。出现peering或peered状态时,第一步要做的是找到无法完成 peering 的具体原因。

ceph pg 1.2 query

这条命令会输出这个 PG 的完整状态,包括参与 peering 的 OSD 列表、各自的状态、历史事件。如果某个副本 OSD 已经彻底丢失(比如盘坏了),而 PG 配置为三副本,此时可能永远无法完成 peering,因为缺少法定人数。你可以先看看能不能把坏副本先从集群中排除:

ceph osd out osd.7

坏盘 OSD 一旦 out,PG 会尝试在剩余的副本里选出最大权威日志,如果剩余副本仍然满足可用状态,就会进入 degraded+peered 状态,这时候还是能继续提供读写。但数据仍然是单副本或两副本状态,风险比较大,需要尽快添加新 OSD 进行恢复。

我曾遇到一个极端场景:一个三副本池,其中一个 OSD 因为机器关机而 down,接着另一个 OSD 在恢复过程中因为磁盘 SMART 报错也 down 了,导致部分 PG 只剩一个在线副本,卡在了incomplete。这个时候别慌,先把两个 down 的 OSD 尽量起回来一个(哪怕它只是能读),利用ceph-objectstore-tool检查本地对象是否完整,实在不行考虑从只剩的那份副本强制标记为使用中。这个操作用到ceph pg force_create_pg或更变态的reset_pg,都有数据丢失风险,必须在明确备份和业务侧确认后才做。记住一个原则:宁可让 PG 卡着,也别在情况未明时乱执行破坏性命令。

5.4 替换坏盘之后,新的 OSD 为什么起不来

替换坏盘是个高频操作,新手最容易在以下环节卡住。盘换好后,插回原槽位,如果 OSD ID 还保留在集群中,你用ceph-volume lvm create --data /dev/sdb初始化,会因为旧的 OSD 记录还未删除而撞车。

正确做法是先按 4.2 节的删除流程把旧 OSD 从集群里摘干净,再zap清理磁盘,然后create。如果系统里已存在/var/lib/ceph/osd/ceph-<id>目录,初始化后新 OSD 可能拿到新的 ID,目录名会出现混乱,建议先停掉旧的 systemd 服务再清理。

另外新盘如果容量比旧盘大,weight 会自动比旧盘高。如果集群里其他 OSD 是 4TB,你换了一块 8TB 盘,那么这个 OSD 会分到远超其他盘的 PG,造成严重不均衡。此时用ceph osd crush reweight把它 weight 调整到和其他盘一致,等以后扩容时再整体调整。

6. 让 OSD 跑得又快又稳:参数调优和集群规划心得

6.1 内存与缓存配置,别让 OSD 饿死也别让它吃撑

Bluestore 时代最重要的一个参数是osd_memory_target。它的默认值是 4GB,含义是内核尽量让 OSD 进程的 RSS 保持在 4GB 左右。如果你的宿主节点有 64GB 内存,部署 8 个 OSD,每个 OSD 4GB 就已经 32GB,这还不算 page cache 消耗。我建议在节点内存足够的情况下,把目标值适当提高:

ceph config set osd osd_memory_target 8G

但这不意味着越大越好。内存调得过大,OSD 会抢占 Page Cache 和文件系统缓存,反而可能影响其他进程。建议先观察实际负载,在ceph daemon osd.x perf dump里看bluestore的缓存命中相关指标,如果命中率已经很高,再加大内存收益就很有限。

另一个值得关注的是bluestore_cache_size_hint,它告诉 Bluestore 预期缓存大小,通常与osd_memory_target配合设置。但如果两个参数冲突,会以更具体的那一个为准。大部分场景下只调整osd_memory_target就够了,你不需要手动去改底层每一个 cache 参数。

6.2 网络规划:数据、恢复、公网要分开思路

一个 Ceph 集群的流量大致可以分成三类:客户端到 OSD 的数据流量、OSD 之间副本同步流量、OSD 之间恢复/均衡流量。很多人图省事只用一个集群网络,高峰期一有大量数据写入,恢复流量就会和正常 IO 抢带宽,客户端延迟瞬间飙升。

规划网络时,我建议至少把集群网络单独划出来,物理上或 VLAN 隔离都行。用两个万兆网口做 bond,并指定cluster_network给 Ceph 使用:

ceph config set global cluster_network 10.10.20.0/24 ceph config set global public_network 10.10.10.0/24

public_network承载客户端访问和 Monitor 心跳,cluster_network承载 OSD 之间数据复制。这样恢复流基本不会打满公网口,客户端延迟受到的影响能控制在一个可接受范围内。这个是我实测对比过最有价值的一个网络优化。

另外,OSD 之间的对等网络质量要稳定。Ceph 默认的心跳超时受mon_osd_report_timeout和网络延迟影响,虽然不建议把心跳超时调得太大,但如果有跨机柜的网络抖动,可以考虑把osd_heartbeat_grace适当放宽,避免一次小抖动就触发大量 PG 迁移。

6.3 恢复速度如何控制,不把集群拖垮

数据恢复是 Ceph 高可用性的直接体现,但恢复过程也是最消耗资源的时候。默认参数往往偏激进,在混用集群里容易导致业务 IO 抖动。我一般会做如下调优:

# 限制恢复操作与客户端操作的资源争抢 ceph config set osd osd_max_backfills 2 ceph config set osd osd_recovery_max_active 3 ceph config set osd osd_recovery_op_priority 3

osd_max_backfills控制一个 OSD 同时参与多少个 PG 的 backfill,osd_recovery_op_priority是恢复操作的优先级,数值越低越不占资源。如果你希望系统快速恢复,可以把backfills提高到 4 甚至 8,但这会让业务延迟明显上升。生产环境我建议保守一点:优先保证在线业务的可用性,恢复慢一点没关系,不要为了追上日报数据导致业务用户全部投诉。

6.4 定期检查的几个细节点

最后分享几个我长期巡检 OSD 时会看的细节:

  • ceph osd df看每个 OSD 的容量使用情况,出现FULL会比down更麻烦,写操作会直接卡住。
  • ceph osd tree看故障域是否真正分散,别让同一个 JBOD 或同一台宿主上的 OSD 都承载同一个 pool 的副本,否则一断电就全没了。
  • smartctl -l error /dev/sdX定期扫一遍坏盘前兆,尤其在读到的日志里频繁出现 ATA error 时。
  • ceph pg dump对比 stale PG 数量,如果异常增长,优先检查 OSD 之间网络延迟和时钟同步。

时钟同步在这个环境里也很重要。OSD 之间的 Peering 和心跳对时间敏感,chrony 必须配好。很多人不知道,其实 Ceph 的时间容错本来不算太苛刻,但如果节点间时钟偏差大于几百毫秒,可能出现clock skew警告,导致 OSD 状态误判。

我个人的体会是,Ceph 的 OSD 像是一个既独立又协作的“库管团队”,它不算聪明,但对纪律要求极高:磁盘整洁、网络稳定、内存得当、时间一致。只要按这些原则去对待它,它就能在很长一段时间里稳定运行,而一旦你忽视这些基础细节,故障就会集中像连坐一样爆发。

如果你正准备搭第一个 Ceph 测试环境,我建议从 3 节点、每节点 2 个 OSD 开始,强制自己走完初始化、写对象、调整 PG、拔盘模拟故障、恢复数据这一整套流程。不用急着上大规模集群,等你对 OSD 这几个状态和日志熟悉了,再把规模化后的网络和成本问题提上议程。Ceph 的底层耐心学透了,后面无论是对象存储、块存储还是文件系统,都只是换一层接口的问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询