跳转到内容

Ceph — 让分布式文件系统不靠中心查表

是什么

Ceph 是一套能扩到上千台机器的分布式存储。和它前辈最大的不同是:没有中央查询表

日常类比:传统快递公司有一本”包裹去哪”的总账本——每件货来都要去柜台问,柜台一忙整个网络就堵。Ceph 的做法是:发一张地图 + 一个公式给所有快递员,每个人自己算包裹该送到哪个仓库。算法叫 CRUSH,地图叫 cluster map

底层叫 RADOS:一群有 CPU 的”智能磁盘”,自己复制、自己心跳、自己再平衡,不靠总部派活。文件系统接口(CephFS)只是 RADOS 之上一层。

为什么重要

Google File System(2003)让大家信”分布式文件系统能搞定 PB 级”。但 GFS 有个单 master——元数据全在它的内存里,扩到一定规模就撞天花板。Lustre / PVFS 也都有”放置表要查询”的瓶颈。

Ceph 2006 第一次把三件事一起做掉:

  • 元数据服务器 集群化(多 MDS 分管子树)
  • 数据放置 算而非查(CRUSH)
  • 存储节点 自治(OSD 间自己复制和恢复)

今天 OpenStack、Kubernetes(Rook)、很多私有云的存储后端都是 Ceph。S3 / OSS 这类公有云对象存储的设计哲学也受它影响——把决策搬到能本地算的地方

核心要点

Ceph 三层结构,从底往上看:

  1. RADOS(Reliable Autonomic Distributed Object Store):一堆 OSD 进程 + 少量 monitor。OSD 存对象,monitor 用 Paxos 维护 cluster map(谁活着、权重多少、拓扑长啥样)。OSD 之间自己心跳、自己复制、自己迁移。

  2. CRUSH(Controlled Replication Under Scalable Hashing):一个确定性函数。输入”对象 ID + cluster map + 副本数”,输出”该放哪几台 OSD”。客户端、OSD、MDS 都本地算,没人需要查表

  3. MDS(Metadata Server)集群:管命名空间(目录、权限、inode),但不在 IO 路径上——客户端拿到 inode 后直接和 OSD 谈。MDS 之间用动态子树分区协作,热点目录自动迁移分裂。

关键的两层间接:对象 → placement group(PG)→ OSD 列表。中间塞个 PG 是为了让”对象数量”和”OSD 数量”解耦——加机器只动 PG→OSD 的映射,不用动数十亿对象。

CRUSH 怎么算

不是哈希环(很多人误会)。它是基于树的加权随机选择

root
├─ rack1 (weight 100)
│ ├─ host1 (weight 50)
│ │ ├─ osd.1
│ │ └─ osd.2
│ └─ host2 ...
└─ rack2 ...

算法:从根开始,按子节点权重做”伪随机抽签”(哈希函数 + 权重),递归到叶子(OSD)。要 3 个副本就走 3 次,但加规则约束(如”3 个副本必须在 3 个不同机架”)。

性质

  • 确定性:同样输入→同样输出,所有节点本地算结果一致
  • 稳定性:加一台机器,只有那一台周边的对象需要迁移(不像普通哈希全部重洗)
  • 拓扑感知:能表达”跨机架副本”这种容灾约束

实践案例

案例 1:写一个对象走的路

客户端要写文件 /data/foo.txt 的第 0~4MB:

  1. 问 MDS 拿 inode(一次,缓存住)
  2. 算对象 ID = inode + offset/4MB
  3. 本地 CRUSH 算出该对象的 3 个 OSD(主 + 两个副本)
  4. 把数据发给主 OSD
  5. 主 OSD 转发副本,全部回执后告诉客户端”成功”

整个过程只有第 1 步问了 MDS,之后纯客户端算 + OSD 写。几百万次 IO 也只问一次元数据。

案例 2:故障了发生什么

一台 OSD 挂了:

  1. 邻居 OSD 心跳失败,告诉 monitor
  2. monitor 用 Paxos 出新版 cluster map(标这台 down)
  3. 新 map 推给所有节点
  4. 所有节点本地 CRUSH 重算:受影响的 PG 算出新副本位置
  5. 那些 PG 的健康副本自己把数据复制到新位置

没有中央调度器决定”谁迁到哪”,每个 OSD 都能自己算。

案例 3:多 MDS 怎么分工

10 个 MDS,命名空间是 /。开始 MDS-A 管全部。/data/hot/ 突然变热点:

  1. MDS-A 检测到那个子树负载高
  2. /data/hot/ 这棵子树的”管理权”切给 MDS-B
  3. 客户端下次访问 /data/hot/foo,MDS-A 转告”去找 MDS-B”

