6 存储的数据管理CRUSH Map

6 存储的数据管理

CRUSH 算法通过计算数据存储位置来确定如何存取数据。使用 CRUSH,Ceph 客户端无需通过中心服务器或中介程序,即可直接与 OSD 通讯。借助算法确定的数据存取方法,Ceph 可避免单一故障点、性能瓶颈和可伸缩性物理限制。

CRUSH 需要获取集群的地图,它使用 CRUSH图以伪随机的方式在 OSD 中存取数据,并以一致的方式在整个集群中分布数据。

CRUSH图包含一个 OSD 列表、一个用于将设备聚合到物理位置的“桶”列表,以及一个告知 CRUSH 应如何在 Ceph 集群存储池中复制数据的规则列表。通过反映安装的底层物理组织,CRUSH 可对相关设备故障的潜在根源建模,从而解决故障的根源。典型的根源包括物理邻近、共用电源和共用网络。通过将这些信息编码到集群地图中,CRUSH 归置策略可将对象副本分隔在不同的故障域中,同时维持所需的分布方式。例如,为了消除可能的并发故障,可能需要确保数据副本位于使用不同机架、机柜、电源、控制器和/或物理位置的设备上。

部署 Ceph 集群后,将会生成默认的 CRUSH图。这种模式适合 Ceph 沙箱环境。但是,在部署大规模的数据集群时,强烈建议您考虑创建自定义 CRUSH图,因为这样做有助于管理 Ceph 集群、提高性能并确保数据安全。

例如,如果某个 OSD 停机,而您需要使用现场支持或更换硬件,则 CRUSH图可帮助您定位到发生 OSD 故障的主机所在的物理数据中心、机房、机柜列和机柜。

同样,CRUSH 可以帮助您更快地确定故障。例如,如果特定机柜中的所有 OSD 同时停机,故障可能是由某个网络交换机或者机柜或网络交换机的电源所致,而不是发生在 OSD 自身上。

当与故障主机关联的归置组处于降级状态时,自定义 CRUSH图还可帮助您确定 Ceph 存储数据冗余副本的物理位置。

CRUSH图包括三个主要部分。

  • 设备由任何对象存储设备(即与 ceph-osd 守护进程对应的硬盘)组成。
  • 由存储位置(例如设备排、机柜、主机等)及为其指定的权重的分层聚合组成。
  • 规则组由桶选择方式组成。

6.1 设备

为了将归置组映射到 OSD,CRUSH图需要 OSD 设备(OSD 守护进程的名称)的列表。设备列表显示在 CRUSH图的最前面。

#devices

device num osd.name

例如:

#devices

device 0 osd.0

device 1 osd.1

device 2 osd.2

device 3 osd.3

一般而言,一个 OSD 守护进程映射到一个磁盘。

6.2

CRUSH图包含 OSD 的列表,可将这些 OSD 组织成“桶”,以便将设备聚合到物理位置。

0

osd

OSD 守护进程(osd.1osd.2 等)。

1

host

包含一个或多个 OSD 的主机名。

2

chassis

组成机柜的机箱。

3

rack

计算机机柜。默认值为 unknownrack

4

row

由一系列机柜组成的设备排。

5

pdu

电源分配单元。

6

pod

 

7

room

包含主机机柜和主机排的机房。

8

datacenter

包含机房的物理数据中心。

9

region

 

10

root

 

提示

可以删除这些类型,并创建自己的桶类型。

Ceph 的部署工具可生成 CRUSH图,其中包含每个主机的桶,以及名为“default”的存储池(可用于默认的 rbd 池)。剩余的桶类型提供了一种存储有关节点/桶的物理位置信息的方法,当 OSD、主机或网络硬件发生故障,并且管理员需要访问物理硬件时,这种方法可大大简化集群管理工作。

