Pour accéder aux fichiers nécessaires pour faire ce TP, visitez: https://drive.google.com/folderview?id=0Bz7DokLRQvx7M2JWZEt1VHdwSE0&usp=sharing
Pour plus de contenu, Visitez http://liliasfaxi.wix.com/liliasfaxi !
1. Institut National des Sciences Appliquées et de Technologie Tunisie
Big Data
2015-2016
TP4- NOSQL ORIENTE
COLONNES AVEC
CASSANDRA
Dr. Lilia SFAXI
Objectifs du TP : Se familiariser avec les bases de données NOSQL,
orientées colonnes, avec Cassandra.
2. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 2
I. Présentation de Cassandra
Cassandra1 est une base de données NOSQL orientée colonnes, destinée
pour de grands volumes de données, hétérogènes, de structure et taille
évolutives et hautement disponibles, sans compromettre la performance.
Un très large panel d’entreprises, dont Twitter, Netflix et eBay, utilisent
Cassandra. Pour voir la liste complète de ses utilisateurs, visiter:
http://planetcassandra.org/companies/
II. Installer Cassandra
Pour les besoins de ce TP, nous allons installer Cassandra sur la machine
virtuelle CentOS que nous avons utilisé pour les deux premier TP sur Hadoop.
Pour cela, télécharger la dernière version de Cassandra sur:
http://cassandra.apache.org/download/
Décompresser simplement le fichier que vous venez de télécharger.
Désormais, on appellera le répertoire obtenu après décompression:
<cass_home>.
III. Démarrer Cassandra
Pour commencer:
1. Lancer le serveur Cassandra. (si on omet le –f, il se lancera en arrière
plan)
sudo <cass_home>/bin/cassandra –f
2. Pour arrêter Cassandra, cliquer sur:
Ctrl-C
3. Pour tuer le processus, taper:
pkill -f CassandraDaemon
1 Apache Cassandra : http://cassandra.apache.org/
3. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 3
IV. CQL : Cassandra Query Language
CQL est l’interface par défaut dans le SGBD Cassandra. C’est un langage
SQL-Like, pour la manipulation des données dans la base.
Nous citons ci-dessous les commandes de base de CQL. Pour plus de détails,
consulter le fichier CQL.html que je vous ai fourni dans le drive partagé.
IV.1. Notions de Base
- Pour se connecter à l’instance locale de CQL
<cass_home>/bin/cqlsh
- Créer un Keyspace :
CREATE KEYSPACE mykeyspace WITH REPLICATION =
{ 'class' : 'SimpleStrategy', 'replication_factor' : 1};
- Afficher l’ensemble des keyspaces:
select * from system.schema_keyspaces;
ou:
describe keyspaces;
- Se connecter au keyspace :
USE mykeyspace;
- Créer une table (il est possible de remplacer le terme TABLE par
COLUMNFAMILY).
CREATE TABLE users (
user_id int PRIMARY KEY,
fname text,
lname text
);
- Afficher les tables existantes:
describe tables;
- Remplir la table:
INSERT INTO users (user_id, fname, lname)
VALUES (1745, 'john', 'smith');
4. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 4
- Afficher les données insérées:
SELECT * FROM users;
- Créer un index sur une colonne, puis extraire les données selon cette
colonne :
CREATE INDEX ON users (lname);
SELECT * FROM users WHERE lname = 'smith';
- Créer une table avec une clef composée :
CREATE TABLE tab2 (
id1 int,
id2 int,
first_name varchar,
last_name varchar,
PRIMARY KEY (id1, id2));
- Ajouter un nouveau champ à la table:
ALTER TABLE users ADD telephone text;
- Modifier la valeur d’un enregistrement:
UPDATE users SET telephone = “21212121”
WHERE user_id=1745;
- Vider une table :
TRUNCATE users;
- Supprimer une table :
DROP users;
IV.2. Les Collections
Dans les bases de données relationnelles traditionnelles, il est fortement
déconseillé d’utiliser des valeurs multiples dans un même champs. Pour cela, il
faudrait créer une autre table, et faire une jointure.
Dans les bases NOSQL, le but ultime est de minimiser au maximum les jointures,
pour faciliter et accélerer la navigation. C’est pour cette raison que des
collections comme les sets, listes et maps sont utilisés.
5. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 5
Attention à ne pas abuser de ce type de champs: il faut s’assurer que les
collections stockent de petites quantités de données, car une requête
Cassandra lit une collection en entier, c’est à l’utilisateur de les parcourir
ensuite.
IV.2.1. Sets
Un ensemble (set) est un ensemble non ordonné de valeurs. En utlisant le type
de données set, il est possible de résoudre le problème de champs multiples,
comme les emails par exemple.
a. Création
Prenons par exemple le cas d’un ensemble d’emails pour un utilisateur. C’est
représenté par un seul champ, de type set<text>, et est défini dans la table
users comme ceci:
CREATE TABLE users (
user_id int PRIMARY KEY,
fname text,
lname text,
emails set<text>
);
b. Insertion
Pour insérer des données dans l’ensemble, placer les valeurs entre accolades
et les séparer par des virgules. Les différentes valeurs dans un ensemble
doivent être uniques.
INSERT INTO users (user_id, fname, lname, emails)
VALUES(1234, 'Frodo', 'Baggins',
{'f@baggins.com', 'baggins@gmail.com'});
c. Ajout
Ajouter un élément à un ensemble en utilisant la commande UPDATE :
UPDATE users
SET emails = emails + {'fb@friendsofmordor.org'}
WHERE user_id = 1234;
d. Extraction
6. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 6
Extraire les adresses email comme ceci:
SELECT user_id, emails FROM users WHERE user_id = 1234;
Les données extraites sont retournées par ordre, selon leur type. Par exemple,
les données textuelles sont ordonnées par ordre alphabétique.
e. Suppression
Pour supprimer un élément de l’ensemble, utiliser l’opérateur (-):
UPDATE users SET emails = emails - {'fb@friendsofmordor.org'}
WHERE user_id = 1234;
Pour supprimer tout l’ensemble:
UPDATE users SET emails = {} WHERE user_id = 1234;
ou bien :
DELETE emails FROM users WHERE user_id = 1234;
Une fois vidée, une collection (ensemble, liste ou map) est assimilée ainsi à la
valeur null.
IV.2.2. Listes
Une liste est utilisée quand l’ordre d’insertion des éléments compte, ou quand
on veut pouvoir insérer la même valeur plusieurs fois.
a. Création
Ajouter une liste des meilleurs endroits visités à la table users.
ALTER TABLE users ADD top_places list<text>;
b. Insertion
UPDATE users
SET top_places = [ 'rivendell', 'rohan' ]
WHERE user_id = 1234;
On remarquera ici que les éléments de la liste sont placés entre crochets.
c. Ajout
Pour ajouter un nouvel élément à la fin de la liste :
7. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 7
UPDATE users
SET top_places = top_places + [ 'mordor' ]
WHERE user_id = 1234;
Pour affecter un élément à un emplacement donné (écrase l’ancienne
valeur) :
UPDATE users
SET top_places[1] = 'riddermark' WHERE user_id = 1234;
Quand un élément est ajouté à la fin (ou au début) de la liste, cette dernière
n’est pas lue. On écrit directement la valeur à son emplacement. Par contre,
quand un élément est placé dans une position particulière, Cassandra lit la
liste entière, puis ajoute le nouvel élément, ce qui provoque une plus grande
latence.
d. Suppression
Supprimer un élément de la liste, en utilisant son index:
DELETE top_places[3] FROM users WHERE user_id = 1234;
Supprimer tous les éléments ayant une valeur donnée d’une liste:
SET top_places = top_places - ['riddermark']
WHERE user_id = 1234;
L’utilisation de cette dernière commande est meilleure que la première, car
elle protège contre les problèmes d’accès concurrent: avec la première
méthode, si un autre client ajoute des éléments à la liste en même temps, on
risque de supprimer la mauvaise valeur, ce qui n’est pas un problème avec la
deuxième méthode.
e. Extraction
SELECT user_id, top_places FROM users WHERE user_id = 1234;
IV.2.3. Maps
Une map permet d’associer deux éléments, sous forme de clef/valeur. Elle
peut être utilisée, par exemple, pour sauvegarder les horaires des différents
évènements dans un profil utilisateur.
8. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 8
Chaque élément dans une Map est stocké dans Cassandra comme étant
une colonne que vous pouvez modifier, remplacer et requêter.
a. Création
ALTER TABLE users ADD todo map<timestamp, text> ;
b. Insertion
Un élément dans une Map est un couple d’éléments entre accolades,
séparés par une virgule.
UPDATE users SET todo = {
'2012-9-24' : 'enter mordor',
'2012-10-2 12:00' : 'throw ring into mount doom'
} WHERE user_id = 1234;
c. Ajout
Ajouter un élément spécifique, en utilisant comme clef la valeur du
timestamp entre crochets:
UPDATE users
SET todo['2012-10-2 12:00'] = 'throw my precious into
mount doom' WHERE user_id = 1234;
Utiliser INSERT pour spécifier des données dans une Map :
INSERT INTO users (user_id,todo) VALUES ( 1234,
{ '2013-9-22 12:01' : 'birthday wishes to Bilbo',
'2013-10-1 18:00' : 'Check into Inn of Prancing Pony'
});
Ceci remplacera toute la Map pour l’utilisateur frodo.
d. Suppression
DELETE todo['2012-9-24'] FROM users WHERE user_id = 1234;
e. Extraction
SELECT user_id, todo FROM users WHERE user_id = 1234;
9. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 9
V. Manipulation de Cassandra avec Python
V.1. API pycassa
Pycassa est un client Python pour manipuler la base de données Cassandra.
Le module à intégrer dans python est récupéré à l'adresse suivante:
https://pypi.python.org/pypi/pycassa
V.2. Installer pycassa
Pour installer le module pycassa, comme tout autre module de Python sur une
machine Linux, suivre les étapes suivantes :
- Décompresser l'archive dans le répertoire de votre choix
- Avec l'invite de commande, déplacez-vous vers ce répertoire, vous
devriez y trouver un fichier setup.py
- Taper:
sudo python setup.py install
Une fois le module installé, l'instruction suivante ne devrait plus lancer
d'exception si on l'exécute avec python:
import pycassa
V.3. Utilisation de pycassa
Nous allons montrer dans ce qui suit les différentes instructions dont nous
aurons besoin pour manipuler la base Cassandra avec python. Pour plus
d'informations, consulter la documentation de pycassa, disponible en ligne à
l'adresse :
http://pycassa.github.io/pycassa/index.html
V.3.1. Connexion à Cassandra
Pour se connecter à un keyspace KS en localhost, utiliser les instructions
suivantes:
pool = pycassa.ConnectionPool(keyspace='KS',
server_list=['127.0.0.1:9160'])
Pour appeler une table (column family) cf1, utiliser:
10. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 10
cf1 = pycassa.ColumnFamily(pool, 'cf1')
V.3.2. Ecriture des données
Pour insérer les colonnes associées à la clef key1 dans une table cf1, utiliser:
cf1.insert(key1, {'col1': 'val1', 'col2': 'val2'})
V.3.3. Lecture des données
Pour extraire des données à partir de la table cf1, utiliser:
data = cf1.get(key1,columns=['col1','col2']);
Cela va extraire les valeurs des colonnes col1 et col2 associées à la clef key1,
et les stocker dans data, qui est de type orderedDict. orderedDict est une liste
de couples (clef,valeur) ordonnées.
Ainsi, dans notre variable data, les champs seront ordonnés comme suit :
{'col1': 'val1', 'col2': 'val2'}
Pour extraire le premier couple, utiliser :
data.items()[0]
Pour extraire la première valeur (val1), utiliser :
data.items()[0][1]
V.3.4. Nombre d'entrées
Pour connaitre le nombre d'entrées (lignes) dans une table cf1, utiliser :
len(list(cf1.get_range()
V.4. Objectifs du TP
Dans ce TP, le but est de charger des données volumineuses dans Cassandra,
et les manipuler avec l’API pycassa.
Pour cela, nous allons:
1. Créer la base de données avec Cassandra
2. Remplir la base de données
3. Afficher les données lues
11. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 11
V.5. Réalisation
V.5.1. Création de la base de données et des tables
Créer un keyspace Cassandra appelé wordcount, contenant une table bible
contenant un champs id (entier, clef primaire) et un champs line(texte)
Pour que pycassa puisse accéder aux données des tables, ces dernières
doivent être créées avec la mention “WITH COMPACT STORAGE“ insérée à la
fin de l'instruction de création.
V.5.2. Remplissage de la table bible
Pour remplir la table bible avec des lignes de texte, nous avons choisi d'utiliser
comme source le texte d'une bible, trouvé ici:
https://sites.google.com/site/ruwach/bibletext .
Créer un répertoire tp4 à l'emplacement de votre choix. C'est dans ce
répertoire que nous allons mettre tous les fichiers nécessaires à notre travail.
- Extraire l'archive donnée dans le répertoire tp3. Renommez le répertoire
obtenu en : bible.
- Ecrire un fichier populate.py, permettant d'utiliser l'API pycassa pour
stocker dans la table bible les lignes lues à partir de l'entrée standard.
Chaque ligne sera stockée en entier dans le champ line, avec comme
identifiant un entier incrémental.
- Pour exécuter le fichier populate.py et lui donner comme entrée le
contenu du répertoire bible, utiliser l'instruction suivante:
find bible -type f -name "*.txt" -print0 | xargs -0 cat | sed
"s/^[0-9 ]*//" | python populate.py
- Vérifier que votre table contient bien le texte. Pour cela, taper:
select * from bible where id = 20;
Et vérifier que le résultat est bien le suivant:
12. TP4 : NOSQL Orientées Colonnes avec Cassandra
Page 12
VI. Homework
• Choisir dans votre réseau social quels types de données pourront être
stockés dans une base de données NOSQL orientée colonnes.
• Concevoir vos tables, les créer avec Cassandra et les remplir avec de
premières données de test.
• Remarque : Vous pouvez utiliser python avec l’API pycassa (comme
dans le TP), ou alors Java grâce à l’API Datastax Java Driver