侧边栏壁纸
博主头像
张种恩博主等级

一个能运维的 JPG 搬运工

  • 累计撰写 694 篇文章
  • 累计创建 58 个标签
  • 累计收到 17 条评论

Ceph Crush 进阶

张种恩
2021-12-21 / 0 评论 / 0 点赞 / 86 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-12-21,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Ceph 集群中由 mon 服务器维护着的五种运行图:

  • Monitor map:监视器运行图(监视 mon 进程的状态,哪个是主、哪个是从);
  • OSD map:OSD 运行图(各个 OSD 的状态,每个 OSD 会汇报自己的状态并且还会感知其它 OSD 的状态,如果一个 OSD 被其它 OSD 进程判定为 down,则在 20 秒后该 OSD 会被踢出集群);
  • PG map:PG 运行图(一个存储池有哪些 PG,每个 PG 又包含哪些 OSD);
  • Crush (Controllers replication under scalable hashing,可控的、可复制的、可伸缩的一致性 hash 算法) map:
    crush 运行图,当新建存储池时会基于 OSD map 创建出合适的 PG 组合列表用于存储数据;
  • MDS map:cephfs metadata 运行图;

一个文件向 Ceph 集群写入时,首先这个文件会被拆分为多个数据对象(object),然后根据每个 object 的 oid 来选择一个 PG(hash(oid)%pg数量)。CRUSH 会根据当前的运行图返回 pg 内的最新的 OSD 组合,每个 object 包含的数据就可以向主 OSD 写,然后同步到副本 OSD 最后完成数据的写入。

Crush 算法目前有 5 种算法来实现节点的选择,包括 Uniform、List、Tree、Straw、Straw2, 早期版本使用的是 Ceph 项目的发起者发明的算法 Straw,目前已经发展到 Straw2 版本。

PG 与 OSD 的映射调整

默认情况下,Crush 算法自行对创建的 pool 中的 PG 分配 OSD,但是可以手动基于权重设置 Crush 算法分配数据的倾向性,比如 1T 的磁盘权重是 1,2T 的就是 2。

虽然可以调整,但还是推荐使用相同大小的设备以便于维护。

查看当前状态

weight 表示设备(device)的容量相对值,比如 1TB 对应 1.00,那么 500G 的 OSD 的 weight 就应该是 0.5,weight 可以基于磁盘空间大小来分配 PG 的数量,让 Crush 算法尽可能往磁盘空间大的 OSD 多分配 OSD,往磁盘空间小的 OSD 分配较少的 OSD。

reweight 参数的目的是重新平衡 Ceph 的 CRUSH 算法随机分配的 PG,默认的分配策略是随机概率上的均衡,即使 OSD 都是一样的磁盘空间也会产生一 此 PG 分布不均匀的情况, 此时可以通过调整 reweight 参数,让 Ceph 集群立即重新平衡当前磁盘的 PG,以达到数据均衡分布的目的。reweight 通常在 PG 已经分配完成,要在 Ceph 集群重新平衡 PG 的分布的时候使用。

可以通过如下方式来查看各 OSD 的 weight 和 reweight 参数:

$ ceph osd df 
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META     AVAIL    %USE  VAR   PGS  STATUS
 0    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   88      up
 1    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   81      up
 2    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   87      up
 3    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   85      up
 4    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   84      up
 5    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   87      up
 6    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   82      up
 7    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   87      up
 8    hdd  0.01949   1.00000   20 GiB   16 MiB  1.8 MiB      0 B   14 MiB   20 GiB  0.08  1.00   87      up
                       TOTAL  180 GiB  142 MiB   16 MiB  8.5 KiB  125 MiB  180 GiB  0.08                   
MIN/MAX VAR: 1.00/1.00  STDDEV: 0

修改 weight

以修改 ID 为 5 的 OSD 的权重为 1.5 为例:

$ ceph osd crush reweight osd.5 1.5
reweighted item id 5 name 'osd.5' to 1.5 in crush map

在执行完这个操作后,Ceph 会立即执行数据的均衡(重新分配 PG),所以这个操作需要在业务空闲期间执行以降低对业务的影响。

修改 reweight

OSD 的 reweight 值默认为 1,值可以调整,范围在 0~1 之间,值越低则落在对应 OSD 的 PG越少,如果调整了任何一个 OSD 的 reweight 值,那么 OSD 的 PG 会立即和其它 OSD 进行重新平衡,即数据重新进行分配。它主要用于当某个 OSD 的 PG 相对较多需要降低其 PG 数量的场景。

