3

非常に幅の広い C* テーブルがあります。それらが広くなりすぎるのを防ぐために、私は自分にぴったりの戦略に出会いました. こちらの動画で紹介されました。 パーティションを賢くバケット化する

この戦略の良い点は、「ルックアップ テーブル」が必要ないことです (高速です)。悪い点は、バケットの最大量を知る必要があり、最終的にバケットがなくなることです。使用します (スケーラブルではありません)。バケットの最大サイズを知っているので、これを試してみます。

テーブルの主キーからハッシュを計算することにより、これを残りの主キーとともにバケット部分として使用できます。

ハッシュが特定の主キーに対して常に同じであることを確認するために、次の方法を思いつきました(と思いますか?)。

グアバハッシュの使用:

public static String bucket(List<String> primKeyParts, int maxBuckets) {

    StringBuilder combinedHashString = new StringBuilder();
    primKeyParts.forEach(part ->{
        combinedHashString.append(
            String.valueOf(
                Hashing.consistentHash(Hashing.sha512()
                    .hashBytes(part.getBytes()), maxBuckets)
            )
        );
    });
    return combinedHashString.toString();
}

私が sha512 を使用する理由は、最大 256 文字 (512 ビット) の文字列を持つことができるようにするためです。そうしないと、結果が同じになることはありません (私のテストによると思われます)。

私はハッシングの第一人者とはほど遠いので、次の質問をしています。

要件:異なるノード/マシンでの異なる JVM 実行間で、特定の Cassandra プライマリ キーの結果は常に同じである必要がありますか?

  1. 言及された方法に頼って仕事をすることはできますか?
  2. 特定の文字列に対して常に同じ結果が得られるように、大きな文字列をハッシュするより良い解決策はありますか?
  3. 常に文字列からハッシュする必要がありますか?それとも、C* の主キーに対してこれを行うより良い方法があり、常に同じ結果を生成する可能性がありますか?

特定のテーブルのデータ モデリングについて話し合うつもりはありません。バケット戦略が必要なだけです。

編集:

さらに精巧にしてこれを思いついたので、文字列の長さは任意です。これについてどう思いますか?

public static int murmur3_128_bucket(int maxBuckets, String... primKeyParts) {

    List<HashCode> hashCodes = new ArrayList();
    for(String part : primKeyParts) {
        hashCodes.add(Hashing.murmur3_128().hashString(part, StandardCharsets.UTF_8));
    };
    return Hashing.consistentHash(Hashing.combineOrdered(hashCodes), maxBuckets);
}
4

1 に答える 1