桶具有类型、唯一的名称(字符串)、以负整数表示的唯一 ID、相对于其项目的总容量/功能的权重、桶算法(默认为 straw)和哈希(默认为 0,反映 CRUSH 哈希 rjenkins1)。一个桶可以包含一个或多个项目。项目可由其他桶或 OSD 组成。项目可能会有一个权重来反映该项目的相对权重。

[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]

}

下面的示例说明如何使用桶来聚合存储池,以及诸如数据中心、机房、机柜和设备排的物理位置。

host ceph-osd-server-1 {

        id -17

        alg straw

        hash 0

        item osd.0 weight 1.00

        item osd.1 weight 1.00

}

 

row rack-1-row-1 {

        id -16

        alg straw

        hash 0

        item ceph-osd-server-1 weight 2.00

}

 

rack rack-3 {

        id -15

        alg straw

        hash 0

        item rack-3-row-1 weight 2.00

        item rack-3-row-2 weight 2.00

        item rack-3-row-3 weight 2.00

        item rack-3-row-4 weight 2.00

        item rack-3-row-5 weight 2.00

}

 

rack rack-2 {

        id -14

        alg straw

        hash 0

        item rack-2-row-1 weight 2.00

        item rack-2-row-2 weight 2.00

        item rack-2-row-3 weight 2.00

        item rack-2-row-4 weight 2.00

        item rack-2-row-5 weight 2.00

}

 

rack rack-1 {

        id -13

        alg straw

        hash 0

        item rack-1-row-1 weight 2.00

        item rack-1-row-2 weight 2.00

        item rack-1-row-3 weight 2.00

        item rack-1-row-4 weight 2.00

        item rack-1-row-5 weight 2.00

}

 

room server-room-1 {

        id -12

        alg straw

        hash 0

        item rack-1 weight 10.00

        item rack-2 weight 10.00

        item rack-3 weight 10.00

}

 

datacenter dc-1 {

        id -11

        alg straw

        hash 0

        item server-room-1 weight 30.00

        item server-room-2 weight 30.00

}

 

pool data {

        id -10

        alg straw

        hash 0

        item dc-1 weight 60.00

        item dc-2 weight 60.00

}

6.3 规则组

CRUSH图支持“CRUSH 规则”概念,这些规则确定存储池的数据归置。对于大型集群,您可能会创建许多存储池,其中每个存储池各自可能具有自己的 CRUSH 规则组和规则。默认的 CRUSH图对每个存储池使用一个规则,并为每个默认存储池指定一个规则组。

 

注意

大多数情况下,无需修改默认规则。创建新存储池时,该存储池的默认规则组为 0。

规则采用以下格式:

rule rulename {

 

        ruleset ruleset

        type type

        min_size min-size

        max_size max-size

        step step

 

}

ruleset

一个整数。将规则分类,使其属于一个规则组。通过在存储池中设置规则组来激活。必须指定此选项。默认值是 0

 

重要

需要从默认值 0 开始连续递增规则组编号,否则相关的监视器可能会崩溃。

type

一个字符串。描述硬盘 (replicated) 或 RAID 的规则。必须指定此选项。默认值为 replicated

min_size

一个整数。如果归置组创建的副本数小于此数字,CRUSH 将不选择此规则。必须指定此选项。默认值是 2

max_size

一个整数。如果归置组创建的副本数大于此数字,CRUSH 将不选择此规则。必须指定此选项。默认值是 10

step take bucket

采用某个桶名称,并开始在树中向下迭代。必须指定此选项。有关在树中迭代的说明,请参见第 6.3.1 节 “在节点树中迭代”

step targetmodenum type bucket-type

target 可以是 choosechooseleaf。如果设置为 choose,则会选择许多桶。chooseleaf 直接从桶集的每个桶的子树中选择 OSD(叶节点)。

mode 可以是 firstnindep。请参见第 6.3.2 节 “firstn 和 indep”

选择给定类型的桶的数量。其中,N 是可用选项的数量,如果 num > 0 且 < N,则选择该数量的桶;如果 num < 0,则表示 N - num;如果 num == 0,则选择 N 个桶(全部可用)。跟在 step takestep choose 后使用。