这叫 dynamic subtree partitioning。比”按文件名哈希分”更好——因为目录访问通常有局部性,按子树切能保留局部性。

踩过的坑

  1. CRUSH 不是 consistent hashing:很多人以为 Ceph = DHT。其实 CRUSH 是基于树 + 加权的随机选择,比 consistent hashing 更能表达拓扑约束(机架/机房/电源域)。

  2. monitor 不在 IO 路径上:monitor 只发 cluster map(数 KB 的小东西,不常变)。IO 全走 OSD,不经过 monitor。把 monitor 误当 master 是常见误解。

  3. Ceph ≠ CephFS:Ceph 是个三件套——RADOS(底层对象) + RBD(块设备) + CephFS(文件系统)。生产里很多人只用 RBD(给 KVM 当虚拟磁盘)或对象网关(RGW,兼容 S3),不碰文件系统层。

  4. CRUSH 不保证完美均匀:权重设错或拓扑不对称时会出现冷热不均,要靠 reweight 和 upmap 微调。

  5. 小文件高并发是软肋:每个文件至少一份元数据,MDS 在百万级小文件 + 高并发下仍是瓶颈。极端小文件场景对象存储(RGW)比 CephFS 更合适。

适用 vs 不适用

适用

  • 私有云 / 混合云的统一存储后端(块 + 对象 + 文件三合一)
  • 容灾要求高(跨机架/跨机房副本规则用 CRUSH 直接表达)
  • 集群规模会持续增长(CRUSH 让扩容只迁必要数据)
  • OpenStack / Kubernetes 持久卷后端

不适用

  • 极小集群(< 5 台)—— monitor 和 MDS 的复杂度不划算
  • 极端小文件 + 极高并发 —— MDS 路径太重
  • 需要严格强一致 + 跨地域 —— 跨 WAN 的 monitor quorum 延迟受不了
  • 单机性能优先 —— 本地文件系统更快

历史小故事(可跳过)

  • 2003 年:GFS 论文出,证明分布式文件系统可行,但单 master 设计被广泛诟病
  • 2004 年:Sage Weil 在 UCSC 读博,导师是 Scott Brandt 和 Ethan Miller。他的目标是 PB 级 + 多 PB 级科学计算存储
  • 2006 年:CRUSH 单独发在 SC 2006,Ceph 整体发在 OSDI 2006。同年同会议还有 BigTable
  • 2007 年:Sage 博士论文给出完整 Ceph 设计 + 实现
  • 2010 年:Ceph 进 Linux 内核(CephFS 客户端)
  • 2014 年:Red Hat 收购 Inktank(Sage 创立的公司),Ceph 成 RHEL 主推存储
  • 2020 年代:Crimson 项目用 SeaStar 重写 OSD,针对 NVMe + 多核

学到什么

  1. 决策能本地算就别远程查:CRUSH 把”放置决策”从”查表”变成”算函数”,省掉一个潜在瓶颈
  2. 两层间接是好朋友:对象 → PG → OSD 让”对象数”和”机器数”解耦,扩容只动一层映射
  3. 节点自治胜过中心调度:OSD 间自己心跳、自己复制、自己再平衡,monitor 只发地图,主路径上没有热点
  4. POSIX 是承诺也是包袱:要支持完整 POSIX 的多 MDS 协作很复杂,纯对象存储(RGW、S3)可以更简单更快

延伸阅读

  • 论文 PDF:Ceph OSDI 2006(14 页,主战场是 §4 CRUSH 和 §5 RADOS)
  • CRUSH 专论:Weil et al., SC 2006(更细的算法 + 权重证明)
  • Sage Weil 博士论文:Ceph (UCSC 2007)(240 页全集)
  • 官方文档:docs.ceph.com(架构、部署、调优)
  • 工程入门:《Learning Ceph》Karan Singh(生产视角)
  • gfs-2003 —— Google File System,Ceph 的对照参照
  • bigtable-2006 —— 同年同会议的另一篇存储经典

关联

  • gfs-2003 —— Ceph 显式对照 GFS,把单 master 拆成多 MDS
  • brewer-cap-2000 —— Ceph 在副本一致性上偏 CP(强一致 + 分区时不可用)
  • chord-2001 —— DHT 思想是 CRUSH 的远亲,但 CRUSH 用树而非环
  • paxos-lamport —— monitor 用 Paxos 维护 cluster map quorum
  • bigtable-2006 —— 同期分布式存储设计参照

反向链接

  • bigtable-2006 —— Bigtable 2006 — Google 把行级随机读写做到 PB 级的存储系统
  • brewer-cap-2000 —— Brewer CAP — 网络一断电,一致性和可用性只能留一个
  • chord-2001 —— Chord — 让上万台机器排成圈,查任何 key 都只走 log N 步