介绍

Ceph 的 CRUSH 算法通过 CRUSH Map 计算数据存储位置来确定如何存储和检索,而不是通过一个中央服务器或经纪人来管理。这样避免了单点故障、性能瓶颈、和伸缩的物理限制等问题。

CRUSH 算法按照 CRUSH Map 把数据伪随机地、尽量平均地分布到整个集群的 OSD 里。定制 CRUSH Map 主要是为了:

  • 区分不同的存储介质
  • 定义故障域,根据机房中的物理架构来做数据高可用
  • 帮助机房定位故障位置

概念与结构

CRUSH Map 包含 OSD 列表、把设备汇聚为物理位置的 Bucket 列表、和指示 CRUSH 如何复制存储池里的数据的规则列表。

OSD 列表

为把 PG 映射到 OSD ,CRUSH 算法需要 CRUSH Map 里的 OSD 列表。要在 CRUSH Map 里声明一个设备,在设备列表后面新建一行,输入 device 、之后是唯一的数字 ID 、之后是相应的 ceph-osd 守护进程实例名字。

# devices
device 0 osd.0
device 1 osd.1
device 2 osd.2

Bucket

Bucket 表示一个物理的位置或者设备的类型。Bucket type 就是一类物理设备的位置或者类型,Bucket 实例就是里面的对象。

Bucket 类型通常自己定义。默认的 Bucket 类型如下表:

数值 类型 描述
0 OSD OSD 守护进程
1 Host 包含 OSD 的节点
2 Rack 包含机器的机架
3 Row 包含机架的节点列
4 Room 包含节点列的机房
5 Data center 包含机房的数据中心
6 Root Bucket 分层结构的根
Bucket 实例的组织形式是树状结构,每个 Bucket 类型是树中的一层:

为了区分存储介质类型 Bucket 实例的定义:

root -> unit -> mediagroup -> media -> ctnr
类型 描述
ctnr 实际的物理机的同种类型的存储介质
media 不同机柜的同类型存储
mediagroup 一种存储介质类型
unit 一个新集群
root Bucket 分层结构的根

CRUSH Map 的相关操作

获取 CRUSH Map

  1. 命令
root@ceph-node1:~# ceph osd tree
ID WEIGHT  TYPE NAME           UP/DOWN REWEIGHT PRIMARY-AFFINITY
-1 3.00000 root default
-2 1.00000     host ceph-node3
 0 1.00000         osd.0            up  1.00000          1.00000
-3 1.00000     host ceph-node2
 1 1.00000         osd.1            up  1.00000          1.00000
-4 1.00000     host ceph-node1
 2 1.00000         osd.2            up  1.00000          1.00000
  1. 反编译导出文件
ceph osd getcrushmap -o {compiled-crushmap-filename}
crushtool -d {compiled-crushmap-filename} -o {decompiled-crushmap-filename}

查看 {decompiled-crushmap-filename} 就可看到 CRUSH Map 内容

编辑 CRUSH Map

1、 命令

# 1 创建 bucket
     ceph osd crush add-bucket <bucket-name> <bucket-type>
# 2 移动 bucket
      ceph osd crush move <bucket-name> <bucket-type>=<bucket-name>

2、 编辑导出的文件

格式:

[bucket-type] [bucket-name] {
        id [a unique negative numeric ID]
        weight [the relative capacity/capability of the item(s)]
        alg [the bucket type: uniform | list | tree | straw ]
        hash [the hash type: 0 by default]
        item [item-name] weight [weight]
}

然后导入:

crushtool -c <crushmap-decompile> -o <crushmap-compiled>
ceph osd setcrushmap -i <crushmap-compiled>