以修改 ID 为 3 的 OSD 的 reweight 值为 0.5 为例:

$ ceph osd reweight 3 0.5
reweighted osd.3 to 0.5 (8000)

经过上述两轮调整,现在就可以明显看到调整过的 OSD 和未调整的 OSD 上落到的 PG 数量差异:

$ ceph osd df 
ID  CLASS  WEIGHT   REWEIGHT  SIZE     RAW USE  DATA     OMAP     META     AVAIL    %USE  VAR   PGS  STATUS
 0    hdd  0.01949   1.00000   20 GiB   17 MiB  1.9 MiB      0 B   15 MiB   20 GiB  0.08  1.00   96      up
 1    hdd  0.01949   1.00000   20 GiB   17 MiB  1.9 MiB      0 B   15 MiB   20 GiB  0.08  1.00   77      up
 2    hdd  0.01949   1.00000   20 GiB   17 MiB  1.9 MiB      0 B   15 MiB   20 GiB  0.08  1.00   93      up
 3    hdd  0.01949   0.50000   20 GiB   16 MiB  1.9 MiB      0 B   14 MiB   20 GiB  0.08  0.98   15      up
 4    hdd  0.01949   1.00000   20 GiB   16 MiB  1.9 MiB      0 B   14 MiB   20 GiB  0.08  0.98    8      up
 5    hdd  1.50000   1.00000   20 GiB   17 MiB  1.9 MiB      0 B   15 MiB   20 GiB  0.08  1.04  247      up
 6    hdd  0.01949   1.00000   20 GiB   17 MiB  1.9 MiB      0 B   15 MiB   20 GiB  0.08  1.00   88      up
 7    hdd  0.01949   1.00000   20 GiB   17 MiB  1.9 MiB      0 B   15 MiB   20 GiB  0.08  1.00   78      up
 8    hdd  0.01949   1.00000   20 GiB   17 MiB  1.9 MiB      0 B   15 MiB   20 GiB  0.08  1.00   66      up
                       TOTAL  180 GiB  150 MiB   17 MiB  8.5 KiB  132 MiB  180 GiB  0.08                   
MIN/MAX VAR: 0.98/1.04  STDDEV: 0.00

Crush 运行图管理

Crush 运行图无法直接进行管理操作,需要通过工具将 Ceph 的 Crush 运行图配置导出进行编辑,然后导入以实现修改操作。

导出二进制

导出的 Crush 运行图为二进制格式,无法通过文本编辑器直接打开。

# 创建一个目录保存导出的文件
$ mkdir /data/ceph -p
# 执行导出操作
$ ceph osd getcrushmap -o /data/ceph/crushmap
26

转换文本格式

可以使用 crushtool 将导出的 Crush 运行图二进制文件转换成文本格式再进行查看与编辑。

# 安装包含 crushtool 的包
$ apt install ceph-base -y
# 执行转换操作
$ crushtool -d /data/ceph/crushmap > crushmap.txt

此时就可以查看当前 Crush map 的配置了:

$ cat /data/ceph/crushmap.txt 
# begin crush map
# crush map 可调整的参数
tunable choose_local_tries 0
tunable choose_local_fallback_tries 0
tunable choose_total_tries 50
tunable chooseleaf_descend_once 1
tunable chooseleaf_vary_r 1
tunable chooseleaf_stable 1
tunable straw_calc_version 1
tunable allowed_bucket_algs 54

# devices
# 当前存储设备列表
device 0 osd.0 class hdd
device 1 osd.1 class hdd
device 2 osd.2 class hdd
device 3 osd.3 class hdd
device 4 osd.4 class hdd
device 5 osd.5 class hdd
device 6 osd.6 class hdd
device 7 osd.7 class hdd
device 8 osd.8 class hdd

# types
# 当前支持的 bucket 类型
type 0 osd # osd 守护进程,对应到一个磁盘设备
type 1 host # 一个主机
type 2 chassis # 刀片服务器的机箱
type 3 rack # 包含若干个服务器的机柜/机架
type 4 row # 包含若干个机柜的一排机柜
type 5 pdu # 机柜的接入电源插座
type 6 pod # 包含若干个电源插座的小房间
type 7 room # 包含若干小房间的房间,一个数据中心有好多这样的房间组成
type 8 datacenter # 一个数据中心或 IDS
type 9 zone # 一个区域,比如 AWS 宁夏中卫数据中心
type 10 region # 地域,比如亚洲、欧洲
type 11 root # 最顶层,根

