Modélisation des données à Cassandra

Modélisation des données à Cassandra

1. Vue d'ensemble

Cassandra est une base de données NoSQL offrant une haute disponibilité et une évolutivité horizontale sans compromettre les performances.

Pour obtenir les meilleures performances de Cassandra, nous devons soigneusement concevoir le schéma autour des modèles de requête spécifiques au problème métier concerné.

Dans cet article, nous passerons en revue certains des concepts clés autour dehow to approach data modeling in Cassandra.

Avant de continuer, vous pouvez parcourir notre articleCassandra with Java pour comprendre les bases et comment vous connecter à Cassandra en utilisant Java.

2. Clé de partition

Cassandra est une base de données distribuée dans laquelle les données sont partitionnées et stockées sur plusieurs nœuds au sein d'un cluster.

La clé de partition est composée d'un ou plusieurs champs de données et estused by the partitioner to generate a token via hashing to distribute the data uniformly across a cluster.

3. Clustering

Une clé de clustering est composée d'un ou de plusieurs champs. Elle permet de classer ou de regrouper des lignes avec la même clé de partition et de les stocker dans un ordre trié.

Disons que nous stockons des données de séries chronologiques dans Cassandra et que nous souhaitons récupérer les données dans l'ordre chronologique. Une clé de regroupement comprenant des champs de données de série chronologique sera très utile pour une récupération efficace des données pour ce cas d'utilisation.

Remarque: La combinaison de la clé de partition et de la clé de cluster constitue la clé primaire et identifie de manière unique tout enregistrement dans le cluster Cassandra.

4. Directives concernant les modèles de requête

Avant de commencer par la modélisation des données dans Cassandra, nous devons identifier les modèles de requête et veiller à ce qu’ils respectent les consignes suivantes:

  1. Chaque requête doit récupérer les données d'une seule partition

  2. Nous devrions garder trace de la quantité de données stockées dans une partition, car Cassandra a des limites concernant le nombre de colonnes pouvant être stockées dans une seule partition.

  3. Il est possible de dénormaliser et de dupliquer les données pour prendre en charge différents types de modèles de requête sur les mêmes données.

Sur la base des consignes ci-dessus, examinons certains cas d'utilisation réels et la manière dont nous modéliserons les modèles de données Cassandra pour eux.

5. Exemples de modélisation de données du monde réel

5.1. Messages Facebook

Supposons que nous stockions les publications Facebook de différents utilisateurs dans Cassandra. L’un des modèles de requête les plus courants consiste à récupérer les meilleurs messages «N» publiés par un utilisateur donné.

Ainsi,we need tostore all data for a particular user on a single partition selon les directives ci-dessus.

En outre, l’utilisation de l’horodatage de la publication comme clé de regroupement sera utile pour récupérer plus efficacement les messages «N» les plus importants.

Définissons le schéma de la table Cassandra pour ce cas d'utilisation:

CREATE TABLE posts_facebook (
  user_id uuid,
  post_id timeuuid,
  content text,
  PRIMARY KEY (user_id, post_id) )
WITH CLUSTERING ORDER BY (post_id DESC);

Maintenant, écrivons une requête pour trouver les 20 premiers messages de l'utilisateurAnna:

SELECT content FROM posts_facebook WHERE user_id = "Anna_id" LIMIT 20

5.2. Gymnases à travers le pays

Supposons que nous stockions les détails des différents gymnases partenaires dans les différentes villes et états de nombreux pays et que nous aimerions aller les chercher pour une ville donnée.

Disons également que nous devons renvoyer les résultats en triant les salles de sport en fonction de leur date d’ouverture.

Selon les directives ci-dessus, nous devrions stocker les salles de sport situées dans une ville donnée d'un État et d'un pays spécifiques sur une partition unique et utiliser la date d'ouverture et le nom de la salle de sport comme clé de regroupement.

Définissons le schéma de la table Cassandra pour cet exemple:

