ceph/src/crush/crush.h 源代码解析

ceph/src/crush/crush.h 源代码解析

crush算法相关的数据结构有 crush_bucket 结构、crush_map 结构和 crush_rule 结构。
(1) crush_bucket
结构 crush_bucket 用于保存 bucket 相关的信息

struct crush_bucket {
	__s32 id;        /*bucket的id,一般为负值*/
	__u16 type;      /* 类型,如果是0,就是OSD设备 */
	__u8 alg;        /* bucket的选择算法*/
	__u8 hash;       /*  bucket的hash函数*/
	__u32 weight;    /* bucket的权重*/
	__u32 size;      /* bucket下的item的数量*/
	__s32 *items;     /*子bucket在crush_bucket结构buckets数组的下标,这里特别要注意的是,其子item的crush_bucket结构体都统一保存在crush map结构中的buckets数组中,这里只保存其在数组中的下标*/
                
	/*以下是随机排序选择算法的一些cache的参数 */
	__u32 perm_x;  /* 要选择的x*/
	__u32 perm_n;  /* 排列的总的元素*/
	__u32 *perm;  /*排列组合的结果*/
};

(2)crush_map
结构 crush_map 定义了静态的所有 Cluster Map 的 bucket。bucket 为动态申请的二维数组,保存了所有的 bucket 结构。

struct crush_map {
	struct crush_bucket **buckets;   /*动态二维数组,保存所有的bucket结构*/
	struct crush_rule **rules;   /*保存所有的Crush_rule */
	
	__s32 max_buckets;
	__u32 max_rules;
	__s32 max_devices;  
	
       /* 在重新下降之前选择本地重试 */
	__u32 choose_local_tries;
	/*在重新下降之前选择使用后备排列的本地尝试*/
	__u32 choose_local_fallback_tries;
	/* 在放弃之前选择尝试*/
	__u32 choose_total_tries;
	/* 尝试选择内部下降一次为firstn模式; 拒绝重试外部下降。 请注意,这不适用于碰撞:在这种情况下,我们将按照惯例重试。 */
	__u32 chooseleaf_descend_once;
	
	/*如果非零,则将r馈入selectleaf,右移(r-1)位。 值为1最适合新群集。 对于想要限制重新排列的传统集群,值为3或4将使映射与先前的映射相比更好一些。*/
	__u8 chooseleaf_vary_r;
	/* 如果为true,则会使chooseleaf首先返回稳定的结果(如果没有本地重试),以便在某些设备出现故障时数据迁移将是最佳的。 */
	__u8 chooseleaf_stable;

#ifndef __KERNEL__
	/*.straw_calc的版本0(原始)有各种缺陷。 版本1修复了其中的一些。 */
	__u8 straw_calc_version;
	/*允许的桶algs是一个位掩码,这里的位位置是CRUSH_BUCKET_ *。 请注意,这些是*位*而不是CRUSH_BUCKET_ *值,所以我们需要或在一起(1 << CRUSH_BUCKET_WHATEVER)。 第0位不用于最小化混淆(桶类型值从1开始)。*/
	__u32 allowed_bucket_algs;
	__u32 *choose_tries;
#endif
};

(3)crush_rule

struct crush_rule {
	__u32 len;   /*steps的数组的长度*/
	struct crush_rule_mask mask;   /*ruleset相关的配置参数*/ 
	struct crush_rule_step steps[0];    /*操作步*/
};
struct crush_rule_mask {
	__u8 ruleset;   /*ruleset的编号*/
	__u8 type;   /*类型*/
	__u8 min_size;    /*最小size*/
	__u8 max_size;   /*最大size*/
};
struct crush_rule_step {
	__u32 op;   /*step操作步的操作码*/
	__s32 arg1;   /*如果是take,参数就是选择的bucket的id号;如果是select,就是选择的数量*/
	__s32 arg2;   /*如果是select,是选择的类型*/
};

猜你喜欢

转载自blog.csdn.net/liguihong123/article/details/85254257