step emit

输出当前值并清空堆栈。通常在规则的末尾使用,但也可在同一规则中用来构成不同的树。跟在 step choose 后使用。

 

重要

要将一个或多个具有共同规则组编号的规则构成某个存储池,请将规则组编号设置为该存储池。

6.3.1 在节点树中迭代

可采用节点树的形式来查看使用桶定义的结构。在此树中,桶是节点,OSD 是叶。

CRUSH图中的规则定义如何从此树中选择 OSD。规则从某个节点开始,然后在树中向下迭代,以返回一组 OSD。无法定义需要选择哪个分支。CRUSH 算法可确保 OSD 集能够满足复制要求并均衡分布数据。

使用 step take bucket 时,节点树中的迭代从给定的桶(而不是桶类型)开始。如果要返回树中所有分支上的 OSD,该桶必须是根桶。否则,以下步骤只会在子树中迭代。

完成 step take 后,接下来会执行规则定义中的一个或多个 step choose 项。每个 step choose 项从前面选定的上层节点中选择定义数量的节点(或分支)。

最后,使用 step emit 返回选定的 OSD。

step chooseleaf 是一个便捷函数,可直接从给定桶的分支中选择 OSD。

图 6.1 “示例树”中提供了说明如何使用 step 在树中迭代的示例。在下面的规则定义中,橙色箭头和数字与 example1aexample1b 对应,蓝色箭头和数字与 example2 对应。

 

图 6.1︰ 示例树 #

# orange arrows

rule example1a {

        ruleset 0

        type replicated

        min_size 2

        max_size 10

        # orange (1)

        step take rack1

        # orange (2)

        step choose firstn 0 host

        # orange (3)

        step choose firstn 1 osd

        step emit

}

 

rule example1b {

        ruleset 0

        type replicated

        min_size 2

        max_size 10

        # orange (1)

        step take rack1

        # orange (2) + (3)

        step chooseleaf firstn 0 host

        step emit

}

 

# blue arrows

rule example2 {

        ruleset 0

        type replicated

        min_size 2

        max_size 10

        # blue (1)

        step take room1

        # blue (2)

        step chooseleaf firstn 0 rack

        step emit

}

6.3.2 firstn 和 indep

CRUSH 规则定义有故障节点或 OSD 的替换项(请参见第 6.3 节 “规则组”)。关键字 step 要求使用 firstnindep 参数。图 6.2 “节点替换方法”提供了示例。

firstn 将替换节点添加到活动节点列表的末尾。如果某个节点发生故障,其后的正常节点会移位到左侧,以填充有故障节点留下的空缺。这是副本池的默认方法,也是需要采取的方法,因为次要节点已包含所有数据,因此可立即接管主要节点的职责。

indep 为每个活动节点选择固定的替换节点。替换有故障节点不会更改剩余节点的顺序。这对于纠删码池而言是所需的行为。在纠删码池中,节点上存储的数据取决于在选择节点时它所在的位置。如果节点的顺序发生变化,受影响节点上的所有数据都需要重新放置。

 

注意:纠删池

确保针对每个纠删码池设置使用 indep 的规则。

 

图 6.2︰ 节点替换方法 #

6.4 CRUSH图操作

本节介绍基本的 CRUSH图操作方法,例如编辑 CRUSH图、更改 CRUSH图参数,以及添加/移动/删除 OSD。

6.4.1 编辑 CRUSH图

要编辑现有的 CRUSH图,请执行以下操作:

获取 CRUSH图。要获取集群的 CRUSH图,请执行以下命令:

root # ceph osd getcrushmap -o compiled-crushmap-filename

Ceph 会将编译的 CRUSH图输出 (-o) 到您指定名称的文件。由于该 CRUSH图采用编译格式,您必须先将其反编译,然后才能对其进行编辑。

