background success stories

Comment gérer la consistance des données sous Cassandra quand on a plusieurs tables contenant les mêmes données.

Nous allons traiter dans cet article de la gestion de la consistance des données dupliquées entre plusieurs tables. Pour rappel sous Cassandra, la duplication des données n’est pas considérée comme un antipattern comme sous certains SGBDs, on va au contraire préférer dupliquer les données afin d’avoir des structures de tables optimisées pour les requêtes.

Problématique : Lors d’une action que ce soit ajout, suppression, modification de données, il faut modifier toutes les tables où sont dupliquées les données. Il est donc impératif de maintenir un plan/modèle de données à jour. Mais la vraie problématique est si un insert/delete/update échoue sur une ou plusieurs tables pour une raison X, on aura un problème de cohérence puisque certaines tables auront étés mises à jour et d’autres non.

Afin de gérer la consistance des données dupliquées à travers plusieurs tables, nous recommandons deux options :

Option 1 : Gestion via l’application

Nous pouvons gérer ce problème de consistance via l’application en mettant en place une gestion efficace des codes retours et retries.

Exemple : Si un insert doit être exécuté sur plusieurs tables (données dupliquées) échoue sur certaines tables, dans ce cas-là on fait un retry des données qui n’ont pas été insérées. Ces opérations de retries doivent être gérées par l’application en utilisant les options que le driver Cassandra met à disposition.

Problèmes :

  • Si l’action voulue était un update ou un delete, il faut avoir préalablement sauvegardé les données pour les réinsérer, ceci devient vite une usine à gaz.
  • De plus au niveau des performances  il est intéressant/vital de paralléliser les requêtes.

Option 2 : Gestion via la fonction Batch Logged

La fonction batch permet de garantir l’atomicité des opérations (Lien vers la documentation officielle : https://docs.datastax.com/en/cql/3.3/cql/cql_using/useBatch.html ).

Exemple :

DEBUT BATCH

INSERT INTO table1 (champ1,champ2,champ3) VALUES (valeur1, valeur2, valeur3);

INSERT INTO table2 (champ1,champ2) VALUES (valeur1, valeur2);

FIN BATCH

Par contre les batchs ont un coût de performance plus élevé (+30% en moyenne que les opérations d’insertions).

Problème :

Conclusion :

Si les opérations ont une contrainte de temps et modifient plusieurs partitions, l’option 1 serait plus à même de convenir (en ayant une parallélisation des requêtes et une gestion de retries). L’option 2 est plus facile à gérer de point de vue applicatif, mais elle vient avec des limites à ne pas prendre à la légère. Par le passé nous aurions pu rajouter une troisième option nommée : les vues matérialisées mais ces dernières sont désormais déconseillées suite aux différents problèmes rencontrés lors de l’implémentation de ces dernières.

Pour conclure cet article, nous avons vu ensemble qu’il n’y a pas de solution « magique » permettant d’obtenir une consistance forte entre plusieurs tables pour les données qui sont dupliquées sous Cassandra sans avoir « x » contraintes. Il convient lors de la réflexion du schéma (Rappel : 90 % du temps doit être sur la réflexion du schéma) de se poser les bonnes questions, de bien tester les solutions sur des données se rapprochant au maximum des données réelles et sur une architecture équivalente.

Si vous souhaitez une analyse ou une optimisation de votre modèle de données, n’hésitez pas à nous contacter.