1. 程式人生 > >關於一致性雜湊演算法的簡單講解

關於一致性雜湊演算法的簡單講解

傳統的取模方式

例如10條資料,3個節點,如果按照取模的方式,那就是

node a: 0,3,6,9

node b: 1,4,7

node c: 2,5,8

當增加一個節點的時候,資料分佈就變更為

node a:0,4,8

node b:1,5,9

node c: 2,6

node d: 3,7

總結:資料3,4,5,6,7,8,9在增加節點的時候,都需要做搬遷,成本太高

一致性雜湊方式

最關鍵的區別就是,對節點和資料,都做一次雜湊運算,然後比較節點和資料的雜湊值,資料取和節點最相近的節點做為存放節點。這樣就保證當節點增加或者減少的時候,影響的資料最少。

還是拿剛剛的例子,(用簡單的字串的ascii碼做雜湊key):

十條資料,算出各自的雜湊值

0:192

1:196

2:200

3:204

4:208

5:212

6:216

7:220

8:224

9:228

有三個節點,算出各自的雜湊值

node a: 203

node g: 209

node z: 228

這個時候比較兩者的雜湊值,如果大於228,就歸到前面的203,相當於整個雜湊值就是一個環,對應的對映結果:

node a: 0,1,2

node g: 3,4

node z: 5,6,7,8,9

這個時候加入node n, 就可以算出node n的雜湊值:

node n: 216

這個時候對應的資料就會做遷移:

node a: 0,1,2

node g: 3,4

node n: 5,6

node z: 7,8,9

這個時候只有5和6需要做遷移

另外,這個時候如果只算出三個雜湊值,那再跟資料的雜湊值比較的時候,很容易分得不均衡,因此就引入了虛擬節點的概念,通過把三個節點加上ID字尾等方式,每個節點算出n個雜湊值,均勻的放在雜湊環上,這樣對於資料算出的雜湊值,能夠比較雜湊的分佈(詳見下面程式碼中的replica)

通過這種演算法做資料分佈,在增減節點的時候,可以大大減少資料的遷移規模。 

