Le DJ qui voulait être cohérent

Jojo Beat et Jojo EnMousse, les deux DJs qui souhaitent mettre en place une plate-forme de partage de musique entre les différents DJs du monde n'arrivent pas à se mettre d'accord sur comment configurer leur cluster.

  • Jojo Beat est persuadé qu'il va y avoir énormément de monde qui va utiliser cette plate-forme, et pense qu'il serait bon d'avoir un système robuste face aux pannes, et qui puisse être le plus cohérent possible, quitte à perdre un peu de performance.

  • Jojo EnMousse lui par contre pense que l'équipement qu'ils achètent est le plus haut de gamme, qu'il ne tombera jamais en panne, et que ça ne sert à rien de perdre de la performance. Pour lui, autant ne pas répliquer les données, cela ne sert à rien.

Ainsi, n'arrivant pas à se mettre d'accord, les deux essaient de mettre en place les solutions, afin de montrer à l'autre qu'il a tort.

Commençons dans un premier temps à nous pencher sur la solution que Jojo Beat souhaite mettre en place, à savoir avoir un système cohérent et robuste face aux pannes.

Question

Il faut commencer par vérifier que nos nœuds dans le cluster de CCM fonctionnent toujours. Pour cela, utiliser la commande "ccm status".

Question

Se connecter au nœud 1 avec CQLSH afin de pouvoir commencer à faire des requêtes.

Solution

1
ccm node1 cqlsh

Vous devriez avoir le retour suivant :

1
Connected to clusterDjs at 127.0.0.1:9042.
2
[cqlsh 5.0.1 | Cassandra 2.1.5 | CQL spec 3.2.0 | Native protocol v3]
3
Use HELP for help.
4
cqlsh> 
5

Question

D'après vous, quel est le Replication Factor à mettre en place pour avoir une assez bonne gestion des pannes dans notre KEYSPACE ? Mettez en place le KEYSPACE ksJojoB avec le Replication Factor choisi.

Indice

Rappel : le Replication Factor est la valeur du nombre de copies des données dans le cluster.

Indice

Il faut utiliser un attribut 'replication_factor' : XXX lors de la création du KEYSPACE.

Indice

On utilisera la SimpleStrategy car nous avons un unique Data-Center en local.

Solution

Ici nous avons un cluster de 5 nœuds.

Si nous mettons un RF=1, alors la tolérance aux pannes est quasi nulle. En effet, si un nœud tombe en panne, alors nous n'avons plus du tout accès aux données associées.

Si nous mettons un RF=5, alors les temps d'écriture seront plus longs. Mais la robustesse face aux pannes est beaucoup plus forte.

Un bon compromis ici est donc RF=3.

1
create keyspace ksJojoB WITH REPLICATION = {'class':'SimpleStrategy', 'replication_factor':3};

Question

Entrer dans le KEYSPACE, et créer une table remix avec les attributs ID, nom, dj. L'ID est la Primary Key. Insérez une première ligne avec les valeurs suivantes :

id = 1 ; nom = 'monRemix', dj='Jojo Beat'.

Vérifiez que l'insertion s'est bien déroulée.

Indice

Pour entrer dans un KEYSPACE, il faut utiliser la commande "use".

Indice

Le langage CQLSH est très ressemblant au SQL.

Solution

1
use ksJojoB;
1
create table remix(id int, nom text, dj text, Primary Key(id));
1
insert into remix (id, nom, dj) values (1, 'monRemix', 'Jojo Beat');
1
select * from remix;

Vous devriez avoir le retour suivant :

1
 id | dj        | nom
2
----+-----------+----------
3
  1 | Jojo Beat | monRemix
4
5
(1 rows)
6

Question

Récupérez le token référençant la ligne de l'insertion précédente. Récupérez les autres colonnes également.

Indice

Utilisez un select token( XXX ) ...

Solution

1
select token(id), id, nom, dj from remix;

Vous devriez avoir le retour suivant :

1
 token(id)            | id | nom      | dj
2
----------------------+----+----------+-----------
3
 -4069959284402364209 |  1 | monRemix | Jojo Beat
4
5
(1 rows)
6

Le token récupéré est en réalité la valeur après le hachage de la primary key (id). Ainsi, cette valeur va permettre de savoir exactement dans quel nœud cette ligne va être écrite.

Question

Quitter CQLSH avec la commande "quit". Puis afficher la table des tokens dans le cluster.

Solution

1
ccm node1 nodetool ring

Ici, nous déduisons que le nœud 5 contiendra toutes les données qui auront un token entre 553402...... à 184467.....

Imaginons qu'une donnée doit initialement être intégrée dans le nœud 3, et que le RF=3, alors la donnée sera répliquée dans le nœud 4 et le nœud 5.

