在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一致性哈希算法簡介

算法與數據結構 ? 來源:labuladong ? 2023-04-04 11:53 ? 次閱讀

最近有一位讀者跟我交流,說除了算法題之外,系統設計題是一大痛點。算法題起碼有很多刷題平臺可以動手實踐,但系統設計類的題目一般很難實踐,所以看一些教程總結也只是一知半解,遇到讓寫代碼實現系統的就懵了。

比如他最近被問到一個大型爬蟲系統的設計題,讓手寫一致性哈希算法,加上一系列 follow up,就被難住了。

說實話這個算法的實現并不難,所以本文就結合一致性哈希算法在工程中的應用場景介紹一下這個算法算法,并給出代碼實現,避免大家重蹈覆轍。

一致性哈希算法簡介

這個名詞大家肯定不陌生,應該也大概理解這個算法的邏輯,不過我這里還是要再介紹一下。

一致性哈希主要解決把數據平均分配到多個節點上的問題,并且某些節點上線/下線后依然能夠做到自動負載均衡。

其原理就是抽象出一個哈希環,把服務器節點的 id 通過哈希函數映射到這個哈希環上:

ca0e0d10-d298-11ed-bfe3-dac502259ad0.jpg

同時,把需要處理的數據也通過哈希函數映射到這個哈希環上,然后順時針找,遇到的第一個服務器節點來負責處理這個數據:

ca202ab8-d298-11ed-bfe3-dac502259ad0.jpg

這樣一來,我們其實已經提供了一種機制將若干數據分布在若干服務節點上了,不妨稱它為 V1 版本的一致性哈希算法。

但 V1 版本的算法還有問題:負載分布很可能不均衡。由于哈希函數的結果是難以預測的,所以可能出現這種情況:

ca2baf28-d298-11ed-bfe3-dac502259ad0.jpg

即某些服務器節點要負責的哈希環很長,而其他服務器負責的哈希環很短。這就會導致某些服務器負載很高,而其他的服務器負載很低,很不均衡。

而且,當某個服務器節點下線后,它的負載會順時針轉移到下一個節點上,那么某些特定的節點下線順序很可能導致某些服務器節點負責的哈希環不斷加長,負載不斷增加。專業點說,這就是「數據傾斜」。

如何解決數據傾斜的問題呢?可以給每個服務器節點添加若干「虛擬節點」分布在哈希環上,我們不妨稱其為 V2 版的一致性哈希算法:

ca39e728-d298-11ed-bfe3-dac502259ad0.jpg

上圖給每個 Node 設置了 4 個虛擬節點,這樣一來,由于哈希函數的隨機性,每個服務器節點的虛擬節點能夠平均分布在哈希環上,那么數據就能夠比較均勻地分配到所有服務器節點上。

如果某個服務器節點下線,那么該服務器節點的所有虛擬節點都會從哈希環上摘除,它們的負載會遷移到順時針的下一個服務器節點上。

和 V1 版算法不同的是,因為虛擬節點有多個,它們的下一位不太可能是同一臺服務器的虛擬節點,所以它們的負載大概率會均分到多臺服務器的虛擬節點上。

綜上,V2 版算法通過虛擬節點的方式完美解決了數據傾斜的問題,是不是很巧妙?不過俗話說,紙上得來終覺淺,絕知此事要躬行,我們需要實踐才能真正寫出正確的一致性哈希算法。

比方說,應該用什么數據結構實現哈希環?如果哈希函數出現哈希沖突怎么辦?真正寫代碼的時候,這些細節問題都是要考慮的。

下面我們就結合代碼和實際場景來看看一致性哈希算法的真實應用。

實際場景分析

就以消息隊列的消費模型為例吧,我在前文用消息隊列做一個聯機游戲介紹過 Apache Pulsar 的消費模型,Pulsar 通過 subscription 的抽象提供多種訂閱模式,其中 key_shared 模式比較有意思:

每條消息會有一個 key,Pulsar 可以根據這個 key 分發消息,保證帶有相同 key 的消息分發到同一個消費者上。

官網的這幅圖比較好理解,圖中的K就是指消息的 key,V就是指消息的數據:

ca532dfa-d298-11ed-bfe3-dac502259ad0.png

