關於一致性hash演算法的解釋和應用場景,部落格中以已經出現了許多非常優秀的文章解釋,這裡放一個解釋比較清楚的部落格文章如果不太瞭解一致性hash演算法是什麼可以點選瞭解一下,本文主要融合一致性hash演算法思想去簡單解決我們工作中遇到的問題。
在程式設計思想中我們知道要時刻面對變化,而一致性hash演算法的出現就是應對hash演算法對特定數值取模時這個特定數值帶來的變化。用我們工作中比較常見的一個場景資料庫分表來舉例:
場景一:我們資料庫有一張文章表資料量超過1000萬條資料,導致我們查詢效率低下,所以技術部決定對這表表進行拆分,考慮到目前公司的發展情況,我們決定把這張表拆分成3份,那麼我們對文章表中主鍵id做hash運算然後對3取模如:hash(id)%3 如果取模得到的值為1就把資料放入文章表1中,如果取模得到2就把資料放入文章表2中,以此類推我們成功把原來的一張表拆分成了3張完美解決了當下的問題。
場景二:萬萬沒想到不到一年的時間公司業務發展迅猛資料量暴增,原來的3張文章表也不夠用了,還要擴張表怎麼辦?如果要擴張表就需要對文章表主鍵進行hash重排,然後重新分配,可以想像那工作量和不確定性是多麼大,基本上不會這樣做。所以基本無解。
場景三:吸取場景二的教訓,然後加上學了一致性hash演算法以後,開始用該演算法去實現自己的分表操作,可是問題來了,演算法我是知道了,可是真正實現起來對一般小公司的技術人員來講還是有一定難度的,真的有一種道理我都懂,可是依然過不好這一生的感覺,哈哈。
最後根據一致性hash演算法的思想和自己的理解我想出了一箇中間方案,我就推測公司的發展情況我預估它5年後可以達到20張文章表,但目前需求我們需要從3張表擴充套件到6張表,然後我們可以計算hash(id)%20將取模後的結果分配到這6張表中,如下表分配:
文章表1 | 0,1,2 |
文章表2 | 4,5,6 |
文章表3 | 7,8,9 |
文章表4 | 10,11,12 |
文章表5 | 13,14,15,16 |
文章表6 | 17,18,19 |
對於hash取模後的值對應上表進行分配,如值為4我們就把該記錄分配到文章表二中, 值為15我們就把記錄放到文章表5中,以此類推,如果哪天我們需要繼續擴充套件表到7張怎麼辦呢?我們就可以把節點15, 16從文章表5中放到文章表7中,如下圖:
文章表1 | 0,1,2 |
文章表2 | 4,5,6 |
文章表3 | 7,8,9 |
文章表4 | 10,11,12 |
文章表5 | 13,14 |
文章表6 | 17,18,19 |
文章表7 | 15,16 |
這樣分配以後,其他文章表不動我們只需要對文章5中的資料進行重新hash,然後重新分配到表5或者表7中即可完美避免hash重排的命運。
在此文章中只是對分表做hash分配,如果上升到機器層面,我們是不是可以對配置高的機器多分配節點,配置低的機器少分配節點,有點根據權重分配的感覺了,哈哈。
如果想對分散式系統相關的中介軟體有個大概的認識 李慶旭的分散式系統設計實踐 這本書真的非常適合你,這是我為數不多連續花兩個晚上看完的書籍,給你上帝的視角去看待分散式系統的設計和各中介軟體的由來和解決什麼問題,受益頗深。