Question

Nous pouvons savoir exactement dans quel nœud va être répliquée une insertion avec la commande suivante.

1
ccm [nom_du_noeud] nodetool getendpoints [nom_keyspace] [nom_table] [valeur_primary_key]

Testez la commande suivante. Qu'en déduisez vous ?

1
ccm node1 nodetool getendpoints ksjojob remix 1

Solution

Vous devriez avoir le retour suivant :

1
127.0.0.3
2
127.0.0.4
3
127.0.0.5

La ligne qui aura pour Primary Key 1 dans la table remix du keyspace ksJojoB sera copiée dans les nœuds 3/4/5.

Question

(Optionnel) Vérifiez la copie de la donnée sur les nœuds 4 et 5.

Indice

Utilisez la commande suivante :

1
ccm <node> json -k <keyspace> -c <columnfamily> test;cat test

Solution

1
ccm node4 json -k ksjojob -c remix test;cat test
1
[
2
{"key": "1",
3
 "cells": [["","",1483875654857606],
4
           ["dj","Jojo Beat",1483875654857606],
5
           ["nom","monRemix",1483875654857606]]}
6
]
1
ccm node5 json -k ksjojob -c remix test;cat test
1
[
2
{"key": "1",
3
 "cells": [["","",1483875654857606],
4
           ["dj","Jojo Beat",1483875654857606],
5
           ["nom","monRemix",1483875654857606]]}
6
]

La donnée est donc bien contenue dans les nœuds 4 et 5.

Question

Maintenant que nous savons que notre dernier insert se trouve dans les nœuds 3 / 4 / 5, imaginons que le nœud 3 tombe en panne. Pourrons nous toujours avoir accès aux valeurs de la table remix sachant que le Consistency Level est à ONE ?

Solution

Oui car ces valeurs sont récupérables dans les nœuds 4 et 5. Testons le :

1
ccm node3 stop
2
ccm node1 cqlsh
1
use ksJojoB;
2
select * from remix;

Ce qui donne :

1
 id | dj        | nom
2
----+-----------+----------
3
  1 | Jojo Beat | monRemix
4
5
(1 rows)

Question

Vérifiez le Consistency Level.

Solution

1
cqlsh:ksjojob> CONSISTENCY 
2
Current consistency level is ONE.

Question

Que se passe-t-il si on update la ligne contenant l'id=1 alors que le nœud 3 est en panne ?

Indice

UPDATE remix SET nom='lemixduturfu' WHERE id=1 ;

Solution

Une ligne sera créée dans la table system.hints. Dès que le noeud 3 redevient en marche, alors on pourra update sa valeur.

1
select * from system.hints;

Ce qui donne :

1
target_id                            | hint_id                              | message_version | mutation
2
--------------------------------------+--------------------------------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------
3
 63569d42-a9d8-4b97-917c-00ab22df4a1e | 4d78d660-d59f-11e6-a37e-3b41757767cd |               8 | 0x000400000001000000010146d23ca0d59711e6a37e3b41757767cd7fffffff80000000000000000000000000000001000600036e6f6d00000005459485cbe8100000000c6c656d697864757475726675
4
5
(1 rows)

Question

Faites plusieurs updates, et regarder les modifications faites dans la table system.hints.

Solution

1
UPDATE remix SET nom='monpetitmix' WHERE id=1 ;
1
SELECT COUNT(*) from system.hints;

Le nombre le lignes dans la table system.hints augmente en fonction du nombre de UPDATE réalisés.

Question

Modifiez le Consistency Level à ALL. Essayez de faire un UPDATE. Cela ne fonctionne pas. A votre avis pourquoi ?

Indice

1
cqlsh> CONSISTENCY ALL
2
Consistency level set to ALL.
3

Indice

Si le Consistency Level vaut ALL, alors il vaut ALL en lecture et en écriture.

Solution

Cela ne fonctionne pas car le nœud 3 est DOWN. Or l'UPDATE doit être réalisé sur les nœuds 3, 4 et 5 avant qu'une réponse positive ne soit retournée au client.

La mise à jour est n'est donc pas possible.

1
Unavailable: code=1000 [Unavailable exception] message="Cannot achieve consistency level ALL" info={'required_replicas': 3, 'alive_replicas': 2, 'consistency': 'ALL'}

Question

Quittez CQLSH. Remettez le nœud 3 en route, et reconnectez vous au nœud 1 en CQLSH. Regardez le contenu de la table system.hints. Que déduisez-vous ?

Solution

1
quit;
2
ccm node3 start
3
ccm node1 cqlsh
4
select * from system.hints;

La table hints est vide. En effet, lorsque nous avons remis en route le nœud 3, alors les différents UPDATE ont été réalisés.