Hadoop Ozone partie 2: tutorial et démonstration des fonctionnalités
3 déc. 2019
- Catégories
- Infrastructure
- Tags
- CLI
- Enseignement et tutorial
- REST
- HDFS
- Ozone
- Amazon S3
- Cluster [plus][moins]
Ne ratez pas nos articles sur l'open source, le big data et les systèmes distribués, fréquence faible d’un email tous les deux mois.
Les versions d’Hadoop Ozone sont livrées avec des fichiers docker-compose très pratique pour tester Ozone. Les instructions ci-dessous apportent des détails sur comment les utiliser. Il est aussi possible d’utiliser le bac à sable Katacoda qui founit un environnement pré-configuré.
Cette article est la deusième partie d’une série de trois articles présentant Ozone, démontrant son usage et proposant une stratégie de réplication avancée basée sur les Copyset.
La démonstration se base sur l’utilisation de la version 0.3.0-alpha. Elle ne propose pas de sécurité (Kerberos, Ranger ou n’importe quelle type d’ACL) mais a déjà implementé le protocole S3.
Téléchargement et installation
Téléchargez et extrayez la version 0.3.0 de Ozone here.
curl -LO http://mirror.ibcp.fr/pub/apache/hadoop/ozone/ozone-0.3.0-alpha/hadoop-ozone-0.3.0-alpha.tar.gz
tar xzf hadoop-ozone-0.3.0-alpha.tar.gz
cd ozone-0.3.0-alpha
La manière la plus simple de démarrer votre premier cluster Ozone consiste à utiliser le docker-compose présent dans la release.
cd compose/ozones3
docker-compose up -d
Cela démarrera un Ozone Manager, un Storage Container Manager et un DataNode.
Utilisation de CLI Ozone
La CLI d’Ozone est très pratique pour commencer à utiliser notre cluster. Nous pouvons l’utiliser directement dans le conteneur puisqu’il propose un environnement déjà configuré (concrètement il s’agit du fichier ozone-site.xml)
docker-compose exec datanode bash
# Créer un volume nommé myvolume, pour l'utilisateur myser avec un quota de 1Tio
ozone sh volume create --quota=1TB --user=myuser /myvolume
# Créer un bucket dans ce volume dénommé mybucker
ozone sh bucket create /myvolume/mybucket
# Créer un fichier et l'insérer avec la clef myfile
echo 'Ozone est génial!' > /tmp/ozone.txt
ozone sh key put /myvolume/mybucket/ozone.txt /tmp/ozone.txt
# Obtenir notre fichier
ozone sh key get /myvolume/mybucket/ozone.txt /tmp/getozone.txt
cat /tmp/getozone.txt
## Ozone is great!
Comme vous pouvez le voir, la CLI Ozone est très intuitive. Simplement une combinaison de ozone sh objet action url
. Par défaut la CLI utilise le protocole RPC pour se connecter avec le Ozone Manager configuré dans le ozone-site.xml.
Utilisation de REST et RPC
L’Ozone Manager expose son serveur HTTP sur le port 9874 et son serveur RPC sur le port 9862. Les deux protocoles supportent les mêmes opérations. Une webUI est exposé par le serveur HTTP à l’adresse http://localhost:9874
(mais il n’y pas encore grand chose à voir).
Pour être explicite, il est possible de basculer entre le protocole HTTP et RPC en changement le protocole et le port de l’URI du fichier.
# Obtenir un fichier par la CLI avec le protocole RPC
ozone sh key get o3://ozoneManager:9862/myvolume/mybucket/ozone.txt /tmp/getozone.txt
# Obtenir un fichier par la CLI en REST
ozone sh key get http://ozoneManager:9874/myvolume/mybucket/ozone.txt /tmp/getozone.txt
# Obtenir le fichier en REST directement (avec wget)
curl -i -H "x-ozone-user: PA" -H "x-ozone-version: v1" -H "Date: Mon, 22 Apr 2019 18:23:30 GMT" -H "Authorization:OZONE" "http://datanode:9880/myvolume/mybucket/ozone.txt"
#HTTP/1.1 200 OK
#Content-Type: application/octet-stream
#x-ozone-server-name: a037e9952722
#x-ozone-request-id: 4104582c-bee4-471f-b70f-f862a72d1953
#Date: Mon, 22 Apr 2019 20:50:41 GMT
#Content-Length: 20
#Connection: keep-alive
#
#Ozone is great!
A noter, la CLI d’Ozone se connecte directement à l’Ozone Manager là où wget a besoin de se connecter au DataNode, pourquoi ?
L’API Rest est uniquement déployée sur les Datanodes, exposant le namesapce du Ozone Manager présent dans sa configuration. L’Ozone manager possède un endpoint /serviceList
listant tout les datanodes du cluster. La CLI choisit aléatoirement un des DataNode pour lui router la requête. Au final le Datanode se connecte à l’Ozone Manager en utilisant le format RPC… C’est un comportement étrange, n’oublions pas qu’Ozone est encore en bêta.
Observons ce qu’il se passe quand plusieurs Ozone Manager sont connectés aux mêmes DataNodes :
Let’s see what happens if we have multiple Ozone Manager running against the same DataNodes :
docker-compose scale ozoneManager=2
docker-compose exec datanode bash
# Créeons le volume /myvolume sur les deux Ozone Manager, en RPC
ozone sh volume create o3://ozoneManager1:9862/myvolume
ozone sh volume create o3://ozoneManager2:9862/myvolume
# Ca marche ! Maintenant supprimons ce volume via Http sur le premier Ozone Manager
ozone sh volume delete http://ozoneManager1:9874/myvolume
# Parfait ! Maintenant supprimons de la même manière le volume sur le second OM
ozone sh volume delete http://ozoneManager2:9874/myvolume
## Exception org.apache.hadoop.ozone.client.rest.OzoneException: Delete Volume failed, error:VOLUME_NOT_FOUND
Que s’est-il passé ? Les deux commandes de suppression en HTTP ont été routé vers un seul et même DataNode. Ce Datanode ne connaît que le premier Ozone Manager. La commande a ainsi exécuté deux fois sur le premier Ozone Manager, levant ainsi l’exception à la deuxième exécution.
Ce comportement est corrigé en utilisant le protocole S3, simple d’utilisation et se connectant à l’Ozone Manger au travers du composant servant de passerelle S3. Concrètement : n’utilisez pas REST, il n’est pas fiable et l’objectif n’est pas de le corriger : il faut utiliser S3.
Utilisation de S3
S3 est actuellement un peu compliqué à utiliser avec Ozone et pour cause : S3 n’a pas le notion de volume. Une cartographie doit être faite entre un bucket S3 et un bucket Ozone et son volume (par exmeple “/monvolume/monbucket)
# Nous avons besoin d'au moins 3 datanodes
docker-compose scale datanode=3
# Créons le bucket s3 dénommée monbuckets3
aws s3api --endpoint-url http://localhost:9878 create-bucket --bucket=monbuckets3
# Place a file under the bucket
aws s3 cp --endpoint-url http://localhost:9878 ozone.txt s3://monbuckets3/ozone.txt
# Get the file
aws s3 cp --endpoint-url http://localhost:9878 s3://monbuckets3/ozone.txt ozone.txt
Ca fonctionne ! Maintenant le sujet épineux. Comme S3 n’a pas la notion de volumes, il n’est pas simple d’accéder au fichier au travers de la CLI d’Ozone. Actuellement, l’association est faite comme-ci :
Volume Ozone | Bucket Ozone | Bucket S3 |
---|---|---|
monvolume | monbucket | N/A |
s3$AccessKeyLowercase | mons3bucket | monbuckets3 (avec l'AcessKey configurée) |
La clef d’accès (Acces Key) est la clef d’identification utilisée dans tous les requêtes d’accès aux resssources AWS. Dans le fragement de code suivi la clef d’accès configuré dans ~/.aws/crendentials
est “myAccessKey”. Il n’y pas actuellement besoin de clef secrète car la sécurité n’est pas implementée.
aws s3api --endpoint-url http://localhost:9878 create-bucket --bucket=mynewbucket
aws s3 cp --endpoint-url http://localhost:9878 ozone.txt s3://mynewbucket/ozone.txt
# Récupérons le fichier
ozone sh key get /s3myaccesskey/mynewbucket/ozone.txt /tmp/s3ozone.txt
Utilisation d’OzoneFS
OzoneFS est le système de fichiers compatible Hadoop fourni par Ozone. Utilisons avec la CLI hdfs
. Nous verrons que sans changement de code nous pouvons utiliser les mêmes outils que sur un cluster HDFS classique. Ces commandes peuvent être testées avec les fichiers docker-compose dans le dossier compose/ozonefs
.
Tout d’abord nous ajoutons un nouveau système de fichier au core-site.xml
:
<property>
<name>fs.o3fs.impl</name>
<value>org.apache.hadoop.fs.ozone.OzoneFileSystem</value>
</property>
<property>
<name>fs.defaultFS</name>
<value>o3fs://localhost:9864/volume/bucket</value>
</property>
Il est nécesaire d’ajouter le “.jar” du système de OzoneFS au HADOOP_CLASSPATH
.
export HADOOP_CLASSPATH=/opt/ozone/share/hadoop/ozonefs/hadoop-ozone-filesystem.jar:$HADOOP_CLASSPATH
En utilisant docker-compose, un client HDFS est déjà configuré :
cd compose/ozonefs
docker-compose up -d
sleep 10
docker-compose exec datanode ozone sh volume create /volume
docker-compose exec datanode ozone sh bucket create /volume/bucket
docker-compose exec hadooplast bash
echo "Hello Ozone from HDFS!" > /tmp/hdfsOzone.txt
hdfs dfs put /tmp/hdfsOzone.txt /hdfsOzone.txt
hdfs dfs ls /
exit
docker-compose exec datanode ozone sh keys list /volume/bucket
Au coeur d’Ozone avec scmcli
Pour finir la CLI d’Ozone contient une commande de gestion du Storage Container Manager très utile pour comprendre ce qu’il se passe au coeur du système.
Pour le voir en action suivez ces instructions : placer un gros fichier (1.2 Gio ici) sur un cluster configuré avec une taille de conteneur à 1Gio, un facteur de réplication à 1 et le paramètre “provision batch size” à 1 (le conteneur seront alloués un à la fois).
On peut lire ainsi :
Ozone sh key info /myvolume/mybucket/mylargekey
{
"version" : 0,
"md5hash" : null,
"createdOn" : "Tue, 23 Apr 2019 14:48:57 GMT",
"modifiedOn" : "Tue, 23 Apr 2019 14:49:09 GMT",
"size" : 1200000000,
"keyName" : "mylargekey",
"type" : null,
"keyLocations" : [ {
"containerID" : 1,
"localID" : 101976043538546689,
"length" : 134217728,
"offset" : 0
}, {
"containerID" : 1,
"localID" : 101976043642945538,
"length" : 268435456,
"offset" : 0
}, {
"containerID" : 1,
"localID" : 101976043780112387,
"length" : 268435456,
"offset" : 0
}, {
"containerID" : 1,
"localID" : 101976044047564804,
"length" : 268435456,
"offset" : 0
}, {
"containerID" : 2,
"localID" : 101976044178833413,
"length" : 260475904,
"offset" : 0
} ]
}
Nous pouvons voir que deux conteneurs ont été alloués. Chaque fragment essayant d’être aussi large qu’un bloc dans notre système de gestion de bloc (256 Mio)
ozone scmcli list -s 0
{
"state" : "OPEN",
"replicationFactor" : "ONE",
"replicationType" : "RATIS",
"allocatedBytes" : 939524104,
"usedBytes" : 939524104,
"numberOfKeys" : 5,
"lastUsed" : 112932039,
"stateEnterTime" : 112782013,
"owner" : "9a24f5f1-8f2e-47a6-938e-320b6e693f95",
"containerID" : 1,
"deleteTransactionId" : 0,
"containerOpen" : true
}
{
"state" : "OPEN",
"replicationFactor" : "ONE",
"replicationType" : "RATIS",
"allocatedBytes" : 260475904,
"usedBytes" : 260475904,
"numberOfKeys" : 1,
"lastUsed" : 112932039,
"stateEnterTime" : 112862371,
"owner" : "9a24f5f1-8f2e-47a6-938e-320b6e693f95",
"containerID" : 2,
"deleteTransactionId" : 0,
"containerOpen" : true
}
Les conteneurs ne sont pas encore remplis. Plaçons un autre fichier et regardons l’état des conteneurs :
ozone scmcli list -s 0
{
"state" : "CLOSED",
"replicationFactor" : "ONE",
"replicationType" : "RATIS",
"allocatedBytes" : 1073741832,
"usedBytes" : 1073741832,
"numberOfKeys" : 6,
"lastUsed" : 114971098,
"stateEnterTime" : 112782013,
"owner" : "9a24f5f1-8f2e-47a6-938e-320b6e693f95",
"containerID" : 1,
"deleteTransactionId" : 0,
"containerOpen" : false
}
{
"state" : "CLOSED",
"replicationFactor" : "ONE",
"replicationType" : "RATIS",
"allocatedBytes" : 1326258176,
"usedBytes" : 1326258176,
"numberOfKeys" : 5,
"lastUsed" : 114971098,
"stateEnterTime" : 112862371,
"owner" : "9a24f5f1-8f2e-47a6-938e-320b6e693f95",
"containerID" : 2,
"deleteTransactionId" : 0,
"containerOpen" : false
}
L’algorithme de la pipeline a décidé de suralloués un conteneur (il fait 1.2Gio pour une taille maximum d’1Gio). Il l’a ensuite fermé, l’alternative aurait été d’ouvrir un 3e conteneur.
Si nous avions un facteur de réplication réglé à 3, nous verrions également 2 conteneur. C’est le conteneur lui-même qui est répliqué à travers les DataNodes. Ici c’est la méthode de réplication RATIS qi est utilisée. Cela signifie que les données sont répliquées sur 3 DataNodes aléatoires et l’algorithme RATIS garantie la consistence des données.
Conclusion
Nous avons vu comment déployer un cluster Ozone simple et ce dont il est capable. Nous avons aussi découvert quelques limitations probablement dûes au fait qu’Ozone est toujours en développement. Enfin nous avons vu quelques outils permettant de comprendre ce qu’il se passe à l’intérieur d’un cluster Ozone.
Dans la dernière partie de ce post nous discuterons de stratégie de réplication avancée disponible dans Ozone.