自己實現乙個一致性 Hash 演算法

2022-07-04 12:09:13 字數 2787 閱讀 8824

在前文分布式理論(八)—— consistent hash(一致性雜湊演算法)中,我們討論了一致性 hash 演算法的原理,並說了,我們會自己寫乙個簡單的演算法。今天就來寫乙個。

先看看普通 hash 怎麼做。

首先,需要快取節點物件,快取中的儲存物件,還有乙個快取節點集合,用於儲存有效的快取節點。

實際儲存物件,很簡單的乙個類,只需要獲取他的 hash 值就好:

static class obj 

@override

public int hashcode()

@override

public string tostring() ';}}

快取節點物件,用於儲存實際物件:

static class node 

public void putobj(obj obj)

obj getobj(obj obj)

@override

public int hashcode()

}

也很簡單,內部使用了乙個 map 儲存節點。

快取節點集合,用於儲存有效的快取節點:

static class nodearray 

obj get(obj obj)

void put(obj obj)

}

內部乙個陣列,取資料時,通過取餘機器數量獲取快取節點,再從節點中取出資料。

測試:當增減節點時,還能不能找到原有資料:

/**

* 驗證普通 hash 對於增減節點,原有會不會出現移動。

*/public static void main(string args) ;

for (node node : nodes)

obj objs = ;

for (obj obj : objs)

validate(nodearray, objs);

}

private static void validate(nodearray nodearray, obj objs) 

nodearray.addnode(new node("anything1"));

nodearray.addnode(new node("anything2"));

system.out.println("********** after **********===");

for (obj obj : objs)

}

測試步驟如下:

向集合中新增 3 個節點。

集群中新增 5 個物件,這 5 個物件會根據 hash 值雜湊到不同的節點中。

列印未增減前的資料。

列印增加 2 個節點後資料,看看還能不能訪問到資料。

結果:乙個都訪問不到了。這就是普通的取餘的缺點,在增減機器的情況下,這種結果無法接收。

再看看一致性 hash 如何解決。

關鍵的地方來了。

快取節點物件和實際儲存物件不用更改,改的是什麼?

改的是儲存物件的方式和取出物件的方式,也就是不使用對機器進行取餘的演算法。

新的 nodearray 物件如下:

static class nodearray 

void put(obj obj)

// 找到比給定 key 大的集合

sortedmaptailmap = nodes.tailmap(objhashcode);

// 找到最小的節點

int nodehashcode = tailmap.isempty() ? nodes.firstkey() : tailmap.firstkey();

nodes.get(nodehashcode).putobj(obj);

}obj get(obj obj)

// 找到比給定 key 大的集合

sortedmaptailmap = nodes.tailmap(obj.hashcode());

// 找到最小的節點

int nodehashcode = tailmap.isempty() ? nodes.firstkey() : tailmap.firstkey();

return nodes.get(nodehashcode).getobj(obj);

}}

該類和之前的類的不同之處在於:

內部沒有使用陣列,而是使用了有序 map。

put 方法中,物件如果沒有落到快取節點上,就找比他小的節點且離他最近的。這裡我們使用了 treemap 的 tailmap 方法,具體 api 可以看文件。

get 方法中,和 put 步驟相同,否則是取不到物件的。

具體尋找節點的方式如圖:

相同的測試用例,執行結果如下:

找到了之前所有的節點。解決了普通 hash 的問題。

**比較簡單,主要是通過 jdk 自帶的 treemap 實現的尋找臨近節點。當然,我們這裡也只是測試了新增,關於修改還沒有測試,但思路是一樣的。這裡只是做乙個拋磚引玉。

同時,我們也沒有實現虛擬節點,感興趣的朋友可以嘗試一下。

good luck!!!!

一致性hash演算法 面試必備 一致性hash演算法

最近公司在招人,我們準備的問題中有一道是關於一致性hash演算法的問題,只有一些面試者能夠回答上來,而且答的也不是很全面,有的面試者只是聽說過,有的連聽都沒聽過,下面我把一致性hash演算法整理一下分享給大家 一致性雜湊演算法在1997年由麻省理工學院的karger等人在解決分布式cache中提出的...

一致性hash演算法虛擬節點 一致性hash演算法

hash 演算法也叫做雜湊演算法,他可以讓任意長度的資料m對映成為長度固定的值h。hash演算法的第乙個作用就是資料的快速儲存與查詢。寫過程式的人都知道,基本上主流的程式語言裡面都有個資料結構叫做map dictionary或者 hash table 它是根據key來直接訪問結果的資料結構。key的...

一致性hash演算法

july部落格16章開始 第一題 全排列,輸入乙個字串,列印出該字串中字元的所有排列 1.個人思路 回溯法建立的排序樹 2.july部落格 遞迴實現,依次固定第乙個字母,後面的交換,和上面描述的使用回溯法相似 c stl 演算法 next permutation的思想,關於next permutat...