CREATE TABLE gyms_by_city (
 country_code text,
 state text,
 city text,
 gym_name text,
 opening_date timestamp,
 PRIMARY KEY (
   (country_code, state_province, city),
   (opening_date, gym_name))
 WITH CLUSTERING ORDER BY (opening_date ASC, gym_name ASC);

Examinons maintenant une requête qui récupère les dix premiers gymnases par leur date d'ouverture pour la ville de Phoenix aux États-Unis. Etat de l'Arizona:

SELECT * FROM gyms_by_city
  WHERE country_code = "us" AND state = "Arizona" AND city = "Phoenix"
  LIMIT 10

Voyons ensuite une requête qui récupère les dix salles de sport récemment ouvertes de la ville de Phoenix aux États-Unis. Etat de l'Arizona:

SELECT * FROM gyms_by_city
  WHERE country_code = "us" and state = "Arizona" and city = "Phoenix"
  ORDER BY opening_date DESC
  LIMIT 10

Remarque: comme l'ordre de tri de la dernière requête est opposé à l'ordre de tri défini lors de la création de la table, la requête s'exécutera plus lentement car Cassandra récupérera d'abord les données, puis les triera en mémoire.

5.3. Clients et produits du commerce électronique

Supposons que nous exploitions une boutique de commerce électronique et que nous stockions les informationsCustomer etProduct dans Cassandra. Examinons certains des modèles de requête courants dans ce cas d'utilisation:

  1. Obtenir les informations deCustomer

  2. Obtenir les informations deProduct

  3. Obtenez tous lesCustomers qui aiment unProduct donné

  4. Obtenez tous lesProducts commeCustomer likes

Nous allons commencer par utiliser des tables séparées pour stocker les informationsCustomer etProduct. Cependant, nous devons introduire une quantité assez importante de dénormalisation pour prendre en charge les troisième et quatrième requêtes présentées ci-dessus.

Nous allons créer deux autres tables pour y parvenir - «Customer_by_Product» et «Product_by_Customer».

Examinons le schéma de la table Cassandra pour cet exemple:

CREATE TABLE Customer (
  cust_id text,
  first_name text,
  last_name text,
  registered_on timestamp,
  PRIMARY KEY (cust_id));

CREATE TABLE Product (
  prdt_id text,
  title text,
  PRIMARY KEY (prdt_id));

CREATE TABLE Customer_By_Liked_Product (
  liked_prdt_id text,
  liked_on timestamp,
  title text,
  cust_id text,
  first_name text,
  last_name text,
  PRIMARY KEY (prdt_id, liked_on));

CREATE TABLE Product_Liked_By_Customer (
  cust_id text,
  first_name text,
  last_name text,
  liked_prdt_id text,
  liked_on timestamp,
  title text,
  PRIMARY KEY (cust_id, liked_on));

Remarque: pour prendre en charge à la fois les requêtes, les produits récemment aimés par un client donné et les clients qui ont récemment aimé un produit donné, nous avons utilisé la colonne «liked_on» comme clé de clustering.

Examinons la requête pour trouver les dix clients qui ont le plus récemment aimé le produit "Pepsi":

SELECT * FROM Customer_By_Liked_Product WHERE title = "Pepsi" LIMIT 10

Et voyons la requête qui recherche les produits récemment appréciés (jusqu'à dix) par un client nommé "Anna":

SELECT * FROM Product_Liked_By_Customer
  WHERE first_name = "Anna" LIMIT 10

6. Modèles de requête inefficaces

En raison de la manière dont Cassandra stocke les données, certains modèles de requête ne sont pas du tout efficaces, notamment:

  • Fetching data from multiple partitions - cela nécessitera un coordinateur pour récupérer les données de plusieurs nœuds, les stocker temporairement dans le tas, puis agréger les données avant de renvoyer les résultats à l'utilisateur

  • Join-based queries - en raison de sa nature distribuée, Cassandra ne prend pas en charge les jointures de table dans les requêtes de la même manière qu'une base de données relationnelle, et par conséquent,queries withjoins will be slower and can also lead to inconsistency and availability issues

7. Conclusion

Dans ce tutoriel, nous avons présenté plusieurs meilleures pratiques concernant la manière d’aborder la modélisation des données à Cassandra.

Comprendre les concepts de base et identifier les modèles de requête à l'avance est nécessaire pour concevoir un modèle de données correct qui optimise les performances d'un cluster Cassandra.