# buckets
host ceph-node1 { # 类型 host,名称为 ceph-node1
		# ceph 生成的 host id,非必要不要改
        id -3           # do not change unnecessarily
        # 设备类型 id,也不需要修改
        id -4 class hdd         # do not change unnecessarily
        # weight 0.058
        alg straw2 # crush 算法,管理 osd 角色
        hash 0  # rjenkins1 指定 hash 算法,0 表示选择 rjenkins1 这种 hash 算法
        # osd 权重比例,crush 会自动根据磁盘容量计算
        item osd.0 weight 0.019
        item osd.1 weight 0.019
        item osd.2 weight 0.019
}
host ceph-node2 {
        id -5           # do not change unnecessarily
        id -6 class hdd         # do not change unnecessarily
        # weight 1.539
        alg straw2
        hash 0  # rjenkins1
        item osd.3 weight 0.019
        item osd.4 weight 0.019
        item osd.5 weight 1.500
}
host ceph-node3 {
        id -7           # do not change unnecessarily
        id -8 class hdd         # do not change unnecessarily
        # weight 0.058
        alg straw2
        hash 0  # rjenkins1
        item osd.6 weight 0.019
        item osd.7 weight 0.019
        item osd.8 weight 0.019
}
root default {
        id -1           # do not change unnecessarily
        id -2 class hdd         # do not change unnecessarily
        # weight 1.656
        alg straw2
        hash 0  # rjenkins1
        item ceph-node1 weight 0.058
        item ceph-node2 weight 1.539
        item ceph-node3 weight 0.058
}

# rules
rule replicated_rule { # 副本池的默认配置
        id 0
        type replicate
        min_size 1
        max_size 10 # 默认最大副本为 10
        step take default # 基于上面定义的 default 规则来分配 OSD
        step chooseleaf firstn 0 type host # 选择主机,故障域类型为主机
        step emit # 弹出配置即返回给客户端
}

# end crush map

导入配置

如果对上面的文本文件做了修改,需要将其转换回二进制格式才能够导入集群。

为演示效果我这里将 replicated_rulemax_size 修改为 5,然后执行转换操作:

$ crushtool -c /data/ceph/crushmap.txt -o /data/ceph/newcrushmap

导入的运行图会立即覆盖原有的运行图并立即生效:

$ ceph osd setcrushmap -i /data/ceph/newcrushmap
27

验证新运行图是否生效:

$ ceph osd crush rule dump
[
    {
        "rule_id": 0,
        "rule_name": "replicated_rule",
        "ruleset": 0,
        "type": 1,
        "min_size": 1,
        "max_size": 5,
        "steps": [
            {
                "op": "take",
                "item": -1,
                "item_name": "default"
            },
            {
                "op": "chooseleaf_firstn",
                "num": 0,
                "type": "host"
            },
            {
                "op": "emit"
            }
        ]
    }
]

数据分类管理

Ceph Crush 算法分配 PG 的时候可以将 PG 分配到不同主机的 OSD 上,以实现以主机为单位的高可用,这也是默认机制。但是该方式无法保证不同 PG 位于不同机柜或者机房的主机,如果要实现基于机柜或者是更高级的 IDC 等方式的数据高可用,或者要实现 A 项目的数据在 SSD, B 项目的数据在机械盘此类功能,则需要导出 Crush 运行图并手动编辑配置,之后再导人并覆盖原有的 Crush 运行图。

修改配置

修改导出的 Crushmap 文本文件,在其中添加如下内容:

host ceph-node1-ssd {
        id -13          # do not change unnecessarily
        id -14 class hdd                # do not change unnecessarily
        alg straw2
        hash 0  # rjenkins1
        item osd.2 weight 0.019
}
host ceph-node2-ssd {
        id -15          # do not change unnecessarily
        id -16 class hdd                # do not change unnecessarily
        alg straw2
        hash 0  # rjenkins1
        item osd.5 weight 0.019
}
host ceph-node3-ssd {
        id -17          # do not change unnecessarily
        id -18 class hdd                # do not change unnecessarily
        alg straw2
        hash 0  # rjenkins1
        item osd.8 weight 0.019
}

