採用跳躍定址方式可以實現 分布式定址演算法

2021-10-16 11:14:31 字數 2695 閱讀 8584

一、分布式定址演算法簡介

分布式定址演算法是很重要的內容,不了解這些演算法,也就不能透徹的了解各種分布式中介軟體的原理。簡單說一下這些高大上的定址到底是個啥意思,比如在elasticsearch中,採用的是多分片,每個分片上儲存的是不一樣的資料,是一種並集關係。比如我們通過_id去搜尋一條資料,elasticsearch怎麼知道這個_id的資料是存在哪個分片上?再比如redis cluster中通過key去查詢一條資料,redis集群中怎麼知道這個key在哪個節點上?所以這就是定址演算法要解決的問題。

簡單介紹三種分布式定址演算法

1 hash演算法2 一致性hash演算法3 hash slot
hash演算法比較適合固定分割槽或者分布式節點的集群架構,比如elasticsearch中primary shard是固定並且不能改變的。所以採用hash演算法是一種不錯的選擇,當然es確實也是這麼做的。感興趣的可以看我的另一篇關於es的部落格。

shard = hash(routing) % number_of_primary_shards (routing預設_id)

一致性hash演算法比較適合需要動態擴容的分布式架構以及一些動態負載均衡的分布式中介軟體和rpc中介軟體。

redis cluster應用的是hash slot實現的一致性hash定址。

比如在elasticsearch中,假如有3個primary shard。

shard = hash(_id) % 3;
插入一條資料,通過以上公式我們很容易能確認該資料存在了哪個分片上。按照_id查詢的是有同樣通過以上公式很容易找到該資料位於哪個分片上。

以上演算法看上去一切都是那麼美好,然鵝。。。

假如primary shard需要擴容意思也就是需要增加乙個primary shard怎麼辦?(僅僅是假如,elasticsearch primary shard是不可變的)hash公式變成下面這樣

shard = hash(_id) % 4;
是不是就會發生定址錯誤?

這就意味著當增加分割槽需要將原來各個分割槽上的資料按照shard = hash(_id) % 4的hash取模結果將資料搬運到對應分割槽上去。假如當有海量資料怎麼辦?說實話很難辦。當發現乙個shard宕機,需要快速容災處理時候,也是一樣的問題。

可以說一致性hash就是解決以上動態擴容和縮容問題而誕生的。在分布式架構中如果不支援動態擴容和容災,分布式=雞肋,沒毛病吧。

其實一致性hash聽起來那麼牛x,其實也沒啥高階的,只不過是一種更加高階的hash取模運算而已。

如上所示,一般的hash環是hash取模運算的node = hash(key) % n;n取2^32,即形成了乙個從0~32的hash環。定址按照順時針進行查詢最近的乙個節點。

有4個節點按照ip取模即node = hash(ip) % n落在了如上圖所示的位置,這時乙個請求,根據node = hash(key) % n求出該請求落在了如下圖所示位置,按照順時針查詢,找到該請求命中節點2。這就是這麼乙個簡單的定址過程。

擴容:在原來4個節點的基礎上,增加乙個節點5,依然根據根據ip取模即node = hash(ip) % n確定節點在hash環上的位置。如下圖所示。

可見原來的請求就命中了節點5,所以我們依然需要進行資料的遷移,但是只是部分的,只需要遷移1-2節點之間的資料即可。相對hash取模,一致性hash演算法減少了擴容帶來的資料遷移量太大的問題。容災同理。

但是一致性hash演算法存在的問題也是很明顯的,因為節點很難均勻的落在hash環上。但是有效的減少了動態增刪節點帶來的資料遷移問題。

hash slot即hash槽。redis cluster採用的正式這種hash槽演算法實現的定址。以redis cluster為例。

在redis cluster中固定的存在16384個hash slot。

hash slot = crc16(key)%16384;
#crc16演算法可以簡單的理解為一種hash演算法。詳見度娘。

這樣我們就能找到key對應的hash slot。其實按照我的理解,hash slot就是在定址和節點間加了一層對映關係。當節點動態變化,只需要改變hash slot ==> 節點的對映,然後只需要遷移指定slot到新新增的節點即可。既減少了hash定址帶來的資料全量遷移問題,相對一致性hash也使得負載均衡效果更加明顯。

如上圖,如果我們有三個節點。redis cluster初始化時會自動均分給每個節點16384個slot。

當增加乙個節點4,只需要將原來node1~node3節點部分slot上的資料遷移到節點4即可。在redis cluster中資料遷移並不會阻塞主程序。對效能影響是十分有限的。

分布式定址演算法

springboot讀原始碼系列 elasticsearch系列 資料結構系列 分布式定址演算法是很重要的內容,不了解這些演算法,也就不能透徹的了解各種分布式中介軟體的原理。簡單說一下這些高大上的定址到底是個啥意思,比如在elasticsearch中,採用的是多分片,每個分片上儲存的是不一樣的資料,...

分布式鎖實現方式

1 資料庫的唯一索引實現 獲得鎖時向表中插入一條記錄,釋放鎖時刪除這條記錄。唯一索引可以保證該記錄只被插入一次,那麼就可以用這個記錄是否存在來判斷是否存於鎖定狀態。缺點 2 redis的setnx指令實現 使用 setnx set if not exist 指令插入乙個鍵值對,如果 key 已經存在...

分布式鎖的實現方式

在進行大型 技術架構設計以及業務實現的過程中,多少都會遇到需要使用分布式鎖的情況。那麼問題也就接踵而至。分布式鎖zk和memcached以及redis三者都能實現,同樣是分布式鎖,三者的區別何在?各自適用什麼場景?一 zookeeper 實現原理 基於zookeeper瞬時有序節點實現的分布式鎖,其...