zoukankan      html  css  js  c++  java
  • ceph之ceph osd tree下的weight, reweight

    一、概述

     1 ID  WEIGHT    TYPE NAME              UP/DOWN REWEIGHT PRIMARY-AFFINITY 
     2  -1 558.47980 root default                                             
     3  -2  32.75999     host SJ-6-Cloud100                                   
     4   2   3.64000         osd.2               up  1.00000          1.00000 
     5   3   3.64000         osd.3               up  1.00000          1.00000 
     6   4   3.64000         osd.4               up  1.00000          1.00000 
     7   5   3.64000         osd.5               up  1.00000          1.00000 
     8   6   3.64000         osd.6               up  1.00000          1.00000 
     9   8   3.64000         osd.8               up  1.00000          1.00000 
    10   9   3.64000         osd.9               up  1.00000          1.00000 
    11  10   3.64000         osd.10              up  1.00000          1.00000 
    12  11   3.64000         osd.11              up  1.00000          1.00000 
    13  -3  32.75999     host SJ-6-Cloud101                                   
    14  12   3.64000         osd.12              up  1.00000          1.00000 
    15  15   3.00000         osd.15              up  1.00000          1.00000 
    16  17   3.64000         osd.17              up  1.00000          1.00000 
    17  18   3.64000         osd.18              up  1.00000          1.00000 
    18  19   3.64000         osd.19              up  1.00000          1.00000 
    19  20   3.64000         osd.20              up  1.00000          1.00000 
    20  21   3.64000         osd.21              up  1.00000          1.00000 
    21  22   3.64000         osd.22              up  1.00000          1.00000 
    22  23   3.64000         osd.23              up  1.00000          1.00000 

      即第2列的weight与第5列的reweight区别;

      class OSDMap

        — ceph::shared_ptr<CrushWrapper> crush;   

        — vector<__u32>   osd_weight;   // 16.16 fixed point, 0x10000 = "in", 0 = "out" 

        —   vector<osd_info_t> osd_info; 

        

       继续跟踪struct  crush_map;

        

        查看crush_bucket的成员变量:

         

      注意其中的weight以及itmes;

      第2行的weight  【osd crush weight】 指的是 crush中 bucket下面的item_weight保存的值;该值没有限制,一般与磁盘容量相匹配;  ceph osd crush reweight osd.0  1.500  #调整osd.0的crush weight

      第5行的reweight 【osd weight】指的是OSDMap中的osd_weight保存的值,该值允许在 [0.0~1.0]之间;             ceph osd reweight  0 0.8         #0 指osd.0  来进行调整数值

    二、意义 

      实际上,OSDMap中的 osd_weight 与 crush 下的 item_weight是独立的,没有相互关联。

       我们执行命令ceph osd out osd.id 操作时,实际上是把 reweight 一项设置为0,而此时weight值并未改变。

       通常情况下,当OSD上面数据相对不平衡时,我们应该使用ceph osd reweight 命令修改reweight值,而不应该使用ceph osd crush reweight 命令修改weight值。原因在于,修改reweight值将不会改变bucket的weight,而如果修改weight值就会改变整个bucket的weight。bucket

    weight 一旦改变,就会导致数据在bucket之间进行迁移,而不是在bucket内部进行迁移,这能最小化数据的转移量。

      通过ceph osd reweight 设置权重,更新了什么?

      ceph osd reweight 命令仅仅更新了OSDMap中osd_weights的值,而crush下面的item_weight值并不改变。从命令行传入的 [0.0 ~ 1.0] 的值会被系统归一化,将值乘个乘数(0x10000)并将其截整,所以osd_weigth下面的最大值为 0x10000,这对于下面解释osd_weights如何起

    作用时候,至关重要。

       归一化算式:weigth = (int)input_weight * 0x10000 (65536)

       从算式可知,当weight 被截整后,精度能够到0.000015,如果权重值变化差异小于该值的,可能的结果是weigth截整后数值没有变化,这也限定了weight的精度值。

      通过ceph osd crush reweight 设置权重,更新了什么?

      与osd reweight相同的是,从命令行传入的weight仍然是double类型的,而传入后Ceph进行归一化处理,转换为int 类型,转换方式与osd reweight相同,这里就不再次提及了。然后,传入的归一化后的weight值将取代crush_map中的buckets下对应的item_weight的值。并且,会利

    用替代的item_weight,通过函数crush_calc_straw() 值重新计算straw的值。

       那么我们看到,其实bucket下面还有一个weight值,该值等于该bucket下所有item_weight值的累加总和,即 sum(item_weight)

      straw的计算方式是Sage通过在权重调整后,统计重映射数据量,并根据统计结果不断优化改进获得,这里不详细展开叙述。

      OSDMap下的osd_weight 与 bucket下的item_weight是如何决定PG向osd的映射关系的?

      我们看到,上面straw值的计算比较复杂,实际上我们不需要太过于关心straw的值到底是怎么算出来的,其实一个最基本的限制就是 straw 值的变化是跟随 item_weight值变化而变化的,item_weight 大的 straw 也一定大,item_weight相对小的straw也相对小,这样item_weight的变大/变小就能够影响数据在一个osd上的迁入/迁出了。

       在决定osd是否被选的权重时,算式是:

    • hash = crush_hash32_3(bucket->h.hash, x, bucket->h.items[i], r);  //计算hash值

    • hash = hash & 0xffff   //取hash值的低16位

    • draw = straws * hash

       最终应该选出拥有最大draw值的bucket或者osd胜出。而计算hash值与 bucket的hash值,选择的位置(第一个副本,第二个副本,还是第三个副本),items的序号,以及重试次数r有关。由于hash值计算出来是32位的,为保证与straw相乘后不会溢出,并且hash值不应该是起决定性因数的因子(即如果两个过大的hash值,0xfffff000 与 0xffff0000 与weight相乘后,如果weight设置的不合理,则会导致数据分布不平均,在这种情况下,决定的因素会更偏向于hash,而不是所设置的权重值),所以这里通过处理,让straw都大于等于0x10000,而hash值让都小于等于0xffff,这样无论用户如何设置straw的值,权重值总能起决定因数来决定数据的分布。

       从上面的分析可以看到,这里影响draw的值的只有straw值的大小,即item_weight值的大小,而osd_weight对其选择没有任何影响,那么osd_weigth又是如何影响PG向osd的映射关系的呢?

      在通过比较draw值获胜后,选出的osd,并不一定是最终的决定。crush算法中,实现了reject的机制,在osd选出来后,根据某些条件,本次选择有可能被拒绝而进入重选逻辑。进入重选后,上面提及的r值会改变,重选计算的hash值将会有所不同,从而最终导致选出了不同的osd。crush算法中,通过四步判断是否reject:

    • item 序号大于权重值数量,说明该item是没有权重的,则reject

    • item 的权重 >= 0x10000,则一定选取,不reject,也就是说当reweight 值设置为 1.0的时候,是不会被reject的

    • item 的权重 == 0, 则说明osd被out,必定reject

    • 如果 item 的权重是 (0 ~ 0x10000)之间的值,那么是否reject取决于 hash & 0xffff 的大小是否大于等于 osd_weight。如果小于osd_weight,则reject

      所以我们看到了,调整reweight的值影响的实际上是每次选择后,选出来的osd是否会被reject而进入重选。

       执行ceph osd out osd.id 后,如果该osd 留在crush map中,为何有可能选不出osd?

      根据上面的理论,我们知道了ceph osd out osd.id 仅仅只是将reweight 设置为0,但是weight仍然是不变的。所以该osd还是会被选到,只是选到osd后,一定会被reject掉。crush算法会根据 crush tunable 里面的参数值设置( choose_total_tries,choose_local_tries 与

      choose_local_fallback_tries),决定是否进行重选,且最多进行多少次重选。

      目前默认的规则如下:

    • choose_total_tries = 50

    • choose_local_tries = 0

    • choose_local_fallback_tries = 0

       意思是,在一PG映射的选取过程中,如果重试次数达到50次,就不允许在进行重选,此时,如果PG需要映射的3个副本,而选择出第二个副本后,重试次数已达50次,那么选择第三个副本存放的osd时,如果在进入重试逻辑,则不再允许继续重选,此时PG只映射能映射到两个副本上,PG

    将会一直停留在degrade 或则 remapped,数据处于降级状态。

      什么情况下会产生大量重试情况,导致最终无法达到预想的效果?

       在crush算法选择时,除了reject,还有一种情况是collision。collision表示,下一次选择选到了重复的bucket或item。例如:第一次选择时,选中了osd-group-c-rack-04,而第二次选择应该选则仍然选中了osd-group-c-rack-04,此时就会被判断为collision,进行重选。通常情况下,

    osd-domain越少,权重越不平衡,则选中后collision的概率就会越高,假设我们有且仅有3个osd-domain并且权重相同,即选中3个osd-domain的概率相等,均为 1/3,那么我们可以计算选出3个osd需要重试次数的期望值,其近似满足几何分布,所以期望可以近似为每次选择会重试3次,如

    果引入精确的概率论计算,应该会大于这个值。而且,如果权重越不平衡,则重试次数将会越多。故通常情况下,如果bucket间权重值不对等,或则reweight osd 过多,又或则有多个osd在crush中被out。都有可能造成重试次数耗尽而选出对应osd的情况,此时应该适当矫正

    choose_total_tries,choose_local_tries,choose_local_fallback_tries三个参数的值,让其选择效率达到最佳。

  • 相关阅读:
    【转】Linux中的特殊权限粘滞位(sticky bit)详解
    【转】Spark实现行列转换pivot和unpivot
    Pyspark 使用 Spark Udf 的一些经验
    CDH 集群机器上部署 Jupyter notebook 使用 Pyspark 读取 Hive 数据库
    Pyspark-SQL 官方 API 的一些梳理(上)
    Kafka-python 客户端导致的 cpu 使用过高,且无法消费消息的问题
    如何创建和管理 MySQL 相关权限
    CDH Yarn 调度资源指南
    Sqoop export(Hive to MySQL) 的一些 reference
    vue2.x学习笔记(二十七)
  • 原文地址:https://www.cnblogs.com/chris-cp/p/6136831.html
Copyright © 2011-2022 走看看