私が書いているJavaコードで一貫したハッシュアルゴリズムを使用することを検討しています。guava Hashing ライブラリにはconsistentHash(HashCode, int)
メソッドがありますが、ドキュメントはかなり不足しています。私の最初の希望は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));
}
出力につながります:
最初のルーティング先: server4 2 回目のルーティング先: server5
私が望むのは、リストの前のサーバーを削除した後、その識別子 (「someId」) を同じサーバーにマップすることです。上記のサンプルでは、削除後、バケット 0 を「server1」に、バケット 1 を「server3」に、バケット 2 を「server4」に、バケット 3 を「server5」にマッピングしたいと思います。
バケットの削除と追加を管理するために、別の (リストよりも複雑な) データ構造を維持する必要がありますか? おそらく、特定のバケットを追加および削除した後の再マッピングを管理する、より複雑なハッシュ API を想定していたと思います。
注:サンプル コードが小さな入力とバケット セットを使用していることはわかっています。100 個のバケットにわたる数千の入力でこれを試しましたが、結果は同じです。バケット 0 ~ 98にマップされる入力は、 を 99 に変更しても同じままで、buckets
バケット 99 が残りの 99 バケットに分散されます。