01 是時候讓我們談談一致性hash了

2022-04-10 12:43:42 字數 3985 閱讀 5272

假如你有圖中三個盒子,我們有代號為 1,4,5,12 這四樣東西 那根據代號作為主鍵,將東西放到盒子了,該如何放置?

我們可以對代號取模 1 mod 3 = 1   4 mod 3 = 1    5 mod 3 = 2  12mod 3 = 0

這樣的話 大家就可以分配好到對應到盒子裡

1 #!/usr/bin/env python

2 3 box0 =

4 box1 =

5 box2 =

6 box_home =

11 res = [1,4,5,12]

12 13 for i in res:

14 key = i % 3

15 if key == 0:

17 elif key == 1:

19 elif key == 2:

21 22 for k,v in box_home.items():

23 print k,v

~

**如上

但是如果現在加乙個盒子 。

就變成這樣了

那麼現在就要取模為4了 之前箱子裡面的東西都要重新計算重新,重新擺放。

這在很多場景是不能夠接受的,比如負載均衡,我不能因為重新加了乙個節點,讓所有使用者的長鏈結都斷開,重新鏈結。

或許這種還能接受,那麼如果是分布式儲存呢?

所以這個時候我們不能夠這樣做。這樣子都服務就不是無狀態都服務。

這個時候就是一致性hash派上用場的時候了。

我們可以在剛剛分配的時候預留很多空位置。

圓形就是是空,矩形就是有箱子的。我們可以在一開始就留很多空白多地方 ,如圖上

我們一開始有三個節點,但是我們會分配5個位置,然後有資料就mod6,如果資料分配到到是沒有節點到位置

那麼我就就把這個資料放到下乙個有節點到位置,比如圖上我們要分配到是 資料8 那麼8mod6 = 2 此時位置2上沒有節點。那麼將這個資料到下乙個有節點到位置

也就是位置3。如果是mod到是最後乙個那麼就從頭開始,也就是說,位置是環形的。

如有新的節點加入,那麼直接放到空的位置上,然後將之前的分配在這個位置上的資料轉移上去即可,這樣子就能避免重新分配。

我們可以通過**模擬分配情況

#!/usr/bin/env python

#coding:utf-8

class node():

def __init__(self,data,next_node = none,node_type = 'body',is_online=0):

self.data = data

self.next_node = next_node

self.is_online = is_online

self.node_type = node_type

self.self_data =

self.other_data =

def get_next_node(self):

return self.next_node

def set_next_node(self,next_node):

self.next_node = next_node

return true

def set_node_status(self,num):

self.is_onlie = num

def get_data(self):

return self.data

class boxs():

def __init__(self,head=none):

self.head_node = head

self.size = 0

self.ser_node = none

def add_none(self,data,num):

if self.head_node == none:

self.head_node =node(data,is_online=num)

self.scr_node = self.head_node

self.size +=1

else:

new_node = node(data,is_online=num)

self.scr_node.set_next_node(new_node)

self.scr_node = new_node

self.size +=1

def print_list(self):

curr = self.head_node

while curr :

print '-----------------------'

print curr.data,'--->',curr.node_type,"---->",curr.is_online

print "data:",curr.self_data

print "other_data",curr.other_data

if curr.node_type != 'body':

break

else:

curr = curr.get_next_node()

def set_ass_node(self,data,num):

new_node = node(data,node_type='tail',is_online=num)

new_node.type = 'tail'

self.scr_node.set_next_node(new_node)

new_node.set_next_node(self.head_node)

def insert_data(self,key,dick_len):

curr = self.head_node

while curr:

if key % dick_len == curr.data:

if curr.is_online == 1:

else:

while 1:

curr = curr.get_next_node()

if curr.is_online == 1:

break

break

else:

curr = curr.get_next_node()

def set_node_allot(self,key_dict,dick_len):

for key in key_dict:

self.insert_data(key,dick_len)

#設定節點種有盒子的節點

online_node = [1,3,5]

#例項化煉表

mylist = boxs()

for i in range(7):

now_status = 0

if i in online_node:

now_status =1

if i <6:

mylist.add_none(i,now_status)

else:

mylist.set_ass_node(6,now_status)

#模擬資料

key_dict = [2,3,5,6,12,22,23,33]

#分配資料

mylist.set_node_allot(key_dict,len(key_dict)-1)

#列印分配情況

mylist.print_list()

談談一致性雜湊

原文 一致性雜湊演算法在1997年由麻省理工學院提出的一種分布式雜湊 dht 實現演算法,設計目標是為了解決網際網路中的熱點 hot spot 問題,初衷和carp十分類似。一致性雜湊修正了carp使用的簡 單雜湊演算法帶來的問題,使得分布式雜湊 dht 可以在p2p環境中真正得到應用。一致性has...

什麼是一致性雜湊?

當我們在資料庫中儲存海量資料時,由於單錶資料存在上限,所以不得不分庫分表儲存。假設我們有2000w條資料,而單錶上限為500w,我們部署了4臺資料庫伺服器來儲存這些資料,當我們需要查詢某一條資料時,我們對四個資料庫進行逐個查詢,顯然這樣做效率太低。因此我們可以使用雜湊演算法,建立資料與資料庫伺服器之...

談談分布式系統的一致性

一致性 consistency 一直是分布式系統裡乙個很重要的話題。在儲存系統中,為了避免資料丟失,我們都會對資料進行持久化。對資料進行持久化可以避免宕機帶來的資料丟失問題,但是不能解決單機永久性故障的問題。儲存系統作為基礎設施,在單機上持久化是遠遠不夠的,我們需要將資料複製到多台機器上以提公升系統...