Outils pour utilisateurs

Outils du site


construire_un_cluster_cassandra_avec_plusieurs_instances_sur_le_meme_serveur

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

construire_un_cluster_cassandra_avec_plusieurs_instances_sur_le_meme_serveur [19/08/2013 20:27] (Version actuelle)
admin créée
Ligne 1: Ligne 1:
 +{{tag>​base_de_données cassandra centos}}
 +====== Construire un cluster Cassandra avec plusieurs instances sur le même serveur ======
 +
 +J'ai eu l'​occasion de travailler avec le moteur de base de données [[http://​cassandra.apache.org/​|Cassandra]],​ un moteur NoSQL qui est l'un des principaux projets de la [[http://​www.apache.org/​|Fondation Apache]].\\
 +\\
 +Personnellement,​ j'aime présenter Cassandra comme un moteur de base de données peer to peer. Chaque noeud est indépendant avec ses propres données, son IP, ect... Nous n'​avons pas ici un cluster actif/​passif avec un service qui tourne uniquement sur 1 noeud à la fois, ou de l'​actif/​actif avec partage des ressources disques comme pourrait le faire Oracle RAC.\\
 +\\
 +Quand on a accès à un environnement virtualisé avec plusieurs machines virtuelles, il est facile de monter un cluster Cassandra de 3-4 noeuds pour faire des tests. Mais malgré tout, passer d'une session SSH à une autre n'est pas simple.\\
 +\\
 +Pour pouvoir découvrir Cassandra, le plus facile selon moi a été de construire un serveur avec plusieurs instances dessus. Il est très facile d'​arrêter/​démarrer des instances, surveiller les concéquences de certaines commandes, le tout sur une seule machine.\\
 +\\
 +La société [[http://​www.datastax.com/​|Datastax]] met à disposition de la communauté un repository avec les paquets Cassandra RPM. Pour cette raison, j'ai utilisé une CentOS 6.4 pour faire ce serveur.
 +
 +===== Ajout du repository Datastax =====
 +
 +Editez le fichier /​etc/​yum.repos.d/​datastax.repo et copier/​coller le repository suivant :
 +<code - datastax.repo>​[cassandra12]
 +name= DataStax Repo for Apache Cassandra (Community)
 +baseurl=http://​rpm.datastax.com/​community/​
 +enabled=1
 +gpgcheck=0
 +</​code>​
 +
 +===== Installation de Cassandra 1.2 =====
 +
 +Maintenant que le repository Datastax est en place, il suffit de lancer la commande yum pour installer le paquet :
 +<code bash>yum install cassandra12</​code>​
 +
 +Toutes les dépendances seront installées avec en particulier Java.
 +
 +===== Installation de Java =====
 +
 +La version de Java fournie dans les repo CentOS ne me convient pas trop, surtout pour Cassandra dont tout le moteur tourne en Java.\\
 +J'ai donc préféré télécharger la dernière version de Java directement sur le site d'​Oracle.\\
 +
 +Sur [[http://​java.com/​fr/​download/​manual.jsp|cette page]], vous pourrez trouver le paquet RPM pour Linux x64 et télécharger le fichier "​jre-7u25-linux-x64.rpm"​.\\
 +\\
 +Pour l'​installer,​ rien de plus simple, transférez le fichier rpm sur le serveur, puis lancer simplement :
 +<code bash>rpm -i jre-7u25-linux-x64.rpm</​code>​
 +
 +A partir de là, si on exécute la commande suivante :
 +<code bash>​[root@vm03 ~]# java -version
 +java version "​1.6.0_24"​
 +OpenJDK Runtime Environment (IcedTea6 1.11.11.90) (rhel-1.62.1.11.11.90.el6_4-x86_64)
 +OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
 +</​code>​
 +On remarque que la commande Java pointe toujours sur la version JDK 1.6 que l'on ne veut pas.\\
 +On va reconfigurer les alternatives pour prendre la bonne version de Java. Pour cela, il faut modifier le fichier /​var/​lib/​alternatives/​java pour lui indiquer le bon chemin du binaire Java.\\
 +\\
 +Exécutez la commande suivante pour modifier directement le fichier :
 +<code bash>​echo "/​usr/​java/​latest/​bin/​java
 +18000
 +/​usr/​java/​latest/​bin/​keytool
 +/​usr/​java/​latest/​bin/​orbd
 +/​usr/​java/​latest/​bin/​pack200
 +/​usr/​java/​latest/​bin/​rmid
 +/​usr/​java/​latest/​bin/​rmiregistry
 +/​usr/​java/​latest/​bin/​servertool
 +/​usr/​java/​latest/​bin/​tnameserv
 +/​usr/​java/​latest/​bin/​unpack200
 +
 +/​usr/​java/​latest/​jre
 +/​usr/​share/​man/​man1/​java-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​keytool-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​orbd-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​pack200-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​rmid-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​rmiregistry-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​servertool-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​tnameserv-java-1.6.0-openjdk.1.gz
 +/​usr/​share/​man/​man1/​unpack200-java-1.6.0-openjdk.1.gz"​ >> /​var/​lib/​alternatives/​java
 +</​code>​
 +
 +Ce fichier décrit simplement comment doit être le lien symbolique (ou alternative) de Java. Il faut encore exécuter la commande suivante pour mettre à jour le lien :
 +<code bash>​alternatives --auto java</​code>​
 +
 +Vérification en relançant la commande :
 +<code bash>​[root@vm03 ~]# java -version
 +java version "​1.7.0_25"​
 +Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
 +Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
 +</​code>​
 +
 +Il s'agit bien de la version 1.7.0_25.
 +
 +===== Création de l'​environnement Cassandra pour la première instance =====
 +
 +A ce stade, nous pourrions déjà démarrer Cassandra, mais nous n'​aurions qu'une seule instance sur le serveur.\\
 +Commençons tout de suite par créer l'​envionnement pour l'​instance 1.\\
 +
 +Nous devons copier le fichier d'init ainsi que le script "​default"​. Il faut également recopier tout le répertoire de configuration de Cassandra. Pour cela, exécutez les commandes suivantes :
 +<code bash>cp /​etc/​init.d/​cassandra /​etc/​init.d/​cassandra1
 +cp /​etc/​default/​cassandra /​etc/​default/​cassandra1
 +rsync -va /​etc/​cassandra/​default.conf /​etc/​cassandra/​1/</​code>​
 +
 +Dans le répertoire /​etc/​cassandra,​ nous pouvons voir un dossier "​default.conf"​ qui représente la configuration de Cassandra, mais également un lien symbolique qui pointe indirectement sur le répertoire "​default.conf"​. Nous allons recréer cette environnement pour notre instance 1 :
 +<code bash>ln -sfT /​etc/​cassandra/​1/​default.conf /​etc/​cassandra/​1/​conf</​code>​
 +
 +Les données de l'​instance sont stockées dans /​var/​lib/​cassandra. Il faut donc que ce répertoire appartienne au user cassandra pour pouvoir y créer les sous-répertoires réservés à chaque instance :
 +<code bash>​chown cassandra:​cassandra /​var/​lib/​cassandra</​code>​
 +
 +Et enfin, on crée les répertoires en tant que cassandra pour avoir tout de suite les bons droits dessus :
 +<code bash>​sudo -u cassandra mkdir /​var/​lib/​cassandra/​1
 +sudo -u cassandra mkdir /​var/​log/​cassandra/​1
 +sudo -u cassandra mkdir /​var/​run/​cassandra/​1
 +</​code>​
 +
 +Il faut maintenant mettre à jour les noms des répertoires dans les scripts de Cassandra, en particulier dans le script d'init :
 +<code bash># Mise à jour du nom du script d'init
 +sed -i '​s#​NAME="​cassandra"#​NAME="​cassandra1"#'​ /​etc/​init.d/​cassandra1
 +# Mise à jour du répertoire /​etc/​cassandra/​conf pour indiquer l'​emplacement des fichiers de configuration de l'​instance
 +sed -i '​s#/​etc/​cassandra/​conf#/​etc/​cassandra/​1/​conf#'​ /​etc/​init.d/​cassandra1
 +# Mise à jour du fichier /​var/​log/​cassandra/​cassandra.log,​ log de l'​instance
 +sed -i '​s#/​var/​log/​cassandra/​cassandra.log#/​var/​log/​cassandra/​1/​cassandra.log#'​ /​etc/​init.d/​cassandra1
 +# Mise à jour du fichier /​var/​run/​cassandra/​cassandra.pid qui contient le PID de l'​instance
 +sed -i '​s#/​var/​run/​cassandra/​cassandra.pid#/​var/​run/​cassandra/​1/​cassandra.pid#'​ /​etc/​init.d/​cassandra1
 +# Mise à jour du fichier /​var/​log/​cassandra/​system.log,​ log du programme Java
 +sed -i '​s#/​var/​log/​cassandra/​system.log#/​var/​log/​cassandra/​1/​system.log#'​ /​etc/​cassandra/​1/​default.conf/​log4j-server.properties
 +</​code>​
 +
 +Chaque cluster Cassandra possède un nom, et ce n'est pas pour faire joli. Il faut donc changer le nom par défaut pour éviter qu'un nouveau noeud fraîchement installé rejoingne notre cluster sans le vouloir :
 +<code bash>sed -i "​s/​cluster_name:​ 'Test Cluster'/​cluster_name:​ 'My Cluster'/"​ /​etc/​cassandra/​1/​default.conf/​cassandra.yaml</​code>​
 +
 +Mettons maintenant à jour le fichier de configuration de Cassandra pour paramétrer l'​instance :
 +<code bash># Mise à jour de la liste des seeds, on indique que la première instance qui tourne sur 127.0.0.1
 +sed -i 's/- seeds: ".*$/- seeds: "​127.0.0.1"/'​ /​etc/​cassandra/​1/​default.conf/​cassandra.yaml
 +# On indique ici l'​adresse IP sur laquelle l'​instance va écouter, 127.0.0.1 pour la première instance, 127.0.0.2 pour la deuxième, ect...
 +sed -i '​s/​listen_address:​ .*$/​listen_address:​ 127.0.0.1/'​ /​etc/​cassandra/​1/​default.conf/​cassandra.yaml
 +# Pareil pour le RPC
 +sed -i '​s/​rpc_address:​ localhost/​rpc_address:​ 127.0.0.1/'​ /​etc/​cassandra/​1/​default.conf/​cassandra.yaml
 +# On précise le nouveau répertoire pour les données
 +sed -i 's#- /​var/​lib/​cassandra/​data#​- /​var/​lib/​cassandra/​1/​data#'​ /​etc/​cassandra/​1/​default.conf/​cassandra.yaml
 +# On précise le nouveau répertoire pour les commitlogs
 +sed -i '​s#/​var/​lib/​cassandra/​commitlog#/​var/​lib/​cassandra/​1/​commitlog#'​ /​etc/​cassandra/​1/​default.conf/​cassandra.yaml
 +# On précise le nouveau répertoire pour le cache
 +sed -i '​s#/​var/​lib/​cassandra/​saved_caches#/​var/​lib/​cassandra/​1/​saved_caches#'​ /​etc/​cassandra/​1/​default.conf/​cassandra.yaml
 +</​code>​
 +
 +Enfin, il faut changer le port du JMX car celui-ci écoute toujours sur 0.0.0.0, on ne pourra donc pas faire de distinction entre les instances. Normalement le port est le 7199, j'ai décidé de garder celui la pour l'​instance 1, et d'​incrémenter de 1 pour les instances suivantes. Du coup, rien à changer pour l'​instance 1, sinon utiliser la commande suivante :
 +<code bash>sed -i '​s#​JMX_PORT="​7199"#​JMX_PORT="​7199"#'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra-env.sh</​code>​
 +
 +Tentons maintenant de lancer notre instance 1 :
 +<code bash>/​etc/​init.d/​cassandra1 start</​code>​
 +
 +Après plusieurs secondes, on vérifie que l'​instance 1 tourne :
 +<​code>​[root@vm03 ~]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 46.54 KB   ​100.0% ​           db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -5810576811809222169 ​                    rack1
 +</​code>​
 +
 +Amusons-nous à insérer des données avec cassandra-stress :
 +<​code>​[root@vm03 ~]# cassandra-stress --threads=4 --keep-going --num-keys=100000 --operation=INSERT
 +Created keyspaces. Sleeping 1s for propagation.
 +total,​interval_op_rate,​interval_key_rate,​latency/​95th/​99th,​elapsed_time
 +15997,​1599,​1599,​0.4,​9.9,​21.4,​10
 +59763,​4376,​4376,​0.4,​6.5,​21.0,​20
 +100000,​4023,​4023,​0.3,​4.2,​21.0,​29
 +END
 +</​code>​
 +
 +Avec cette commande, on a créé un keyspace "​Keyspace1"​ puis inséré 100 000 lignes dans le Column Family "​Standard1"​.
 +Lançons une commande de flush puis regardons de nouveau le status de notre cluster :
 +<​code>​[root@vm03 ~]# nodetool flush
 +[root@vm03 ~]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 29.47 MB   ​100.0% ​           db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -5810576811809222169 ​                    rack1
 +</​code>​
 +
 +On remarque que le "​Load"​ est passé à une 30aine de Mo. Les données sont bien là.
 +
 +===== Créer d'​autres environnements =====
 +
 +Pour créer des environnements plus rapidement, on peut se servir d'une variable INSTANCE_NUM,​ puis simplement faire un copier/​coller des commandes pour répéter toutes les étapes :
 +<code bash>​export INSTANCE_NUM=2
 +
 +cp /​etc/​init.d/​cassandra /​etc/​init.d/​cassandra$INSTANCE_NUM
 +cp /​etc/​default/​cassandra /​etc/​default/​cassandra$INSTANCE_NUM
 +rsync -va /​etc/​cassandra/​default.conf /​etc/​cassandra/​$INSTANCE_NUM/​
 +
 +ln -sfT /​etc/​cassandra/​$INSTANCE_NUM/​default.conf /​etc/​cassandra/​$INSTANCE_NUM/​conf
 +
 +chown cassandra:​cassandra /​var/​lib/​cassandra
 +sudo -u cassandra mkdir /​var/​lib/​cassandra/​$INSTANCE_NUM
 +sudo -u cassandra mkdir /​var/​log/​cassandra/​$INSTANCE_NUM
 +sudo -u cassandra mkdir /​var/​run/​cassandra/​$INSTANCE_NUM
 +
 +sed -i '​s#​NAME="​cassandra"#​NAME="​cassandra'​$INSTANCE_NUM'"#'​ /​etc/​init.d/​cassandra$INSTANCE_NUM
 +sed -i '​s#/​etc/​cassandra/​conf#/​etc/​cassandra/'​$INSTANCE_NUM'/​conf#'​ /​etc/​init.d/​cassandra$INSTANCE_NUM
 +sed -i '​s#/​var/​log/​cassandra/​cassandra.log#/​var/​log/​cassandra/'​$INSTANCE_NUM'/​cassandra.log#'​ /​etc/​init.d/​cassandra$INSTANCE_NUM
 +sed -i '​s#/​var/​run/​cassandra/​cassandra.pid#/​var/​run/​cassandra/'​$INSTANCE_NUM'/​cassandra.pid#'​ /​etc/​init.d/​cassandra$INSTANCE_NUM
 +sed -i '​s#/​var/​log/​cassandra/​system.log#/​var/​log/​cassandra/'​$INSTANCE_NUM'/​system.log#'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​log4j-server.properties
 +
 +sed -i "​s/​cluster_name:​ 'Test Cluster'/​cluster_name:​ 'My Cluster'/"​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra.yaml
 +
 +sed -i 's/- seeds: ".*$/- seeds: "​127.0.0.1"/'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra.yaml
 +sed -i '​s/​listen_address:​ .*$/​listen_address:​ 127.0.0.'​$INSTANCE_NUM'/'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra.yaml
 +sed -i '​s/​rpc_address:​ localhost/​rpc_address:​ 127.0.0.'​$INSTANCE_NUM'/'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra.yaml
 +sed -i 's#- /​var/​lib/​cassandra/​data#​- /​var/​lib/​cassandra/'​$INSTANCE_NUM'/​data#'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra.yaml
 +sed -i '​s#/​var/​lib/​cassandra/​commitlog#/​var/​lib/​cassandra/'​$INSTANCE_NUM'/​commitlog#'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra.yaml
 +sed -i '​s#/​var/​lib/​cassandra/​saved_caches#/​var/​lib/​cassandra/'​$INSTANCE_NUM'/​saved_caches#'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra.yaml
 +sed -i '​s#​JMX_PORT="​7199"#​JMX_PORT="'​$((7198 + $INSTANCE_NUM))'"#'​ /​etc/​cassandra/​$INSTANCE_NUM/​default.conf/​cassandra-env.sh
 +</​code>​
 +
 +Maintenant qu'une deuxième instance est créée, il suffit de la lancer :
 +<​code>/​etc/​init.d/​cassandra2 start</​code>​
 +
 +Après avoir attendu un peu, on vérifie le status :
 +<​code>​[root@vm03 ~]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 29.47 MB   ​49.9% ​            ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -5810576811809222169 ​                    rack1
 +UN  127.0.0.2 ​ 9.43 KB    50.1%             ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ 3438279170277773133 ​                     rack1
 +</​code>​
 +
 +La deuxième instance sur 127.0.0.2 est bien là. On remarque par contre dans la colonne "​Load"​ que l'​instance 1 a encore toutes les données, et l'​instance 2 aucune. Pourtant, la colonne "​Owns"​ montre que chaque noeud se partage bien les données à 50/50.\\
 +Mais Cassandra s'​occupe de tout, après quelques secondes (minutes ?), voici ce que j'​obtiens :
 +<​code>​[root@vm03 ~]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 29.47 MB   ​49.9% ​            ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -5810576811809222169 ​                    rack1
 +UN  127.0.0.2 ​ 14.78 MB   ​50.1% ​            ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ 3438279170277773133 ​                     rack1
 +</​code>​
 +
 +Le noeud 1 a toujours toutes les données de départ. C'est parce que Cassandra conserve les données sur les noeuds quand une nouvelle instance rejoint le cluster. Simplement, car une nouvelle instance, et donc un nouveau serveur, c'est peut être fragile, pas encore stable, donc on garde les données au cas où. Pour purger ces données en trop sur l'​instance 1, il faut donc lancer un "​cleanup"​ :
 +<code bash>​nodetool -h 127.0.0.1 -p 7199 cleanup</​code>​
 +
 +Vu qu'on a maintenant plusieurs instances, il est préférable de préciser l'host et le port de l'​instance sur laquelle on souhaite lancer la commande nodetool. Par défaut, ça sera toujours l'​instance 1 (l'​host par défaut étant 127.0.0.1 et le port 7199).\\
 +\\
 +Après le "​cleanup"​ j'​obtiens une répartition quasi parfaite :
 +<​code>​[root@vm03 ~]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 14.8 MB    49.9%             ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -5810576811809222169 ​                    rack1
 +UN  127.0.0.2 ​ 14.78 MB   ​50.1% ​            ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ 3438279170277773133 ​                     rack1
 +</​code>​
 +
 +==== 3ème instance ====
 +
 +Réexécutons les scripts pour une 3ème instance. Puis on la démarre :
 +<code bash>/​etc/​init.d/​cassandra3 start</​code>​
 +
 +On attend quelques secondes voir minutes. Niveau mémoire pas besoin d'un foudre de guerre, j'ai réalisé ce test sur une VM VirtualBox avec 2Go de RAM alloué à la machine. Les 3 instances ont réussi à tourner sans souci. Cependant, je n'ai pas fait grand chose, ni inséré beaucoup de lignes. Si vous souhaitez vraiment tester Cassandra avec 3-4 instances, je vous conseille une machine avec au moins 8Go de RAM.\\
 +
 +Après l'​attente,​ le cluster s'est réparti :
 +<​code>​[root@vm03 ~]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 14.8 MB    24.6%             ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -5810576811809222169 ​                    rack1
 +UN  127.0.0.2 ​ 14.79 MB   ​50.1% ​            ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ 3438279170277773133 ​                     rack1
 +UN  127.0.0.3 ​ 7.46 MB    25.3%             ​4a92c47c-578f-45ff-a182-a1eb44a7800c ​ 8097365138884282044 ​                     rack1
 +</​code>​
 +
 +Nous avons vu pourquoi le "​Load"​ n'est pas parfaitement réparti, mais ici nous avons également le Owns qui n'est pas de 33% partout. C'est normal, à l'​ajout d'une instance, Cassandra prend la tranche de données, et divise en 2.\\
 +\\
 +Imaginons que l'on doit répartir les lettres de l'​alphabet de A à Z. Le premier noeud va donc prendre toutes les lettres. Quand la 2ème instance arrive, on divise cet ensemble en 2, l'​instance 1 reçoit donc de A à M et l'​instance 2 de N à Z, on a 50/50.\\
 +\\
 +Mais quand l'​instance 3 se présente, on prend l'​ensemble de l'​instance 1 (A à M) et on divise encore en 2 : instance 1 avec A à G, et instance 3 de H à M. L'​instance 2 reste inchangée et conserve donc 50% de données pour elle.\\
 +\\
 +Cela crée un déséquilibre. On va donc rétablir la situation en déplaçant les tokens. Pour cela, nous devons calculer les nouveaux tokens pour avoir une répartition parfaite. C'est avec la commande python suivante que nous pouvons facilement calculer les tokens :
 +<code bash>​python -c 'print [str(((2**64 / number_of_tokens) * i) - 2**63) for i in range(number_of_tokens)]'</​code>​
 +
 +Pour 3 instances, j'ai lancé :
 +<​code>​[root@vm03 ~]# python -c 'print [str(((2**64 / 3) * i) - 2**63) for i in range(3)]'​
 +['​-9223372036854775808',​ '​-3074457345618258603',​ '​3074457345618258602'​]
 +</​code>​
 +
 +Déplaçons maintenant les instances pour leur attribuer les nouveaux tokens :
 +<​code>​[root@vm03 ~]# nodetool -h 127.0.0.1 -p 7199 move \\-9223372036854775808
 +[root@vm03 ~]# nodetool -h 127.0.0.2 -p 7200 move \\-3074457345618258603
 +[root@vm03 ~]# nodetool -h 127.0.0.3 -p 7201 move 3074457345618258602
 +</​code>​
 +
 +Regardons maintenant le status pour observer la répartition :
 +<​code>​[root@vm03 ~]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 22.79 MB   ​33.3% ​            ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -9223372036854775808 ​                    rack1
 +UN  127.0.0.2 ​ 20.28 MB   ​33.3% ​            ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ -3074457345618258603 ​                    rack1
 +UN  127.0.0.3 ​ 17.85 MB   ​33.3% ​            ​4a92c47c-578f-45ff-a182-a1eb44a7800c ​ 3074457345618258602 ​                     rack1
 +</​code>​
 +
 +Chaque instance a bien 33%, la répartition est parfaite. Tentons maintenant de répartir le "​Load",​ lancez des cleanup sur chaque instance :
 +<​code>​[root@vm03 ~]# nodetool -h 127.0.0.1 -p 7199 cleanup
 +[root@vm03 ~]# nodetool -h 127.0.0.2 -p 7200 cleanup
 +[root@vm03 ~]# nodetool -h 127.0.0.3 -p 7201 cleanup
 +</​code>​
 +
 +Après quelques minutes, on obtient normalement quelque chose comme ça :
 +<​code>​[root@vm03 Keyspace1]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 17.27 MB   ​33.3% ​            ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -9223372036854775808 ​                    rack1
 +UN  127.0.0.2 ​ 9.93 MB    33.3%             ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ -3074457345618258603 ​                    rack1
 +UN  127.0.0.3 ​ 9.88 MB    33.3%             ​4a92c47c-578f-45ff-a182-a1eb44a7800c ​ 3074457345618258602 ​                     rack1
 +</​code>​
 +
 +L'​instance 1 n'est toujours pas parfaite. Cela s'​explique par le fait que Cassandra créer des fichiers SSTABLE à chaque flush. Du coup, si on regarde le contenu du répertoire de données, voici ce qu'on remarque :
 +<​code>​[root@vm03 ~]# cd /​var/​lib/​cassandra/​1/​data/​Keyspace1/​Standard1
 +[root@vm03 Standard1]# ls
 +Keyspace1-Standard1-ic-10-Data.db ​       Keyspace1-Standard1-ic-10-Summary.db ​ Keyspace1-Standard1-ic-8-Index.db ​      ​Keyspace1-Standard1-ic-9-Digest.sha1 ​   Keyspace1-Standard1-ic-9-TOC.txt
 +Keyspace1-Standard1-ic-10-Digest.sha1 ​   Keyspace1-Standard1-ic-10-TOC.txt ​    ​Keyspace1-Standard1-ic-8-Statistics.db ​ Keyspace1-Standard1-ic-9-Filter.db
 +Keyspace1-Standard1-ic-10-Filter.db ​     Keyspace1-Standard1-ic-8-Data.db ​     Keyspace1-Standard1-ic-8-Summary.db ​    ​Keyspace1-Standard1-ic-9-Index.db
 +Keyspace1-Standard1-ic-10-Index.db ​      ​Keyspace1-Standard1-ic-8-Digest.sha1 ​ Keyspace1-Standard1-ic-8-TOC.txt ​       Keyspace1-Standard1-ic-9-Statistics.db
 +Keyspace1-Standard1-ic-10-Statistics.db ​ Keyspace1-Standard1-ic-8-Filter.db ​   Keyspace1-Standard1-ic-9-Data.db ​       Keyspace1-Standard1-ic-9-Summary.db
 +</​code>​
 +
 +Plein de fichiers, or les SSTABLEs ne sont modifiés qu'à la prochaine compaction. Forçons le destin en lançant manuellement un compactage :
 +<​code>​[root@vm03 Standard1]# nodetool -h 127.0.0.1 -p 7199 compact</​code>​
 +
 +Que donne le répertoire des données maintenant :
 +<​code>​[root@vm03 Standard1]# ls
 +Keyspace1-Standard1-ic-11-Data.db ​     Keyspace1-Standard1-ic-11-Filter.db ​ Keyspace1-Standard1-ic-11-Statistics.db ​ Keyspace1-Standard1-ic-11-TOC.txt
 +Keyspace1-Standard1-ic-11-Digest.sha1 ​ Keyspace1-Standard1-ic-11-Index.db ​  ​Keyspace1-Standard1-ic-11-Summary.db
 +</​code>​
 +
 +Beaucoup moins de fichiers, vérifions le status :
 +<​code>​[root@vm03 Standard1]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 9.86 MB    33.3%             ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -9223372036854775808 ​                    rack1
 +UN  127.0.0.2 ​ 9.93 MB    33.3%             ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ -3074457345618258603 ​                    rack1
 +UN  127.0.0.3 ​ 9.88 MB    33.3%             ​4a92c47c-578f-45ff-a182-a1eb44a7800c ​ 3074457345618258602 ​                     rack1
 +</​code>​
 +
 +Répartition quasi parfaite, on remarque une très légère différence sur l'​instance 2. Il s'agit du même problème, en jetant un oeil au répertoire de données de l'​instance 2, on remarque plusieurs fichiers. Il suffit donc de lancer un compactage sur l'​instance 2 pour avoir cette fois une répartition parfaite :
 +<​code>​[root@vm03 Standard1]# nodetool -h 127.0.0.2 -p 7200 compact
 +[root@vm03 Standard1]# nodetool status
 +Datacenter: datacenter1
 +=======================
 +Status=Up/​Down
 +|/ State=Normal/​Leaving/​Joining/​Moving
 +--  Address ​   Load       Owns (effective) ​ Host ID                               ​Token ​                                   Rack
 +UN  127.0.0.1 ​ 9.86 MB    33.3%             ​db7b86bf-ae95-43c7-bdd9-dd3360fe218c ​ -9223372036854775808 ​                    rack1
 +UN  127.0.0.2 ​ 9.87 MB    33.3%             ​a8be6a3e-1af6-4eb3-bd95-4e92a0cdf03f ​ -3074457345618258603 ​                    rack1
 +UN  127.0.0.3 ​ 9.88 MB    33.3%             ​4a92c47c-578f-45ff-a182-a1eb44a7800c ​ 3074457345618258602 ​                     rack1
 +</​code>​
 +
 +Cependant, les SSTABLEs ne sont pas tout le temps compactables de cette manière. De manière générale, il ne faut pas s'​inquiéter du "​Load",​ le plus important c'est les tokens et la colonne "​Owns"​.\\
 +\\
 +Vous pouvez maintenant créer une éventuelle instance 4 et tenter de refaire une répartition parfaite.
 +
 +===== Versions utilisées =====
 +
 +Guide réalisé sur une CentOS 6.4 avec les versions suivantes des paquets :
 +  * Cassandra 1.2.8-1
 +  * Java JRE 1.7.0_25
 +
 +===== Liens externes =====
 +
 +[[http://​cassandra.apache.org/​|Site officiel de Apache Cassadra]]\\
 +[[http://​www.datastax.com/​|Site officiel de Datastax]]
  
construire_un_cluster_cassandra_avec_plusieurs_instances_sur_le_meme_serveur.txt · Dernière modification: 19/08/2013 20:27 par admin