CRUSHMAP : 分层集群映射示例

laurentbarbe

在 Crushmap 中组织数据并不总是容易的,尤其是在尝试地理分布数据,同时分离不同类型的磁盘时,例如 SATA、SAS 和 SSD。 让我们看看我们可以想象的 Crushmap 层次结构。

以在两个数据中心进行分布的简单示例为例。 (模型 1.1)

随着缓存池的引入,我们可以很容易地想象在我们的集群中添加 ssd 驱动器。 以将 ssd 添加到新主机为例。 然后我们剩下两种类型的磁盘需要管理。 在仅描述集群物理划分的层次结构中,我们将最终得到这种类型的层次结构: (模型 1.2)

但是,我们很快意识到这种配置不允许将磁盘类型分离出来用于特定池。

为了分离这些磁盘并组织 Crushmap,最简单的方法仍然是从根目录复制树。 因此,我们得到两个进入点“default”(可以重命名为“hdd”)和“ssd”。 另一个示例,其中 hdd 和 ssd 混合在同一硬件上(您需要拆分每个主机): (模型 1.3)

问题是,我们已经通过驱动器类型分割了整个集群。 因此,我们的树中不再有进入点来选择“dc-1”或“dc-2”中的任何磁盘。 例如,我们不再能够定义规则来将数据存储在特定的数据中心,而不管磁盘类型如何。

我们可以做的是在根级别添加其他进入点。 例如,为了允许访问所有驱动器: (模型 1.4)

如果我们想在树中保持某种逻辑,也可以添加更多的层级,有些层级更“逻辑”,例如用于磁盘类型,而其他层级代表物理分布。 它们可以放置在我们想要的位置,并以我们想要的方式命名。 例如,在这里,我添加了“pool”层级,也可以将其称为“type”或其他名称。 (模型 1.5)

好的,这可行,但很难阅读。 此外,当 SSD 和 HDD 混合在同一主机上时,它会变得难以阅读,因为它涉及复制每个主机。 此外,不再有物理数据放置逻辑。 我们可以尝试在 HOST 和 OSD 之间插入一个层级: (模型 1.6)

好的,这可能对小型集群有利,或者在不需要其他层级的情况下有利。 让我们尝试其他方法,我们还可以尝试使用另一种组织方式,例如将 osd 分离到不同的层级,并在特定规则中使用它。 例如,使用 step chooseleaf firstn 5 type host-sata 选择 sata 驱动器,并使用 step chooseleaf firstn 5 type host-ssd 选择 ssd 驱动器。 (模型 1.7)

但是,这不起作用。 事实上,该算法将尝试获取树的每个分支中的一个 OSD。 如果未找到 OSD,它将再次尝试回溯。 但是,这种操作是相当随机的,很容易导致复制不足。

使用此 crushmap 进行测试

  • 1 个规则用于选择每个 DC 的一个 ssd

  • 1 个规则用于选择每个 DC 的一个 sata

  • 1 个规则用于选择 2 个不同主机的 sata

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# begin crush map
tunable choose_local_tries 0
tunable choose_local_fallback_tries 0
tunable choose_total_tries 50
tunable chooseleaf_descend_once 0
tunable chooseleaf_vary_r 0

# devices
device 0 osd.0
device 1 osd.1
device 2 osd.2
device 3 osd.3
device 4 osd.4
device 5 osd.5
device 6 osd.6
device 7 osd.7
device 8 osd.8
device 9 osd.9
device 10 osd.10
device 11 osd.11
device 12 osd.12
device 13 osd.13
device 14 osd.14
device 15 osd.15
device 16 osd.16
device 17 osd.17
device 18 osd.18

# types
type 0 osd
type 1 host-ssd
type 2 host-sata
type 3 datacenter
type 4 root

# buckets
host-sata host-01 {
  alg straw
  hash 0
  item osd.1 weight 1.000
  item osd.2 weight 1.000
  item osd.3 weight 1.000
}
host-sata host-02 {
  alg straw
  hash 0
  item osd.4 weight 1.000
  item osd.5 weight 1.000
  item osd.6 weight 1.000
}
host-sata host-03 {
  alg straw
  hash 0
  item osd.7 weight 1.000
  item osd.8 weight 1.000
  item osd.9 weight 1.000
}
host-sata host-04 {
  alg straw
  hash 0
  item osd.10 weight 1.000
  item osd.11 weight 1.000
  item osd.12 weight 1.000
}

host-ssd host-05 {
  alg straw
  hash 0
  item osd.13 weight 1.000
  item osd.14 weight 1.000
  item osd.15 weight 1.000
}
host-ssd host-06 {
  alg straw
  hash 0
  item osd.16 weight 1.000
  item osd.17 weight 1.000
  item osd.18 weight 1.000
}

datacenter dc1 {
  alg straw
  hash 0
  item host-01 weight 1.000
  item host-02 weight 1.000
  item host-05 weight 1.000
}
datacenter dc2 {
  alg straw
  hash 0
  item host-03 weight 1.000
  item host-04 weight 1.000
  item host-06 weight 1.000
}