通過某些算法,所有的消息都會有消費者去處理,比如上圖就是consumerA負責處理key=K3的消息,consumerB負責處理key=K1的消息,consumerC負責處理key=K2的消息。

當然,如果有 consumer 加入或者離開,消息的分配會重置。比如consumerA下線,那么key=K3的消息會被分配給其他消費者消費;如果有新的消費者consumerD加入,那么當前的分配方案也可能會改變。

簡單總結就是:

1、在沒有 consumer 加入或者離開的前提下,保證 key 相同的消息都會分配到固定的 consumer,不能一會兒分配到consumerA,一會兒分配給consumerB。

2、如果有 consumer 加入或者離開,可以重新進行分配每個 consumer 負責的 key,要求盡量把 key 平均分配給 consumer,避免出現某些 consumer 負責過多 key 的情況導致數據傾斜。

3、以上兩個操作,尤其是給 consumer 重新分配 key 的操作,效率要盡可能高。

對于上述場景,你如何設計分配算法,把這些帶有 key 的消息高效地、均勻地分配給所有 consumer 呢

我們來看看 Pulsar 是如何做的,官網對這部分的實現原理描述的比較清楚,參考鏈接如下:

https://pulsar.apache.org/docs/next/concepts-messaging/#key_shared

結合我之前在學習開源項目的套路中介紹的查看源碼背景信息的技巧,可以發現 Pulsar 的 key_shared 模式的消費者實現其實是經歷了一些演進的。

最開始的默認實現方式叫做 Auto-split Hash Range,即抽象出來一個[0, 65535]的哈希區間,讓每個 consumer 負責這個區間的一部分。比如有C1~C44 個 consumer,那么它們會平分整個哈希區間:

016,38432,76849,15265,536
|-------C3------|-------C2------|-------C4------|-------C1------|

然后我們可以對每條消息的 key 計算哈希值并求模映射到[0, 65535]的區間中,這樣我們就可以選出負責處理這條消息的 consumer 了,而且 key 相同的消息總會分配到這個 consumer 上。

那么如果有 consumer 上線或者下線怎么處理呢?

如果有 consumer 下線,那么它負責的哈希區間會直接交給右側的 consumer。比如上例中C4下線,那么哈希區間就會變成這樣:

016,38432,76865,536
|-------C3------|-------C2------|----------------C1---------------|

當然這里也有個特殊情況,就是下線的那個 consumer 右邊沒有其他 consumer 的情況,我們可以讓它左邊的 consumer 頂上來。比如現在的C1下線,那么就讓左邊的C2負責C1的區間:

016,38465,536
|-------C3------|--------------------------C2-----------------------|

如果有 consumer 上線,那么算法可以把最長的哈希區間平分,分一半給新來的 consumer。比如此時C5上線,我們就可以把C2負責的一半哈希區間分給C5:

016,38440,96065,536
|-------C3------|-----------C5-----------|----------C2----------|

這就是 Auto-split Hash Range 的方案,不算復雜,具體的實現可以看 Pulsar 源碼中HashRangeAutoSplitStickyKeyConsumerSelector這個類,我在這里就不列舉了。

這個方案的問題主要還是數據傾斜,比如上面的例子出現的這種情況,C2的負載顯然比C3多很多:

016,38465,536
|-------C3------|--------------------------C2-----------------------|

按照這個算法邏輯,一些 consumer 下線后很容易產生這種數據傾斜的情況,所以這個解決方案并不能均勻地把 key 分配給 consumer。

那么如何優化這個算法呢?就要用到一致性哈希算法了。

一致性哈希算法的實現

結合我在本文開頭對一致性哈希算法的介紹,應該很容易想到優化思路。其實現在 Pulsar 就是使用一致性哈希算法來實現的 key_shared 訂閱。

首先抽象出一個值在[0, MAX_INT]的哈希環,然后給每個 consumer 分配 100 個虛擬節點映射到這個哈希環上。接下來,我們把 key 的哈希值放在哈希環上,順時針方向找到最近的 consumer 虛擬節點,也就找到了負責處理這個 key 的 consumer。

哈希環我們一般用 TreeMap 實現,直接看 Pulsar 源碼中ConsistentHashingStickyKeyConsumerSelector的實現吧,我提取了其中的關鍵邏輯并添加了詳細的注釋:

classConsistentHashingStickyKeyConsumerSelector{
//哈希環,虛擬節點的哈希值->consumer列表
//因為存在哈希沖突,多個虛擬節點可能映射到同一個哈希值,所以值為List類型
NavigableMap>hashRing=newTreeMap<>();
//每個consumer有100個虛擬節點
intnumberOfPoints=100;

//將該consumer的100個虛擬節點添加到哈希環上
publicvoidaddConsumer(Consumerconsumer){
for(inti=0;i());
hashRing.get(hash).add(consumer);
}
}

//在哈希環上刪除該consumer的所有虛擬節點
publicvoidremoveConsumer(Consumerconsumer){
for(inti=0;i>ceilingEntry=hashRing.ceilingEntry(hash);
ListconsumerList;
if(ceilingEntry!=null){
consumerList=ceilingEntry.getValue();
}else{
//哈希環順時針轉一圈,回到開頭尋找第一個節點
consumerList=hashRing.firstEntry().getValue();
}
//保證相同的key都會分配到同一個consumer
returnconsumerList.get(hash%consumerList.size());
}
}

當消息被發送過來后,Pulsar 可以通過select方法選擇對應的 consumer 來處理數據;當新的 consumer 上線時,可以通過addConsumer將它的虛擬節點放到哈希環上并開始接收消息;當有 consumer 下線時,可以通過removeConsumer將它的虛擬節點從哈希環上摘除,由其他 consumer 承擔它的工作。

因為每個 consumer 有 100 個虛擬節點,所以在 consumer 下線時,負載其實是均勻地分配給了其他 consumer,因此一致性哈希算法能夠解決之前 Auto-split Hash Range 方案數據傾斜的問題。




審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 虛擬機
    +關注

    關注

    1

    文章

    955

    瀏覽量

    28864
  • 哈希算法
    +關注

    關注

    1

    文章

    56

    瀏覽量

    10872

