Administrator
发布于 2022-08-04 / 5 阅读
0
0

ceph中的 weight

ceph中的 weight

最近在群里讨论 crush weight的问题,什么是 crush weight?这两天都只是部署安装,还没了解这个,在osd tree中是可以看到 weight,如下图,有weight 和 reweight。前者我知道是对应osd (磁盘)容量,后者呢?这个reweight有什么?这几个问题网上几乎是千篇一律,说是 weight会改变 它影响PG的到OSD的映射关系?是为什么呢?而且还有一个问题,Ceph osd weight与ceph osd crush weight 这两个命令之间又有什么区别?

!image-20220730012445791

先说下几个知识点

  • CRUSH 层级结构

假如一个数据中心里面有很多个机房,机房里面又有很多机柜,机柜里面又有很多服务器,服务器又可以挂载很多磁盘,层层递进就像是多叉树一样,前面所说的 基础设备,在ceph中统称为 故障域 或者 CRUSH bucket ,这里的 bucket 就是桶的意思,如在机房room0里面就是一个桶,桶里面装的时候rack0,rack1,rack2,rack0也是个bucket,这个bucket里面装的是host,以此类推,但是osd并不是桶,在这个层级结构中osd是最小的单位 ;这些bucket 表明了设备的位置,此外 ceph在管理这种大型分级存储网络,会将这些 基础设备 用crush map映射起来形成一个嵌套层次的结构如下图

!image-20220731001442177

在 ceph 的命令 也可以看到设备对应的层级结构

!image-20220730012445791

  • crush rule

从 crush map知道了数据可以放在哪里,数据应该怎么放呢,这也是有对应的规则的,ceph客户端如何去选bucket,以及到最后的osd,选择那个osd作为主osd,那个作为辅助osd ;如果我想 把将热数据存放于SSD中,而将冷数据放在HDD中,这也可以设定相关的规则,crush 算法会根据相应的规则去调整,接下来看下ceph 中的规则是怎样的


# getcrushmap 获取CRUSH map,这个输出是编译后的,人不看不了,需要反编译下
[root@node29 ceph]# ceph osd getcrushmap -o crushmap.bin
33
#crushtool -d 反编译
[root@node29 ceph]# crushtool -d crushmap.bin -o crushmap.txt

#这里面有map 中 每个bucket的详细情况
# 如 node29  和  root,参照上一张图片的 osd tree
# buckets
host node29 {
  	id -3		# do not change unnecessarily   id为正数说明是osd
  	id -4 class hdd		# do not change unnecessarily
  	# weight 0.586
  	alg straw2
  	hash 0	# rjenkins1
  	item osd.0 weight 0.293
  	item osd.3 weight 0.293
}
.....
root default {
  	id -1		# do not change unnecessarily
  	id -2 class hdd		# do not change unnecessarily
  	# weight 1.177       #这的weight是 item weight的总和
  	alg straw2  #每个bucket选择item时都有指定算法,这里用的是 straw2算法
  	hash 0	# rjenkins1
  	# bucket 里面的item, 按照层级关系
  	item rack01 weight 0.586
  	item rack02 weight 0.298
  	item rack03 weight 0.293
}

#最后是rules
# rules
rule replicated_rule {
  	id 0  #rule 的编号
  	type replicated   # pool的类型   多副本还是EC
  	min_size 1    #pool的最小副本数
  	max_size 10   #pool 的最大副本数
  	step take default   # bucket的入口点, default 是bucket root的名称
  	step chooseleaf firstn 0 type host  # fistst 算法,返回 osd位置
  	step emit
}

rule中有三个 setp

  1. take 从crush map选定编号(选定特定的bucket,示例中 选择的是 root ),作为步骤的开始
  2. select 从输入的bucket中选择随机选择指定类型 type 的item(桶里面的元素),bucket里面有type类型的item,为了尽可能的随机,会使用随机选择算法(有四种),ceph默认是使用 straw2 算法,使用straw2算法,选择item概率都相同,但是会为每一个item计算一个长度,最终会取最长的那个item;计算公式是一个hash值(这个hash值产生与pgid有关系)乘以 item的 weight(crush weight ),item weight大的元素有较大的概率算出最长的长度,从而更容易被抽中,当达到一点的数量规模,宏观上看是随机的。(straw2算法还有很多细节,这里知识简单概述下)
  3. emit 将结果返回上一层;

