例如, 分散式存儲,有三臺機器,目前存儲數量為 100G , 20G ,10G ;不平衡,需要 重新分配一下,那麼在分配過程中,新來的 讀寫該如何進行呢?


分散式存儲通常使用一致性hash或range partiton來實現數據的分佈路由。基於一致性hash做數據分佈路由,在數據寫入時,基本就能保證均衡分佈到各個server,除非是hash演算法選擇有問題導致數據不均衡。

基於range partiton做數據分佈路由,需要通過partition分裂+rebanlance來保證數據佈局均衡,其中,partiton分裂時對未來較近時間內的數據預測尤為關鍵,預測到位可以同時保證數據均衡和rebanlance的數據量最少,但預測到位卻是很難的。

rebanlance過程中,前臺讀業務,可以直接從目的節點讀,目的節點沒有則由目的節點向源發起proxy讀;前臺寫可以雙寫。這只是思路之一,實際的方法要視應用場景而定。至於rebanlance中前後臺讀寫業務互斥,處理方式與解決前臺業務並發衝突的思路是一致,可以加互斥鎖或用樂觀鎖,視並發衝突的概率而定。如果前臺寫業務對時延不敏感,直接在遷入數據的目的節點加互斥鎖,簡單。

一種常見的思路是:當分散式系統中所存儲的數據有冗餘副本的時候,通過用暫時未遷移的穩定的其他副本提供數據的讀服務,然後根據分佈的規則尋找可以寫入數據的地方寫入,從而做到在負載平衡的時候讀寫不受影響——本質上還是屬於把讀寫部分保護起來拒絕讀寫,然後利用自帶的冗餘提供服務。

一種具體的方法以ceph為例:

系統對對象默認存取三個副本,每個被存儲的對象會被分塊,然後經過兩重邏輯映射(PG,OSD)後分散式的存儲在存儲設備上,而負責對外提供數據索引的第一層映射會關聯多個存儲設備(邏輯上的,非物理上的),其中有一個存儲設備作為對外提供服務的主設備(一塊數據會被關聯到一個PG上,一個PG會關聯多個對象存儲設備OSD,但是其中有一個OSD作為primary OSD對外提供服務)。

當因為新增節點或其他原因導致數據不均衡的時候,系統會根據情況調整待PG的標記,將對應穩定完整的數據的邏輯存儲設備作為主設備提供服務,然後在後臺對待遷移的其他數據進行遷移。新寫入的數據則會根據系統變化後的新的分佈的規則重新分佈。

1)設計上保證一定是平衡的

問題:那刪數據後還平衡嗎,新加入節點呢?都要一併處理

2)往空的寫 或 按剩餘空間大小作權重寫

問題:寫入熱點,並(大多場景下)很快變成讀取熱點。

3)繼續均衡地寫,滿的做只讀

問題:到後期會有寫入熱點,寫入能力如果把 IO能力 和 存儲能力 分開,那就變成了,均衡寫+後臺遷移,這是我比較側向的。


鎖一份冗餘 只寫 遷移 解鎖 再鎖另一份冗餘, 或者不做rebalance代價太大
moosefs裡面設計以一套負載均衡的演算法,跟這個有點類似,大致的思路是元數據伺服器會根據節點的存儲空間,當前的負載分配一個空閑的伺服器為新的寫請求分配存儲空間;當前的負載即包括了最近的外部讀寫,也包括了內部副本修復、遷移之類的操作。比較簡單的做法是外部讀寫請求較多超過閾值是不允許內部的rebalance遷移操作,但是數據修復的優先順序是最高了。進一步的做法,每種不同的IO賦予不同的優先順序,網路io、磁碟io都要實現優先順序隊列。某些高端陣列或者某種的網路協議都有優先順序的概念。


不清楚,rebalance的目標肯定是趨於平衡吧,當做已經平衡的來分配唄?貌似HDFS會進入保護模式?
推薦閱讀:
相關文章