反编译 CRUSH图。要反编译 CRUSH图,请执行以下命令:

root # crushtool -d compiled-crushmap-filename -o decompiled-crushmap-filename

Ceph 将对已编译的 CRUSH图进行反编译 (-d),并将其输出 (-o) 到您指定名称的文件。

至少编辑“设备”、“桶”和“规则”中的其中一个参数。

编译 CRUSH图。要编译 CRUSH图,请执行以下命令:

root # crushtool -c decompiled-crush-map-filename -o compiled-crush-map-filename

Ceph 会将编译的 CRUSH图存储到您指定名称的文件。

设置 CRUSH图。要设置集群的 CRUSH图,请执行以下命令:

root # ceph osd setcrushmap -i compiled-crushmap-filename

Ceph 将输入您所指定文件名的已编译 CRUSH图,作为集群的 CRUSH图。

6.4.2 添加/移动 OSD

要在运行中集群的 CRUSH图中添加或移动 OSD,请执行以下命令:

root # ceph osd crush set id_or_name weight root=pool-name

bucket-type=bucket-name ...

id

一个整数。OSD 的数字 ID。必须指定此选项。

name

一个字符串。OSD 的全名。必须指定此选项。

weight

一个双精度值。OSD 的 CRUSH 权重。必须指定此选项。

pool

一个键/值对。默认情况下,CRUSH 层次结构包含 default 存储池作为根。必须指定此选项。

bucket-type

键/值对。可在 CRUSH 层次结构中指定 OSD 的位置。

下面的示例将 osd.0 添加到层次结构,或移动之前某个位置的 OSD。

root # ceph osd crush set osd.0 1.0 root=data datacenter=dc1 room=room1 \

row=foo rack=bar host=foo-bar-1

6.4.3 调整 OSD 的 CRUSH 权重

要在运行中集群的 CRUSH图中调整 OSD 的 CRUSH 权重,请执行以下命令:

root # ceph osd crush reweight name weight

name

一个字符串。OSD 的全名。必须指定此选项。

weight

一个双精度值。OSD 的 CRUSH 权重。必须指定此选项。

6.4.4 删除 OSD

要从运行中集群的 CRUSH图中删除 OSD,请执行以下命令:

root # ceph osd crush remove name

name

一个字符串。OSD 的全名。必须指定此选项。

6.4.5 移动桶

要将某个桶移到 CRUSH图层次结构中的不同位置,请执行以下命令:

root # ceph osd crush move bucket-name bucket-type=bucket-name, ...

bucket-name

一个字符串。要移动/重新定位的桶的名称。必须指定此选项。

bucket-type

键/值对。可在 CRUSH 层次结构中指定桶的位置。

6.6 在同一个节点上混用 SSD 和 HDD

有时,用户可能需要配置这样一个 Ceph 集群:在每个节点上混用 SSD 和 HDD,并将一个存储池放在速度较快的 SSD 上,将另一个存储池放在速度较慢的 HDD 上。要实现此目的,需要编辑 CRUSH图。

默认的 CRUSH图采用简单的层次结构,其中,默认根包含主机,而主机包含 OSD,例如:

root # ceph osd tree

 ID CLASS WEIGHT   TYPE NAME      STATUS REWEIGHT PRI-AFF

 -1       83.17899 root default

 -4       23.86200     host cpach

 2   hdd  1.81898         osd.2      up  1.00000 1.00000

 3   hdd  1.81898         osd.3      up  1.00000 1.00000

 4   hdd  1.81898         osd.4      up  1.00000 1.00000

 5   hdd  1.81898         osd.5      up  1.00000 1.00000

 6   hdd  1.81898         osd.6      up  1.00000 1.00000

 7   hdd  1.81898         osd.7      up  1.00000 1.00000

 8   hdd  1.81898         osd.8      up  1.00000 1.00000

 15  hdd  1.81898         osd.15     up  1.00000 1.00000

 10  nvme 0.93100         osd.10     up  1.00000 1.00000

 0   ssd  0.93100         osd.0      up  1.00000 1.00000

 9   ssd  0.93100         osd.9      up  1.00000 1.00000

