關於一致性雜湊演算法的簡單講解
傳統的取模方式
例如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相加的方式,便於測試驗證。
- import md5
- class HashRing(object):
- def __init__(self, nodes=None, replicas=3):
- """Manages a hash ring.
- `nodes` is a list of objects that have a proper __str__ representation.
- `replicas` indicates how many virtual points should be used pr. node,
- replicas are required to improve the distribution.
- """
- self.replicas = replicas
- self.ring = dict()
- self._sorted_keys = []
- if nodes:
- for node in nodes:
- self.add_node(node)
- def add_node(self, node):
- """Adds a `node` to the hash ring (including a number of replicas).
- """
- for i in xrange(0, self.replicas):
- key = self.gen_key('%s:%s' % (node, i))
- print"node %s-%s key is %ld" % (node, i, key)
- self.ring[key] = node
- self._sorted_keys.append(key)
- self._sorted_keys.sort()
- def remove_node(self, node):
- """Removes `node` from the hash ring and its replicas.
- """
- for i in xrange(0, self.replicas):
- key = self.gen_key('%s:%s' % (node, i))
- delself.ring[key]
- self._sorted_keys.remove(key)
- def get_node(self, string_key):
- """Given a string key a corresponding node in the hash ring is returned.
- If the hash ring is empty, `None` is returned.
- """
- returnself.get_node_pos(string_key)[0]
- def get_node_pos(self, string_key):
- """Given a string key a corresponding node in the hash ring is returned
- along with it's position in the ring.
- If the hash ring is empty, (`None`, `None`) is returned.
- """
- ifnotself.ring:
- returnNone, None
- key = self.gen_key(string_key)
- nodes = self._sorted_keys
- for i in xrange(0, len(nodes)):
- node = nodes[i]
- if key <= node:
- print"string_key %s key %ld" % (string_key, key)
- print"get node %s-%d " % (self.ring[node], i)
- returnself.ring[node], i
- returnself.ring[nodes[0]], 0
- def print_ring(self):
- ifnotself.ring:
- returnNone, None
- nodes = self._sorted_keys
- for i in xrange(0, len(nodes)):
- node = nodes[i]
- print"ring slot %d is node %s, hash vale is %s" % (i, self.ring[node], node)
- def get_nodes(self, string_key):
- """Given a string key it returns the nodes as a generator that can hold the key.
- The generator is never ending and iterates through the ring
- starting at the correct position.
- """
- ifnotself.ring:
- yieldNone, None
- node, pos = self.get_node_pos(string_key)
- for key inself._sorted_keys[pos:]:
- yieldself.ring[key]
- whileTrue:
- for key inself._sorted_keys:
- yieldself.ring[key]
- def gen_key(self, key):
- """Given a string key it returns a long value,
- this long value represents a place on the hash ring.
- md5 is currently used because it mixes well.
- """
- m = md5.new()
- m.update(key)
- return long(m.hexdigest(), 16)
- """
- hash = 0
- for i in xrange(0, len(key)):
- hash += ord(key[i])
- return hash
- """
- memcache_servers = ['a',
- 'g',
- 'z']
- ring = HashRing(memcache_servers,1)
- ring.print_ring()
- server = ring.get_node('0000')
- server = ring.get_node('1111')
- server = ring.get_node('2222')
- server = ring.get_node('3333')
-
相關推薦
關於一致性雜湊演算法的簡單講解
傳統的取模方式例如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,論文原文連結 – 點這裡,一些討論 – 點這裡 整篇文章基於對論文原文的翻譯,摻雜自己的