原文標題:一致性哈希算法設計題,栽了

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    順序一致性和TSO一致性分別是什么?SC和TSO到底哪個好?

    內存一致性之順序一致性(sequential consistency)可以說,最直觀的內存一致性模型是sequentially consistent(SC):內存訪問執行的順序與程序指定的順序相同
    發表于 07-19 14:54

    一致性規劃研究

    針對一致性規劃的高度求解復雜度,分析主流一致性規劃器的求解策略,給出影響一致性規劃器性能的主要因素:啟發信息的有效,信念狀態表示方法的緊湊
    發表于 04-06 08:43 ?12次下載

    CMP中Cache一致性協議的驗證

    CMP是處理器體系結構發展的個重要方向,其中Cache一致性問題的驗證是CMP設計中的項重要課題。基于MESI一致性協議,本文建立了CMP的Cache
    發表于 07-20 14:18 ?38次下載

    加速器一致性接口

    Zynq PS上的加速器一致性接口(Accelerator Coherency Port, ACP)是個兼容AXI3的64位從機接口,連接到SCU(Snoop Control Unit),為PL
    發表于 11-17 15:04 ?3900次閱讀

    分布式一致性算法Yac

    傳統靜態拓撲主從模型分布式一致性算法存在嚴重負載不均及單點性能瓶頸效應,且崩潰節點大于集群規模的50qo時算法無法正常工作。針對上述問題,提出基于動態拓撲及有限表決思想的分布式一致性
    發表于 11-27 17:49 ?0次下載
    分布式<b class='flag-5'>一致性</b><b class='flag-5'>算法</b>Yac

    基于軌跡標簽的謠言一致性維護算法

    針對發布/訂閱系統中緩存副本一致性維護問題,首先,對原有基于謠言的一致性維護算法進行改進,提出種基于軌跡標簽的謠言一致性維護
    發表于 12-17 11:35 ?0次下載
    基于軌跡標簽的謠言<b class='flag-5'>一致性</b>維護<b class='flag-5'>算法</b>

    Cache一致性協議優化研究

    問題的由來.總結了多核時代高速緩存一致性協議設計的關鍵問題,綜述了近年來學術界對一致性的研究.從程序訪存行為模式、目錄組織結構、一致性粒度、一致性協議流量、目錄協議的可擴展性等方面,闡
    發表于 12-30 15:04 ?0次下載
    Cache<b class='flag-5'>一致性</b>協議優化研究

    優化模型的乘偏好關系一致性改進

    針對乘偏好信息下的決策問題,引入乘偏好關系的有序一致性、滿意一致性以及一致性指數等概念,建立以偏差變量最小化為目標函數的優化模型,進而構
    發表于 03-20 17:28 ?0次下載

    一致性哈希是什么?為什么它是可擴展的分布式系統架構的個必要工具

    在本文中,我們將了解一致性哈希是什么、為什么它是可擴展的分布式系統架構中的個必要工具。
    的頭像 發表于 07-17 17:57 ?4528次閱讀

    哈希圖一致性算法已被驗證為異步拜占庭容錯

    HederaHashgraph在下代公共分類帳中擁有多樣化的治理。它最近宣布哈希圖一致性算法已被驗證為異步拜占庭容錯。這是通過使用Coq系統的計算機檢查的數學證明完成的。
    發表于 10-23 11:07 ?1915次閱讀

    基于改進一致性的多無人機編隊控制算法

    基于改進一致性的多無人機編隊控制算法
    發表于 06-22 16:02 ?16次下載

    Dubbo負載均衡策略之一致性哈希

    本文主要講解了一致性哈希算法的原理以及其存在的數據傾斜的問題,然后引出解決數據傾斜問題的方法,最后分析一致性哈希
    的頭像 發表于 06-16 15:30 ?969次閱讀
    Dubbo負載均衡策略之<b class='flag-5'>一致性</b><b class='flag-5'>哈希</b>

    如何保證緩存一致性

    “ 本文的參考文章是2022年HOT 34上Intel Rob Blakenship關于CXL緩存一致性篇介紹。”
    的頭像 發表于 10-19 17:42 ?1454次閱讀
    如何保證緩存<b class='flag-5'>一致性</b>

    DDR一致性測試的操作步驟

    DDR一致性測試的操作步驟? DDR(雙數據率)一致性測試是對DDR內存模塊進行測試以確保其性能和可靠。在進行DDR一致性測試時,需要遵循
    的頭像 發表于 02-01 16:24 ?2156次閱讀

    深入理解數據備份的關鍵原則:應用一致性與崩潰一致性的區別

    深入理解數據備份的關鍵原則:應用一致性與崩潰一致性的區別 在數字化時代,數據備份成為了企業信息安全的核心環節。但在備份過程中,兩個關鍵概念——應用一致性和崩潰一致性,常常被誤解或混淆。
    的頭像 發表于 03-11 11:29 ?1223次閱讀
    深入理解數據備份的關鍵原則:應用<b class='flag-5'>一致性</b>與崩潰<b class='flag-5'>一致性</b>的區別
    主站蜘蛛池模板: 国产三级网站在线观看 | 乱码中文字幕人成在线 | 国产片无遮挡在线看床戏 | 日本一区不卡在线观看 | 日韩欧美中文字幕在线视频 | 欧美激情二区三区 | 一级日本高清视频免费观看 | 日本一区二区免费在线观看 | 男人天堂网在线观看 | 又粗又大又爽又色又过瘾视频 | 1024手机看片国产旧版你懂的 | 夜夜夜夜夜夜夜猛噜噜噜噜噜噜 | 女人张开腿让男人桶视频免费大全 | 免费男女视频 | 国产吧在线视频 | 中国高清性色生活片 | 在线观看免费观看 | 视频一区在线观看 | 四虎最新网站 | 国产免费亚洲 | 黄色美女免费网站 | 女同国产| 性 色 黄 一级 | 在线视频一二三区 | 欧美成人天天综合在线视色 | 三级毛片在线播放 | 久操免费在线 | 全免费a级毛片免费看不卡 全日本爽视频在线 | 爱爱小说视频永久免费网站 | 激情综合色五月丁香六月亚洲 | 我被黑人巨大开嫩苞在线观看 | 在线天堂bt中文www在线 | 91av成人| 久青草国产手机在线视频 | 寄宿日记在线看 | 久久国产午夜精品理论片34页 | 亚洲综合五月天婷 | 国产农村一级特黄α真人毛片 | 亚洲网站一区 | 亚洲美女视频一区 | bt天堂资源在线种子 |