在前文分布式理論(八)—— 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...