資料分布演算法
(1)集中式的元資料查詢,如hdfs
(2)分布式演算法,例如一致性雜湊演算法,如crush
crush演算法步驟:
1、pool_id+hash(object_id)得到pg_id
2、針對每乙個osd,通過同樣的常量r,crush_hash(pg_id, osd_id, r) 得出乙個不同的隨機數,然後使用自己的隨機數與osd的weight相乘,得到draw,選出其中最大的draw值作為第乙個osd;然後將常量r+1,對每乙個osd再一次計算自己的隨機數,然後使用自己的隨機數與osd的weight相乘,得到draw,選出其中最大的draw值作為第二個osd;然後將常量r+2,對每乙個osd再一次計算自己的隨機數,然後使用自己的隨機數與osd的weight相乘,得到draw,選出其中最大的draw值作為第三個osd。
四種選擇演算法:
1、unique
2、list
3、tree
4、straw(目前使用)
crush演算法原始碼分析:
void
do_rule
(int rule,
int x, vector<
int>
& out,
int maxout,
const weightvector& weight,
uint64_t choose_args_index)
const
(1)、根據當前執行步驟的操作型別,選擇不同的分支操作,首先一般是take操作,而且是take fault。即crush map樹根節點。
(2)、當rule的操作型別以下四種時:
case crush_rule_chooseleaf_firstn:
case crush_rule_choose_firstn:
firstn =1;
/* fall through */
case crush_rule_chooseleaf_indep:
case crush_rule_choose_indep:
3、通過函式crush_choose_firstn和crush_choose_indep進行位置選擇:
firstn: 適用於副本池,選擇結果中rep(replica,指乙份副本或者ec中的乙個分塊,下同)位置無明顯意義
indep: 適用於ec池,選擇結果中rep位置不可隨意變動
舉例來說,副本池中每份副本儲存的是完全相同的資料,因此選擇結果為[0, 1, 2](數字代表osd編號)與[0, 2, 1]並無大的不同。但是ec池不一樣,在2+1的配比下前兩份是資料塊,最後乙份是校驗塊,後兩份rep位置一交換就會導致資料出錯。
下面主要針對firstn的型別:
4、函式crush_choose_firstn,目標是選出指定的numrep,type型別的節點,
執行for迴圈,rep變數初始值為0,到rep等於numrep時跳出迴圈,每次rep加1。
(1)、首先計算用於crush演算法的常量值r,常量值r的取值由rep變數(從0開始,每次選取完乙個osd則加1)+ ftotal(初始值0,每次選取結果不符合則加1)+ parent_r(從parent傳遞過來的值)【這裡的傳遞的parent_r值都是0】
(2)、呼叫函式crush_bucket_choose根據實際的crush演算法(一般使用straw)來選出第乙個符合的節點item;
(3)、當!collide && recurse_to_leaf時,如果遞迴呼叫crush_choose_firstn函式找不到葉子節點,就去掉這個節點item,此時ftotal加1,回到步驟1;
(4)、直到找到符合要求的numrep個節點,即完成for迴圈。
5、函式crush_bucket_choose根據使用的是哪一種演算法,找到對應演算法的choose函式,這裡以straw為例,會呼叫函式bucket_straw_choose。
/* straw */
static
intbucket_straw_choose
(const
struct crush_bucket_straw *bucket,
int x,
int r)
}return bucket->h.items[high];}
// 返回簽長最長的節點作為選取的節點
crush演算法應對情況一:osd.1掛掉,再回來crush演算法應對情況二:加入新的osd.4crush演算法應對情況三:刪除osd.2與使用hash演算法的區別:
如果是使用hash演算法,對每乙個pg_id取hash值以後,對osd總數取模,那麼一旦osd掛掉或者刪除osd或者加入新的osd,都會導致osd的總數產生變化,以致於大量的pg_id到osd的對映關係發生變化,會造成大量的資料遷移。
同時每次使用hash演算法都只能得到乙個osd的對映關係,所以如果需要找到osd集合的話,需要執行多次hash。
問題:
pgid到osd集合的對映中,需要先針對每乙個osd通過乙個crush_hash(pg_id, osd_id, r) 得出乙個隨機數,然後與該osd的weight相乘,得到乘值最大的osd;然後將r+1,得到另乙個不同的osd,再將r+2,得到第三個不同的osd。這裡r是乙個隨機常量??只有每次都是同樣的r才能每次計算都是一樣的結果吧。所有這裡的r是會儲存起來嗎?不然客戶端計算得到的會一直都是一樣的集合嗎?
解答:至少在目前看到的流程中r的初始值始終是1。
參考:
演算法分析 演算法的漸進效率分析
一般用於界定函式集合的上界,漸進表示式o g n 的含義就是,c為正常數,函式集合o中的元素的最大值不會超過c.g n f n o g n 的含義是,函式f n 的屬於集合o g n 因為函式集合o中的最大值為c.g n 所以f n 的最大值為c.g n 由於只是漸進的上界,所以當函式g n 的階數...
演算法和演算法分析
一 演算法的基本概述 演算法是為了解決某類問題而規定的乙個有限長的操作序列。乙個演算法必須滿足以下五個重要特性 1 有窮性2 確定性3 可行性 4 有輸入5 有輸出 二 設計演算法的原則 1.正確性 2.可讀性 3 健壯性 4.高效率與低儲存量需求 三 演算法的時間複雜度簡介 語句頻度 語句重複執行...
演算法和演算法分析
演算法是為了解決某類問題而規定的乙個有限長的操作序列。五個特性 1.有窮性2.確定性3.可行性4.輸入5.輸出 1.正確性2.可讀性3.健壯性4.高效性 1.問題規模和語句頻度 不考慮計算機的軟硬體等環境因素,影響演算法時間代價的最主要因素是問題規模。問題規模是演算法求解問題輸入量的多少,是問題大小...