J'aurai des tables C* qui seront très larges. Pour éviter qu'ils ne deviennent trop larges, j'ai rencontré une stratégie qui pourrait bien me convenir. Elle est présentée dans cette vidéo. Mettez vos partitions à bon escient
L'avantage de cette stratégie est qu'elle ne nécessite pas de "look-up-table" (c'est rapide), l'inconvénient est qu'il faut connaître la quantité maximale de seaux et qu'on finit par ne plus avoir de seaux à utiliser (ce qui n'est pas évolutif). Je connais la taille maximale de mon seau, je vais donc essayer.
En calculant un hachage à partir des clés primaires de la table, on peut l'utiliser comme partie de seau avec le reste des clés primaires.
J'ai trouvé la méthode suivante pour être sûr (je pense ?) que le hash sera toujours le même pour une clé primaire spécifique.
Utilisation de Guava Hashing :
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();
}
La raison pour laquelle j'utilise sha512 est de pouvoir avoir des chaînes avec des caractères maximum de 256 (512 bit) sinon le résultat ne sera jamais le même (comme il semble d'après mes tests).
Je suis loin d'être un gourou du hachage, c'est pourquoi je pose les questions suivantes.
Exigence : Entre différentes exécutions de JVM sur différents nœuds/machines, le résultat devrait toujours être le même pour une clé primaire Cassandra donnée ?
- Puis-je compter sur la méthode mentionnée pour faire le travail ?
- Existe-t-il une meilleure solution pour hacher de grandes chaînes de caractères afin de produire toujours le même résultat pour une chaîne donnée ?
- Dois-je toujours effectuer un hachage à partir d'une chaîne de caractères ou existe-t-il une meilleure façon de procéder pour une clé primaire C* et produire toujours le même résultat ?
S'il vous plaît, je ne veux pas discuter de la modélisation des données pour une table spécifique, je veux juste avoir une stratégie de seau.
EDITAR:
J'ai poussé plus loin et j'ai trouvé ceci pour que la longueur de la corde puisse être arbitraire. Que dites-vous de celle-ci ?
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);
}