pres-nosql/presentation.md
2025-06-24 14:59:05 +02:00

381 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
marp: true
header: Cassandra et les bases de données NoSQL
footer: 3SE • Matthieu Jolimaitre • 24/06/2025
---
<!-- paginate: true -->
<style>
.cent {
display: flex;
align-items: center;
justify-content: space-around;
margin: 2rem;
}
small {
font-size: 0.75rem;
}
.cols {
display: flex;
align-items: center;
justify-content: space-around;
}
</style>
# Cassandra et les bases de données NoSQL : architecture, performances et cas dusage
Analyser les principes de Cassandra, ses avantages par rapport aux bases relationnelles, et ses cas dapplication dans le Big Data.
> Matthieu Jolimaitre
<br>
<div class="cent">
<img width="300" src="./diagrams/cassandra_logo.png">
<img width="300" src="./diagrams/NoSQL_logo.jpg">
</div>
---
## Sommaire
<small>
- Introduction aux bases NoSQL
- Pourquoi NoSQL ?
- Catégories (clé-valeur, document, colonne, graphe)
- Architecture de Cassandra
- Peer-to-peer, partitionnement, réplication
- Consistency levels et CAP theorem
- Modèle de données et requêtage
- Tables dénormalisées, CQL (Cassandra Query Language)
- Performances et cas dusage
- Écritures rapides, scalabilité horizontale
- Cas détude
- Limites et comparaison avec dautres NoSQL
</small>
---
## Introduction aux bases NoSQL
> Not Only SQL
![bg fit right](./diagrams/not_only_sql_venn.png)
---
#### Le SQL
Un modèle de donnée appuyé sur des tableaux et des scripts de modification.
<br>
```sql
INSERT INTO checkouts
(id, user_id, book_id, checkout_date, return_date)
VALUES
(1, 1, 1, '2017-10-15 14:43:18', NULL),
(2, 1, 2, '2017-10-05 16:22:44', '2017-10-13 13:00:12'),
(3, 2, 2, '2017-10-15 11:11:24', '2017-10-22 17:47:10'),
(4, 5, 3, '2017-10-15 09:27:07', NULL);
```
![bg fit right](./diagrams/sql_table_preview.png)
---
### Pourquoi NoSQL ?
<div class="cols">
<div>
- Utiliser de nouvelles topologies.
- Fournir des interfaces de modification plus adaptés à la donnée.
- Se détacher du modèle de données arrangées en tables.
- Modéliser des états plus complexes.
- Optimiser en fonction des données.
</div>
<div>
- Autoriser des transgressions du principe ACID.
- Atomicité.
- Consistance.
- Isolation.
- Durabilité.
- Apparition de nouveaux principes BASE.
- Basiquement Disponible.
- Souplesse de l'état.
- Éventuellement consistent.
</div>
</div>
---
### Catégories
<small>
- **clé-valeur** : Les données sont des valeurs accessibles par leur clé (souvent un texte).
- **document** : Clé-valeur optimisé pour les données structurées.
- **colonne larges** : Les données sont mises en tableau, mais le schéma dun même tableau peut varier selon les lignes.
- **graphe** : Les données sont arrangées dans des nœuds pouvant être référencés dans dautres nœuds.
</small>
![bg fit right](./diagrams/nosql_categories.png)
---
## Architecture de Cassandra
- Suit un modèle de donnée en **Large colonnes**.
- **Distribuée** : Les données sont répliquées sur plusieurs 'nœuds' pour permettre une expansion horizontale et pour se rendre résilient aux pannes.
- Garanti une **consistance éventuelle**.
![bg fit right](./diagrams/cassandra_architecture.png)
---
### Peer-to-peer, partitionnement, réplication
Différentes techniques pour répartir et synchroniser les données dans un système distribué.
![bg fit right](./diagrams/nodes_gossip_example.png)
---
#### pair-à-pair
Pour synchroniser les changements de données, **la grappe nutilise pas un nœud autoritaire** orchestrant la synchronisation.
À la place, les nœuds communiquent périodiquement par deux, sans hiérarchie, en utilisant un **protocole de 'potins'**.
![bg fit right](./diagrams/gossip_protocol.png)
---
#### Partitionnement
<small>
Pour réduire la charge dune requête sur la grappe, les données sont partitionnées entre les différents nœuds.
Cest à dire qu**une donnée napparaitra que sur 'certains' nœuds** de la grappe, et quune requête accédant à cette donnée devra être traitée par un de ces nœuds.
Pour une donnée partitionnée, ladresse du nœud contenant une ligne est comprise **dans sa clé primaire**.
</small>
![bg fit right](./diagrams/partition_example.png)
---
#### Réplication
<small>
Pour diminuer le **risque de perte** de donnée et augmenter la **disponibilité** dune donnée, la réplication sert à contenir la même donnée dans plusieurs nœuds.
Concrètement, les partitions ont chacune un **facteur de réplication** RF, et **une partition est copiée vers RF nœuds** différents à partir dun nœud responsable de cette partition.
Ce système est implémenté avec un mécanisme de jeton.
</small>
![bg fit right](./diagrams/replication_example.jpg)
---
### Consistency levels et CAP theorem
Les bases de données distribués ont trois aspects propres :
- **Consistance** : Toutes les lectures dune même donnée retournent la version la plus récente de cette donnée.
- **Disponibilité** : Maximiser le taux de réponse aux requêtes saines.
- **Tolérance au partitionnement** : La dégradation de certains nœuds nentraine pas une dégradation du système.
---
### Consistency levels et CAP theorem
Le 'théorème de CAP' énonce quune base de donnée distribuée **doit se focaliser sur deux aspects**, car il est impossible den atteindre deux sans en sacrifier un.
![bg fit right](./diagrams/CAP_theorem_venn.png)
---
## Modèle de données et requêtage
Cassandra suit un modèle de **tables à colonnes larges**, les colonnes sont de taille et structure dynamique : Le même tableau peut avoir des lignes de colonnes différentes.
Cela augmente la **flexibilité de modélisation** et diminue les **efforts de mise à jour du schéma** dun tableau.
![bg fit right](./diagrams/cassandra_data_model.png)
---
### Tables dénormalisées, CQL (Cassandra Query Language)
<small>
Le modèle de donnée est normalisé lorsqu'il réponds à plusieurs exigences :
- **UNF** : Aucune colonne n'est dupliquée.
- **1NF** : Les colonnes doivent contenir des valeurs primitives, et non des agrégats.
- **2NF** : Chaque colonne dun tableau dépends de toutes les clés primaires de ce tableau.
- **3NF** : Les colonnes ne dépendent uniquement des clés primaires de leur tableau.
</small>
```
Normalisé │ Dénormalisé
┌──────────────┐ ┌───────────────┐ │ ┌─────────────────────────┐ ┌───────────────┐
│USERS BY EMAIL│ │USERS │ │ │USERS BY EMAIL │ │USERS │
├─────┬────────┤ ├──┬────────┬───┤ │ ├──┬─────┬────────┬───────┤ ├──┬────────┬───┤
│email│ user_id│ │id│ name│age│ │ │id│email│ name│user_id│ │id│ name│age│
├─────┼────────┤ ├──┼────────┼───┤ │ ├──┼─────┼────────┼───────┤ ├──┼────────┼───┤
│b@o.b│ 1│ │ 1│ bob│ 19│ │ │ 1│b@o.b│ bob│ 1│ │ 1│ bob│ 19│
│c@r.l│ 2│ │ 2│ charlie│ 23│ │ │ 2│c@r.l│ charlie│ 2│ │ 2│ charlie│ 23│
└─────┴────────┘ └──┴────────┴───┘ │ └──┴─────┴────────┴───────┘ └──┴────────┴───┘
```
---
- La dénormalisation :
- Réduit le nombre dopération par lecture.
- Augmente le nombre dopération par écriture.
<br>
```
Normalisé │ Dénormalisé
┌──────────────┐ ┌───────────────┐ │ ┌─────────────────────────┐ ┌───────────────┐
│USERS BY EMAIL│ │USERS │ │ │USERS BY EMAIL │ │USERS │
├─────┬────────┤ ├──┬────────┬───┤ │ ├──┬─────┬────────┬───────┤ ├──┬────────┬───┤
│email│ user_id│ │id│ name│age│ │ │id│email│ name│user_id│ │id│ name│age│
├─────┼────────┤ ├──┼────────┼───┤ │ ├──┼─────┼────────┼───────┤ ├──┼────────┼───┤
│b@o.b│ 1│ │ 1│ bob│ 19│ │ │ 1│b@o.b│ bob│ 1│ │ 1│ bob│ 19│
│c@r.l│ 2│ │ 2│ charlie│ 23│ │ │ 2│c@r.l│ charlie│ 2│ │ 2│ charlie│ 23│
└─────┴────────┘ └──┴────────┴───┘ │ └──┴─────┴────────┴───────┘ └──┴────────┴───┘
```
---
#### Cassandra Query Language : Un DSL pour Cassandra
```sql
/* Create a new keyspace in CQL */
CREATE KEYSPACE myDatabase WITH replication =
{'class': 'SimpleStrategy', 'replication_factor': 1};
/* Create a new database in SQL */
CREATE DATABASE myDatabase;
```
```sql
/* Expiring Data in 24 Hours */
INSERT INTO myTable (id, myField) VALUES (2, 9) USING TTL 86400;
```
- Les écritures sont peu coûteuses, donc il est encouragé de créer des tables redondantes plutôt que des requêtes complexes.
- Le filtrage est désactivé par défaut.
---
## Performances et cas dusage
- Distribué
- **Répliqué** : Forte résilience.
- **Partitionné** : Bonne mise à léchelle.
- **NoSQL** : Flexibilité.
- Modéliser sa donnée avec moins de contraintes.
- Adapter les schémas pour améliorer les performances.
---
### Écritures rapides, scalabilité horizontale
Cassandra est une base de donnée optimisée pour la **mise à léchelle**, cest à dire offrir une grande disponibilité au détriment de la **consistance forte des données**.
Donc elle est recommandée dans les cas où il y a une haute contention décritures, et où la consistance de la donnée n'est pas cruciale.
![bg fit right](./diagrams/cassandra_scalability_benchmark.png)
---
### Cas détude : Discord
![bg right](./diagrams/discord_background.webp)
> July, we announced 40 million messages a day, in December we announced 100 million. How do we do it? Cassandra!
>
> <br>
>
> https://discord.com/blog/how-discord-stores-billions-of-messages
---
#### Requirements
> We defined our requirements:
>
> - **Linear scalability** : We do not want to reconsider the solution later or manually re-shard the data.
> - **Low maintenance** : It should just work once we set it up. We should only have to add more nodes as data grows.
> - **Predictable performance** : We have alerts go off when our APIs response time 95th percentile goes above 80ms. We also do not want to have to cache messages in Redis or Memcached.
> - **Not a blob store** : Writing thousands of messages per second would not work great if we had to constantly deserialize blobs and append to them.
>
> Cassandra was the only database that fulfilled all of our requirements.
---
#### Distribution
> Here is a simplified schema for our messages table (this omits about 10 columns).
>
> ```sql
> CREATE TABLE messages (
> channel_id bigint, bucket int, message_id bigint, author_id bigint, content text,
> PRIMARY KEY ((channel_id, bucket), message_id)
> ) WITH CLUSTERING ORDER BY (message_id DESC);
> ```
- Nous notons une clé de partitionnement composite, utilisant lID dun salon ET un nombre arbitraire pour contrôler la taille des partitions.
---
### Résultats
![](./diagrams/discord_perf.png)
> At the beginning of 2022, it had 177 nodes with trillions of messages
---
## Limites et comparaison avec dautres NoSQL
---
#### Faible consistance
- Une **consistance éventuelle** entraine un risque de **courses de données** pouvant rendre létat du service invalide.
![bg fit right](./diagrams/race_condition.png)
---
#### Coût de la mise à léchelle
![bg fit right](./diagrams/scaling_comparison.png)
- Les performances sur un seul noeud sont relativement basses.
---
## Fin