接下来的crush 算法步骤,这里不在继续讨论,会再另外篇文章 结合源码再来介绍crush 中具体实现算法

bucket weight是其item weight 的总和,weight是从下往上推的,若是改变osd的weight,osd的上一层bucket weight,会影响cursh 层级,修改 weight 的命令是


 #ceph osd crush reweight {name} {weight}
 #这里修改 osd.0 的weight
[root@node29 ~]# ceph osd tree |grep -E  "WEIGHT|osd.0"
ID  CLASS WEIGHT  TYPE NAME           STATUS REWEIGHT PRI-AFF
  0   hdd 0.29300             osd.0       up  1.00000 1.00000
#修改之前导出 pg的分布
[root@node29 ~]# ceph pg dump pgs|awk '{print $1,$17}' > old
dumped pgs
[root@node29 ~]# cat old | head -n 10
2.0 [1,3,2]
3.1 [1,3,2]
2.1 [3,2,1]
3.0 [1,2,0]
2.2 [2,0,1]
3.3 [0,2,1]
2.3 [3,1,2]
3.2 [3,1,2]
2.4 [3,1,2]
[root@node29 ~]#
 #现在修改 osd.0 weight
    [root@node29 ~]#  ceph osd crush reweight osd.0 0.1
^[[Areweighted item id 0 name 'osd.0' to 0.1 in crush map
    [root@node29 ~]# ceph osd tree |grep -E  "WEIGHT|osd.0"
ID  CLASS WEIGHT  TYPE NAME           STATUS REWEIGHT PRI-AFF
      0   hdd 0.09999             osd.0       up  1.00000 1.00000
[root@node29 ~]# ceph pg dump pgs|awk '{print $1,$17}' > new
    dumped pgs

[root@node29 ~]# diff old new  -y -W 30 --suppress-common-lines | head -n 10
2.0 [1,3,2]   |	2.0 [1,2,3]
3.0 [1,2,0]   |	3.0 [1,2,3]
2.2 [2,0,1]   |	2.2 [2,3,1]
3.4 [2,1,0]   |	3.4 [2,1,3]
2.6 [3,1,2]   |	2.6 [1,0,2]
3.6 [1,3,2]   |	3.6 [1,0,2]
2.8 [0,1,2]   |	2.8 [3,1,2]
3.9 [3,2,1]   |	3.9 [1,3,2]
2.a [0,1,2]   |	2.a [1,3,2]
2.d [2,0,1]   |	2.d [2,3,1]
[root@node29 ~]# diff old new  -y -W 30 --suppress-common-lines |wc -l
101
[root@node29 ~]# wc -l old
259
#pg在osd分布可以看出, 将osd weight 调小后,选择 osd.0 比较少了,所以调整item权重在step 中select是有影响的

总之我们的目的是,尽最大可能让数据均衡在 osd中,这个均衡并不是说 让每个osd存放的数据尽可能一样多,而是说数据所占的百分比,假如有两个硬盘,容量是100g和300g,如果要均衡,存放数据时,存放比例为 1:3 时才能到达均衡,而 osd reweight 就可以的调节;osd reweight 默认为1 ,其这个过程称为过载测试,算法流程如下:

!image-20220731175714700

is\_out 则是 选出osd的结果,reweight 调整得越高,那么通过测试的概率越高,通过调节reweight可以使数据分布更加合理


ceph osd reweight {osd} {reweight}
[root@node29 ~]# ceph osd reweight osd.1 0.5
reweighted osd.1 to 0.5 (8000)
[root@node29 ~]# ceph osd tree |grep -E  "WEIGHT|osd.1"
ID  CLASS WEIGHT  TYPE NAME           STATUS REWEIGHT PRI-AFF
  1   hdd 0.29799             osd.1       up  0.50000 1.00000
#修改后pg分布也有改变

ceh osd weight 是修改 reweight,数值在 \[0,1\], 选出osd后,通过 reweight可以进行过载测试

ceph osd crush weight 是修改 bucket weight, 这个weight 影响在bucket中选择那个 item起着关键作用


评论