下面轉載的雜湊程式碼,已經將gen_key改成上述描述的用字串ascii相加的方式,便於測試驗證。

  1. import md5  
  2. class HashRing(object):  
  3.     def __init__(self, nodes=None, replicas=3):  
  4.         """Manages a hash ring. 
  5.         `nodes` is a list of objects that have a proper __str__ representation. 
  6.         `replicas` indicates how many virtual points should be used pr. node,
     
  7.         replicas are required to improve the distribution. 
  8.         """
  9.         self.replicas = replicas  
  10.         self.ring = dict()  
  11.         self._sorted_keys = []  
  12.         if nodes:  
  13.             for node in nodes:  
  14.                 self.add_node(node)  
  15.     def add_node(self, node):  
  16.         """Adds a `node` to the hash ring (including a number of replicas). 
  17.         """
  18.         for i in xrange(0self.replicas):  
  19.             key = self.gen_key('%s:%s' % (node, i))  
  20.             print"node %s-%s key is %ld" % (node, i, key)  
  21.             self.ring[key] = node  
  22.             self._sorted_keys.append(key)  
  23.         self._sorted_keys.sort()  
  24.     def remove_node(self, node):  
  25.         """Removes `node` from the hash ring and its replicas. 
  26.         """
  27.         for i in xrange(0self.replicas):  
  28.             key = self.gen_key('%s:%s' % (node, i))  
  29.             delself.ring[key]  
  30.             self._sorted_keys.remove(key)  
  31.     def get_node(self, string_key):  
  32.         """Given a string key a corresponding node in the hash ring is returned. 
  33.         If the hash ring is empty, `None` is returned. 
  34.         """
  35.         returnself.get_node_pos(string_key)[0]  
  36.     def get_node_pos(self, string_key):  
  37.         """Given a string key a corresponding node in the hash ring is returned 
  38.         along with it's position in the ring. 
  39.         If the hash ring is empty, (`None`, `None`) is returned. 
  40.         """
  41.         ifnotself.ring:  
  42.             returnNoneNone
  43.         key = self.gen_key(string_key)  
  44.         nodes = self._sorted_keys  
  45.         for i in xrange(0, len(nodes)):  
  46.             node = nodes[i]  
  47.             if key <= node:  
  48.                 print"string_key %s key %ld" % (string_key, key)   
  49.                 print"get node %s-%d " % (self.ring[node], i)  
  50.                 returnself.ring[node], i  
  51.         returnself.ring[nodes[0]], 0
  52.     def print_ring(self):  
  53.         ifnotself.ring:  
  54.             returnNoneNone
  55.         nodes = self._sorted_keys  
  56.         for i in xrange(0, len(nodes)):  
  57.             node = nodes[i]  
  58.             print"ring slot %d is node %s, hash vale is %s" % (i, self.ring[node], node)  
  59.     def get_nodes(self, string_key):  
  60.         """Given a string key it returns the nodes as a generator that can hold the key. 
  61.         The generator is never ending and iterates through the ring 
  62.         starting at the correct position. 
  63.         """
  64.         ifnotself.ring:  
  65.             yieldNoneNone
  66.         node, pos = self.get_node_pos(string_key)  
  67.         for key inself._sorted_keys[pos:]:  
  68.             yieldself.ring[key]  
  69.         whileTrue:  
  70.             for key inself._sorted_keys:  
  71.                 yieldself.ring[key]  
  72.     def gen_key(self, key):  
  73.         """Given a string key it returns a long value, 
  74.         this long value represents a place on the hash ring. 
  75.         md5 is currently used because it mixes well. 
  76.         """
  77.         m = md5.new()  
  78.         m.update(key)  
  79.         return long(m.hexdigest(), 16)  
  80.         """ 
  81.         hash = 0 
  82.         for i in xrange(0, len(key)): 
  83.             hash += ord(key[i])  
  84.         return hash 
  85.         """
  86. memcache_servers = ['a',  
  87.                    'g',  
  88.                     'z']  
  89. ring = HashRing(memcache_servers,1)  
  90. ring.print_ring()  
  91. server = ring.get_node('0000')  
  92. server = ring.get_node('1111')  
  93. server = ring.get_node('2222')  
  94. server = ring.get_node('3333')  
  95. 相關推薦

    關於一致性演算法簡單講解

    傳統的取模方式例如10條資料,3個節點,如果按照取模的方式,那就是node a: 0,3,6,9node b: 1,4,7node c: 2,5,8當增加一個節點的時候,資料分佈就變更為node a:0,4,8node b:1,5,9node c: 2,6node d: 3,7總結:資料3,4,5,6,7,8

    java簡單實現一致性演算法

    什麼是一致性雜湊演算法 一種特殊的雜湊演算法,這種演算法使得雜湊表、叢集的規模在伸縮時儘可能減少重對映(remap)。為什麼需要它 一致性雜湊基本解決了在P2P環境中最為關鍵的問題——如何在動態的網路拓撲(叢集)中分佈儲存和路由。每個節點僅需維護少量相鄰節點的資訊,並且在節

    關於一致性演算法

    假設我們有 K 個機器,資料的雜湊值的範圍為 [0, MAX]。我們將整個範圍劃分為 m 個小區間(m 遠大於 K),每個機器負責 m/K 個小區間。當有新機器加入的時候,我們就將某幾個小區間的資料搬移到新機器上去。這樣,既不用全部重新計算雜湊值,搬移資料,也保持了各個機器上資料數量的均衡。 1

    【轉】一致性演算法

    在瞭解一致性雜湊演算法之前,最好先了解一下快取中的一個應用場景,瞭解了這個應用場景之後,再來理解一致性雜湊演算法,就容易多了,也更能體現出一致性雜湊演算法的優點,那麼,我們先來描述一下這個經典的分散式快取的應用場景。 場景描述 假設,我們有三臺快取伺服器,用於快取圖片,我們為這三臺快取伺服器編號為0

    一致性演算法的基本原理-如何解決傾斜問題

    在日常工作中,經常有這樣的情況,我們需要做hash,雜湊開資料到不同的區或節點。目標要的結果是要均勻雜湊,避免某個節點積累大量的資料,出現傾斜情況。 比如目前有N臺機器,過來的資料key,需要做雜湊key%N,分發到對應的節點上。 一致性雜湊演算法原理  為了解決has

    一致性演算法原理

    2018年11月12日 14:01:38 he582754810 閱讀數:6 個人分類: 分散式

    分散式memcache 一致性演算法(採用環狀資料結構)

      <?php #分散式memcache 一致性雜湊演算法(採用環狀資料結構) class ConsistentHashMemcache { private $virtualNode=''; #用於儲存虛擬節點個數 private $realN

    Redis一致性演算法

    場景描述 假設有N臺快取伺服器,現在我們希望把3萬張圖片快取到這些伺服器上。目標:快取儘可能均勻分佈在各伺服器上,以上它們能夠平攤快取壓力。那麼可以: 無任何規律的將3萬張圖片平均快取到所有伺服器上。但當需訪問某圖片時,需要遍歷所有伺服器所有快取項,效率太

    一致性演算法原理及其在分散式系統中的應用

    分散式快取問題 假設我們有一個網站,最近發現隨著流量增加,伺服器壓力越來越大,之前直接讀寫資料庫的方式不太給力了,於是我們想引入Memcached作為快取機制。現在我們一共有三臺機器可以作為Memcached伺服器,如下圖所示。 很顯然,最簡單的策略是將每一次Memcached請求隨機發送到一臺Memca

    每天進步一點點——五分鐘理解一致性演算法(consistent hashing)

    根據上面的圖解分析,一致性雜湊演算法滿足了單調性和負載均衡的特性以及一般hash演算法的分散性,但這還並不能當做其被廣泛應用的原由,因為還缺少了平衡性。下面將分析一致性雜湊演算法是如何滿足平衡性的。hash演算法是不保證平衡的,如上面只部署了NODE1和NODE3的情況(NODE2被刪除的圖),object1

    分散式一致性演算法(一)一致性演算法(consistent hashing)

    一 基本場景 比如你有 N 個 cache 伺服器(後面簡稱 cache ),那麼如何將一個物件 object 對映到 N 個 cache 上呢,你很可能會採用類似下面的通用方法計算 object 的 hash 值,然後均勻的對映到到 N 個 cache ; hash(o

    一致性演算法在分散式場景中的應用

    文章概要 本文將會從實際應用場景出發,介紹一致性雜湊演算法(Consistent Hashing)及其在分散式系統中的應用。首先本文會描述一個在日常開發中經常會遇到的問題場景,藉此介紹一致性雜湊演算法以及這個演算法如何解決此問題;接下來會對這個演算法進行相對詳細的描述,並討論一些如虛擬節

    查詢--深入理解一致性演算法

    注:本篇部落格只是講述了一致性雜湊的思想,我們會在之後講述分散式雜湊表以及一致性雜湊的一種實現(Chord演算法)。 什麼是一致性雜湊演算法? 引用自維基百科: 一致性雜湊是一種特殊的雜湊演算法。在使用一致雜湊演算法後,雜湊表槽位數(大小)的改變

    一致性演算法(consistent hashing)

    本文要解決的問題: 從原理上理解一致性雜湊演算法。 轉自:http://blog.csdn.net/cywosp/article/details/23397179/ 一致性雜湊演算法在1997年由麻省理工學院提出的一種分散式雜湊(DHT)實現演算法,設計目標是為了解決

    詳解一致性演算法(consistent hashing)

    根據上面的圖解分析,一致性雜湊演算法滿足了單調性和負載均衡的特性以及一般hash演算法的分散性,但這還並不能當做其被廣泛應用的原由,因為還缺少了平衡性。下面將分析一致性雜湊演算法是如何滿足平衡性的。hash演算法是不保證平衡的,如上面只部署了NODE1和NODE3的情況(NODE2被刪除的圖),object1

    三分鐘看懂一致性演算法

    受一篇“五分鐘看懂”的啟發,來個譁眾取寵的標題 一致性雜湊演算法,作為分散式計算的資料分配參考,比傳統的取模,劃段都好很多。 在電信計費中,可以作為多臺訊息介面機和線上計費主機的分配演算法,根據session_id來分配,這樣當計費主機動態伸縮的時候,因為session_i

    布隆過濾器、一致性演算法總結

    認識布隆過濾器 不安全網頁的黑名單包含 100 億個黑名單網頁,每個網頁的 URL 最多佔用 64B。 現在想要實現一種網頁過濾系統,可以根據網頁的 URL 判斷該網頁是否在黑名單上,請設計該系統。 1.該系統允許有萬分之一以下的判斷失誤率。 2.使用的額外空間不要超過 3

    [轉]理解一致性演算法(consistent hashing)

    [size=medium]一致性雜湊演算法原理[url]http://www.cnblogs.com/lpfuture/p/5796398.html[/url]白話解析一致性雜湊演算法(Excellent)[url]http://www.zsythink.net/archiv

    一致性演算法與C++實現

    一. 演算法解決問題 一致性雜湊演算法在1997年由麻省理工學院提出的一種分散式雜湊(DHT)實現演算法,設計目標是為了解決因特網中的熱點(Hot spot)問題,初衷和CARP十分類似。一致性雜湊修正了CARP使用的簡 單雜湊演算法帶來的問題,使得分散式雜湊

    一致性演算法(consistent hash)的黑科技

    這是一個來自Google的零記憶體消耗、均勻、快速、簡潔的一致性雜湊演算法 – Jump Consistent Hash 演算法的作者是Google的John Lamping和Eric Veach,論文原文連結 – 點這裡,一些討論 – 點這裡 整篇文章基於對論文原文的翻譯,摻雜自己的