非常に幅の広い 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 プライマリ キーの結果は常に同じである必要がありますか?
- 言及された方法に頼って仕事をすることはできますか?
- 特定の文字列に対して常に同じ結果が得られるように、大きな文字列をハッシュするより良い解決策はありますか?
- 常に文字列からハッシュする必要がありますか?それとも、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);
}