这样,就无法区分磁盘类型。要将 OSD 分为 SSD 和 HDD,需在 CRUSH图中创建另一个层次结构:

root # ceph osd crush add-bucket ssd root

为 SSD 创建新根后,需在此根中添加主机。这意味着需要创建新的主机项。但是,由于同一个主机名不能在 CRUSH图中出现多次,此处使用了虚设的主机名。这些虚设的主机名无需由 DNS 解析。CRUSH 不关心主机名是什么,只需创建适当的层次结构即可。要支持虚设的主机名,真正需要进行的一项更改就是必须设置

osd crush update on start = false

(在 /srv/salt/ceph/configuration/files/ceph.conf.d/global.conf 文件中),然后运行 DeepSea 阶段 3 以分发该项更改(有关详细信息,请参见第 1.11 节 “自定义 ceph.conf 文件”):

root@master # salt-run state.orch ceph.stage.3

否则,您移动的 OSD 稍后将重设置到其在默认根中的原始位置,并且集群不会按预期方式工作。

更改该设置后,请将新的虚设主机添加到 SSD 的根中:

root # ceph osd crush add-bucket node1-ssd host

root # ceph osd crush move node1-ssd root=ssd

root # ceph osd crush add-bucket node2-ssd host

root # ceph osd crush move node2-ssd root=ssd

root # ceph osd crush add-bucket node3-ssd host

root # ceph osd crush move node3-ssd root=ssd

最后,针对每个 SSD OSD,将 OSD 移到 SSD 的根中。在本示例中,我们假设 osd.0、osd.1 和 osd.2 实际托管在 SSD 上:

root # ceph osd crush add osd.0 1 root=ssd

root # ceph osd crush set osd.0 1 root=ssd host=node1-ssd

root # ceph osd crush add osd.1 1 root=ssd

root # ceph osd crush set osd.1 1 root=ssd host=node2-ssd

root # ceph osd crush add osd.2 1 root=ssd

root # ceph osd crush set osd.2 1 root=ssd host=node3-ssd

CRUSH 层次结构现在应类似下方所示:

root # ceph osd tree

ID WEIGHT  TYPE NAME                   UP/DOWN REWEIGHT PRIMARY-AFFINITY

-5 3.00000 root ssd

-6 1.00000     host node1-ssd

 0 1.00000         osd.0                    up  1.00000          1.00000

-7 1.00000     host node2-ssd

 1 1.00000         osd.1                    up  1.00000          1.00000

-8 1.00000     host node3-ssd

 2 1.00000         osd.2                    up  1.00000          1.00000

-1 0.11096 root default

-2 0.03699     host node1

 3 0.01849         osd.3                    up  1.00000          1.00000

 6 0.01849         osd.6                    up  1.00000          1.00000

-3 0.03699     host node2

 4 0.01849         osd.4                    up  1.00000          1.00000

 7 0.01849         osd.7                    up  1.00000          1.00000

-4 0.03699     host node3

 5 0.01849         osd.5                    up  1.00000          1.00000

 8 0.01849         osd.8                    up  1.00000          1.00000

现在,创建一个针对 SSD 根的 CRUSH 规则:

root # ceph osd crush rule create-simple ssd_replicated_ruleset ssd host

原始默认规则组 replicated_ruleset(ID 为 0)针对的是 HDD。新规则组 ssd_replicated_ruleset(ID 为 1)针对的是 SSD。

所有现有存储池仍会使用 HDD,因为它们位于 CRUSH图的默认层次结构中。可以创建一个仅使用 SSD 的新存储池:

root # ceph osd pool create ssd-pool 64 64

root # ceph osd pool set ssd-pool crush_rule ssd_replicated_ruleset

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值