root ssd {
        id -11          # do not change unnecessarily
        id -12 class hdd                # do not change unnecessarily
        alg straw2
        hash 0  # rjenkins1
        item ceph-node1-ssd weight 0.058
        item ceph-node2-ssd weight 0.058
        item ceph-node3-ssd weight 0.058
}

rule ssd_replicated_rule {
        id 1
        type replicated
        min_size 1
        max_size 5
        step take ssd
        step chooseleaf firstn 0 type host
        step emit
}

上述配置将 ID 为 2、5、8 的三个 OSD 当做 SSD 盘,单独创建一个名为 ssd_replicated_rule 的 rule 关联对应几块磁盘所在主机。所以后续使用该 rule 创建的存储池的 PG 仅会分配在这几个使用 SSD 盘的 OSD。

执行导入操作:

$ crushtool -c /data/ceph/crushmap.txt -o /data/ceph/crushmap-ssd
$ ceph osd setcrushmap -i /data/ceph/crushmap-ssd
28

此时查看 OSD 结构可以看到两个 root 节点:

$ ceph osd tree
ID   CLASS  WEIGHT   TYPE NAME                STATUS  REWEIGHT  PRI-AFF
-11         0.17400  root ssd                                          
-13         0.05800      host ceph-node1-ssd                           
  2    hdd  0.01900          osd.2                up   1.00000  1.00000
-15         0.05800      host ceph-node2-ssd                           
  5    hdd  0.01900          osd.5                up   1.00000  1.00000
-17         0.05800      host ceph-node3-ssd                           
  8    hdd  0.01900          osd.8                up   1.00000  1.00000
 -1         1.65498  root default                                      
 -3         0.05800      host ceph-node1                               
  0    hdd  0.01900          osd.0                up   1.00000  1.00000
  1    hdd  0.01900          osd.1                up   1.00000  1.00000
  2    hdd  0.01900          osd.2                up   1.00000  1.00000
 -5         1.53899      host ceph-node2                               
  3    hdd  0.01900          osd.3                up   0.50000  1.00000
  4    hdd  0.01900          osd.4                up   1.00000  1.00000
  5    hdd  1.50000          osd.5                up   1.00000  1.00000
 -7         0.05800      host ceph-node3                               
  6    hdd  0.01900          osd.6                up   1.00000  1.00000
  7    hdd  0.01900          osd.7                up   1.00000  1.00000
  8    hdd  0.01900          osd.8                up   1.00000  1.00000

测试创建存储池

指定使用 ssd_replicated_rule rule 来创建存储池:

$ ceph osd pool create ssd-pool 32 32 ssd_replicated_rule
pool 'ssd-pool' created

查看 PGP 的状态来验证仅使用了 SSD OSD:

$ ceph pg ls-by-pool ssd-pool | awk '{print $1,$2,$15}'
PG OBJECTS ACTING
2.0 0 [5,2,8]p5
2.1 0 [5,8,2]p5
2.2 0 [5,2,8]p5
2.3 0 [2,8,5]p2
2.4 0 [5,8,2]p5
2.5 0 [2,5,8]p2
2.6 0 [8,2,5]p8
2.7 0 [5,8,2]p5
2.8 0 [8,2,5]p8
2.9 0 [5,8,2]p5
2.a 0 [2,8,5]p2
2.b 0 [2,8,5]p2
2.c 0 [5,8,2]p5
2.d 0 [2,8,5]p2
2.e 0 [8,5,2]p8
2.f 0 [5,8,2]p5
2.10 0 [8,2,5]p8
2.11 0 [2,5,8]p2
2.12 0 [8,5,2]p8
2.13 0 [2,8,5]p2
2.14 0 [2,8,5]p2
2.15 0 [5,2,8]p5
2.16 0 [5,2,8]p5
2.17 0 [5,2,8]p5
2.18 0 [2,5,8]p2
2.19 0 [2,8,5]p2
2.1a 0 [5,2,8]p5
2.1b 0 [2,5,8]p2
2.1c 0 [8,2,5]p8
2.1d 0 [5,2,8]p5
2.1e 0 [8,5,2]p8
2.1f 0 [2,5,8]p2

可以看到所有 PG 都是由我们指定的那几个 OSD 组成。

0

评论区