1. 程式人生 > >ceph/src/crush/crush.h 原始碼解析

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,是選擇的型別*/
};