root default {
  alg straw
  hash 0
  item dc1 weight 1.000
  item dc2 weight 1.000
}

# rules

rule sata-rep_2dc {
  ruleset 0
  type replicated
  min_size 2
  max_size 2
  step take default
  step choose firstn 0 type datacenter
  step chooseleaf firstn 1 type host-sata
  step emit
}

rule ssd-rep_2dc {
  ruleset 1
  type replicated
  min_size 2
  max_size 2
  step take default
  step choose firstn 0 type datacenter
  step chooseleaf firstn 1 type host-ssd
  step emit
}

rule sata-all {
  ruleset 2
  type replicated
  min_size 2
  max_size 2
  step take default
  step chooseleaf firstn 0 type host-sata
  step emit
}


# end crush map

要测试放置,我们可以使用这些命令

crushtool -c crushmap.txt -o crushmap-new.bin
crushtool --test -i crushmap-new.bin --show-utilization --rule 0 --num-rep=2
crushtool --test -i crushmap-new.bin --show-choose-tries --rule 0 --num-rep=2

检查利用率

$ crushtool --test -i crushmap-new.bin --show-utilization  --num-rep=2 | grep ^rule
rule 0 (sata-rep_2dc), x = 0..1023, numrep = 2..2
rule 0 (sata-rep_2dc) num_rep 2 result size == 0:   117/1024
rule 0 (sata-rep_2dc) num_rep 2 result size == 1:   448/1024
rule 0 (sata-rep_2dc) num_rep 2 result size == 2:   459/1024
rule 1 (ssd-rep_2dc), x = 0..1023, numrep = 2..2
rule 1 (ssd-rep_2dc) num_rep 2 result size == 0:    459/1024
rule 1 (ssd-rep_2dc) num_rep 2 result size == 1:    448/1024
rule 1 (ssd-rep_2dc) num_rep 2 result size == 2:    117/1024
rule 2 (sata-all), x = 0..1023, numrep = 2..2
rule 2 (sata-all) num_rep 2 result size == 0:   113/1024
rule 2 (sata-all) num_rep 2 result size == 1:   519/1024
rule 2 (sata-all) num_rep 2 result size == 2:   392/1024

对于所有规则,样本的一部分复制数量不足。 特别是对于数量较少的驱动器(在本例中为 ssd)。 查看选择 osd 的重试次数,我们看到增加“choose_total_tries”将毫无用处,因为它已经足够了

$ crushtool --test -i crushmap-new.bin --show-choose-tries --rule 0 --num-rep=2
 0:      4298
 1:       226
 2:       130
 3:        59
 4:        38
 5:        11
 6:        10
 7:         3
 8:         0
 9:         2
10:         1
11:         0
12:         2

$ crushtool --test -i crushmap-new.bin --show-choose-tries --rule 1 --num-rep=2
 0:      2930
 1:       226
 2:       130
 3:        59
 4:        38
 5:        11
 6:        10
 7:         3
 8:         0
 9:         2
10:         1
11:         0
12:         2

$ crushtool --test -i crushmap-new.bin --show-choose-tries --rule 2 --num-rep=2
 0:      2542
 1:        52
 2:        12

我们可以测试增加 osd 的数量以进行测试(这不太漂亮……)

在 sata-rep_2dc 中:step chooseleaf firstn 5 type host-sata

在 ssd-rep_2dc 中:step chooseleaf firstn 5 type host-ssd

在 sata-all 中:step chooseleaf firstn 15 type host-sata

$ crushtool --test -i crushmap-new.bin --show-utilization  --num-rep=2 | grep ^rule
rule 0 (sata-rep_2dc), x = 0..1023, numrep = 2..2
rule 0 (sata-rep_2dc) num_rep 2 result size == 1:   1/1024
rule 0 (sata-rep_2dc) num_rep 2 result size == 2:   1023/1024
rule 1 (ssd-rep_2dc), x = 0..1023, numrep = 2..2
rule 1 (ssd-rep_2dc) num_rep 2 result size == 0:    20/1024
rule 1 (ssd-rep_2dc) num_rep 2 result size == 1:    247/1024
rule 1 (ssd-rep_2dc) num_rep 2 result size == 2:    757/1024
rule 2 (sata-all), x = 0..1023, numrep = 2..2
rule 2 (sata-all) num_rep 2 result size == 2:   1024/1024

更好的是,我们看到对于“sata-all”规则,它工作得很好,但是,当磁盘较少时,复制数量仍然不正确。 这种分布的想法很有吸引力,但很快意识到它行不通。

如果有人探索过这种方法,或者有高级 CRUSHMAP 的示例,我鼓励大家分享。 我对可以使用它完成的所有事情感到好奇。 同时,最好根据您的需要使其简单化。 在大多数情况下,模型 1.3 将是完美的。

有关 CRUSH 算法的更多详细信息:https://ceph.net.cn/papers/weil-crush-sc06.pdf