我正在研究在我寫的一些java代碼中使用consistent hash算法。番石榴哈希圖書館有一個consistentHash(HashCode, int)
方法,但the documentation是相當缺乏。我最初的希望是,我只需使用consistentHash()
即可獲得簡單的會話親和力,從而有效地分配一組後端服務器的負載。我應該如何使用番石榴的散列#consistentHash?
有沒有人有如何使用這種方法的現實世界的例子?特別是我關心的是如何管理從目標範圍中移除一個桶。
例如:
@Test
public void testConsistentHash() {
List<String> servers = Lists.newArrayList("server1", "server2", "server3", "server4", "server5");
int bucket = Hashing.consistentHash(Hashing.md5().hashString("someId"), servers.size());
System.out.println("First time routed to: " + servers.get(bucket));
// one of the back end servers is removed from the (middle of the) pool
servers.remove(1);
bucket = Hashing.consistentHash(Hashing.md5().hashString("blah"), servers.size());
System.out.println("Second time routed to: " + servers.get(bucket));
}
信息到輸出:
First time routed to: server4 Second time routed to: server5
我想是該標識符(「someId」)除去的服務器較早後映射到相同的服務器在列表中。所以在上面的示例中,刪除後我想我想要存儲區0映射到「server1」,存儲區1映射到「server3」,存儲區2映射到「server4」,存儲區3映射到「server5」。
我是否應該維護一個單獨的(比列表更復雜的)數據結構來管理桶的移除和添加?我想我已經設想了一個更復雜的哈希API,它可以在添加和刪除特定桶之後管理重新映射。
注:我知道示例代碼是使用一個小輸入和桶集。我在100個桶中輸入了1000個輸入,並且結果是相同的。當我將buckets
更改爲99,並將存儲區99分配到剩餘的99個存儲區時,映射到存儲區0-98的輸入保持不變。
您注意的是正確的...但你可以看到,番石榴什麼都不知道關於你的清單,除了它的尺寸,你呢?所以它不能做其他事情。 – maaartinus
我認爲這是您真正想要的文檔鏈接:http://docs.guava-libraries.googlecode.com/git-history/release13/javadoc/com/google/common/hash/Hashing.html#consistentHash%28com。 google.common.hash.HashCode,%20int%29 - 雖然這確實沒有太多,您還有什麼感覺應該說? –
@Kevin - 文檔可能是O.K.如果在最後增加/刪除的要求再多一個字的話。我發佈了我的問題,因爲我希望我的解釋是錯誤的,並且有一些顯而易見的方式來管理我沒有想到的bucket操作。在開始維基百科條目並閱讀那裏引用的java實現之後,我得到了番石榴方法,所以我想我期望看到更接近這兩篇文章描述的東西(更像克里斯對下面答案中的內容的描述)。 – GamingBuck