客户端读写流程
Ceph 的读写流程之所以高效,是因为客户端(Client)承担了大部分计算工作,直接与数据节点通信,无需任何中心服务器转发数据。整个过程可以概括为“问路、计算、直连”三步。
1. 问路:获取集群地图
当客户端(如一个挂载了 RBD 的虚拟机)首次启动或需要读写数据时,它做的第一件事是连接 Ceph 集群的“大脑”——Monitor (MON) 节点。
- 目的:获取最新的集群地图(Cluster Map)。这张地图包含了集群的完整拓扑结构,如所有 OSD 的状态、CRUSH 规则、PG 与 OSD 的映射关系等。
- 结果:客户端拿到地图后,就拥有了在集群中“导航”的能力,后续的操作不再需要打扰 Monitor。
2. 计算:定位数据位置
拿到地图后,客户端会根据要读写的对象名称(Object Name),通过一个两步计算过程,精确地定位到数据应该存放在哪个 OSD 上。这个过程完全在客户端本地完成。
- 第一步:对象 → PG (归置组)
客户端对对象名进行哈希运算,然后对存储池的 PG 总数取模,从而确定该对象属于哪个 PG。
PG ID = hash(Object Name) % PG总数
这一步将海量对象聚合成数量可控的 PG,大大简化了管理。 - 第二步:PG → OSD (存储守护进程)
客户端将上一步得到的 PG ID 代入 CRUSH 算法,并结合集群地图中的物理拓扑信息,计算出这个 PG 由哪一组 OSD 负责存储(通常是一个主 OSD 和多个副本 OSD)。
CRUSH(PG ID) → [Primary OSD, Replica OSD 1, Replica OSD 2, ...]
通过这两步计算,客户端就拿到了数据的最终物理位置。
3. 直连:执行读写操作
定位完成后,客户端直接与计算出的 Primary OSD 建立连接,发起读写请求。
- 写操作:
- 客户端将数据发送给 Primary OSD。
- Primary OSD 负责将数据并行复制给其他副本 OSD。
- 只有当所有副本都成功写入并返回确认后,Primary OSD 才会向客户端返回“写入成功”。这保证了数据的强一致性。
- 读操作:
- 客户端直接向 Primary OSD 请求数据。
- Primary OSD 从本地磁盘读取数据并返回给客户端。如果 Primary OSD 故障,客户端可以从其他副本 OSD 读取。
核心优势:整个流程中,Monitor 仅在开始时提供地图,不参与任何实际数据的传输。这种去中心化的设计避免了性能瓶颈,使得 Ceph 的性能可以随着节点增加而线性扩展。
存储引擎:BlueStore
OSD 负责将数据真正持久化到物理磁盘上。在现代 Ceph 版本中,默认的存储引擎是 BlueStore,它取代了早期的 FileStore,带来了巨大的性能提升。
BlueStore 的核心设计
BlueStore 的最大特点是绕过文件系统,直接管理裸磁盘。它不再将对象存储为 XFS 或 EXT4 上的文件,而是直接将数据写入原始块设备,从而消除了文件系统的开销。
为了实现高性能,BlueStore 巧妙地将数据分离存储:
| 组件 | 存储介质 | 存储内容 | 作用 |
|---|---|---|---|
| WAL (Write-Ahead Log) | SSD/NVMe | 待写入的数据和元数据 | 充当高速写缓冲。写操作先快速写入 WAL,立即返回成功,保证低延迟。 |
| DB (Metadata DB) | SSD/NVMe | 对象的元数据(如属性、位置) | 使用 RocksDB 存储。元数据操作非常频繁,放在 SSD 上能极大提升性能。 |
| Data | HDD/SSD | 实际的对象数据 | 数据主体。由于 WAL 和 DB 已经处理了大部分 IO,数据盘的压力大大减轻。 |
BlueStore 的工作流程
- 写入:当 OSD 收到写请求时,它会将数据和元数据先写入高速的 WAL 和 DB(通常在 SSD 上)。这个操作非常快,完成后即可向客户端返回成功。
- 异步落盘:在后台,BlueStore 会异步地将 WAL 中的数据整理并写入到容量更大的 Data 区域(通常在 HDD 上)。
- 读取:读取时,BlueStore 会先查 DB 找到数据的位置,然后直接从 Data 区域读取。
性能优势:
- 低延迟:利用 SSD 的 WAL 和 DB,极大地加速了写入和元数据操作。
- 高吞吐:直接管理裸盘,避免了文件系统层的开销。
- 纠删码友好:BlueStore 原生支持纠删码,能更高效地处理 EC 池的读写。
