首页/系统与基础设施/存储速查/CRUSH 算法与数据放置规则
分布式与对象存储70 条

CRUSH 算法与数据放置规则

CRUSH 用一份层级化的 Map 加确定性哈希算出数据落在哪些 OSD 上,客户端与服务端各自计算即可,不需要中心元数据服务。权重表达容量差异,增删设备时只迁移受影响的归置组。本文说明其映射步骤、规则写法与变更风险。

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌​​‌‌‌​‌​‌​‌‌‌​​‌‌​‌‌​‌​​​​​‌​‌‌​‌​‌‌​​​​‌​‌‌​‌‌​​​‌‌​​‌‌‌​‌‌​‌‌‌‌​‌‌‌​​‌​​‌‌​‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌​‌​​‌​‌‌​‌​‌‌​​‌​​​‌‌​​​​‌​‌‌‌​‌​​​‌‌​​​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‌​‌‌​​​‌‌​‌‌​​‌​‌​‌‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

CRUSH 解决什么问题

CRUSH(Controlled Replication Under Scalable Hashing)用确定性的伪随机函数把归置组映射到 OSD 集合。所有客户端与 OSD 持有同一份 Map,各自算出相同结果,因此不需要一个中心节点记录数据位置。这个设计让集群扩展到数千块盘,并在增删设备时只迁移受影响的 PG。

基本信息

输入归置组编号、CRUSH Map(设备树与权重、规则)、tunables
两步映射对象名哈希到 PG,PG 经 CRUSH 选出 OSD 集合
选择算子take 选根,chooseleaf 按故障域选副本,emit 输出结果
默认算法较新版本的 bucket 算法默认 straw2
权重语义与容量成正比,通常 1TB 记 1.0
迁移特性增删设备按权重比例迁移,不做全量重分布

典型使用场景

  • 扩容前评估迁移量:按权重比例估算受影响的 PG 范围
  • 核对池的副本落点:比对规则中的故障域与实际设备树结构
  • 排除部分盘参与业务池:借助 device class 或独立规则限制
  • 排查分布不均:确认权重、规则与 PG 数量三者是否匹配
  • 评估机架级容灾能力:规则中的故障域是否已提升到机架

查阅与模拟分布

查阅与模拟分布
ceph osd getcrushmap -o /tmp/map.bin      # 导出二进制 Map
crushtool -d /tmp/map.bin -o /tmp/map.txt # 反编译为可读文本
crushtool -c /tmp/map.txt -o /tmp/map2.bin # 编译回二进制
crushtool -i /tmp/map.bin --test --show-utilization --min-x=0 --max-x=500  # 模拟分布
ceph osd crush rule dump                  # 查看现有规则定义
ceph osd crush rule create-replicated r-hdd default host hdd  # 建按主机故障域的副本规则

CRUSH 关键概念

概念含义配置要点
tunables控制哈希行为的兼容参数集集群内取值应统一,混用会造成分布不一致
bucket 算法同一层级内设备的选择算法straw2 分布最均匀,新集群保持默认即可
规则 ruleset从根到叶的选择路径规则决定池的落点,改规则会触发迁移
权重 weight设备承担数据的比例应与真实可用容量成正比
故障域副本不会落在同一域内默认按主机,多机架部署应提升到机架
crushtool 的模拟测试可以在不落地的情况下输出分布与使用率结果,是评估规则改动影响最省事的手段。任何涉及规则的变更,都建议先模拟再执行。
手工反编译再编译回 Map 时,任何语法或权重错误都会在应用后立刻影响全集群的数据分布,且回滚需要时间。变更前先导出当前 Map 备份,并安排在业务低峰执行。

权重比数量更重要

CRUSH 按权重而不是按设备数量分配数据。容量差异较大的盘混装时,如果权重被人为均分,小盘与大容量盘会承担同样多的 PG,容量利用率出现明显差距。正确做法是让权重与可用容量成正比,或用 device class 把不同介质分开承载不同池。

易错点

  • 权重与实际容量不符:容量小的盘先满而大盘空闲,长期处于近满告警
  • 手工改完 Map 不做语法与分布验证就应用:错误分布难以快速回滚,只能再改一次并承担二次迁移
  • 故障域留在默认主机级却以为是机架容灾:同一机架断电会同时影响同一 PG 的多个副本
  • 混用不同 tunables:部分客户端与 OSD 计算结果不一致,出现难以解释的数据迁移
  • 频繁调整权重:每次调整都触发迁移,连续调整等于让集群长期处于恢复状态

数据来源与参考

  • 论文《CRUSH: Controlled, Scalable, Decentralized Placement of Replicated Data》(SC 2006)
  • Ceph 官方文档《CRUSH Maps》章节
  • Ceph 官方文档《CRUSH 权重与放置规则》

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/storage/crush-algorithm-data-placement.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌​​‌‌‌​‌​‌​‌‌‌​​‌‌​‌‌​‌​​​​​‌​‌‌​‌​‌‌​​​​‌​‌‌​‌‌​​​‌‌​​‌‌‌​‌‌​‌‌‌‌​‌‌‌​​‌​​‌‌​‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌​‌​​‌​‌‌​‌​‌‌​​‌​​​‌‌​​​​‌​‌‌‌​‌​​​‌‌​​​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‌​‌‌​​​‌‌​‌‌​​‌​‌​‌‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌‌​‌​​​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​