Hadoop Pig : traitement des flux de données

Traiter des gros volumes de données et offrir des services à base de ces traitements nécessite des méthodes et des processus de traitement hautement productifs. Dans cette optique que le projet Hadoop Pig à vu le jour. Il démocratise les traitements et les rend accessible au non développeur, en proposant un langage d’abstraction simple au-dessus de MapReduce.

 

La complexité et l’expérience nécessaire dans le développement de job MapReduce sont masqué par une DSL nommé Pig Latin, elle permet d’écrire des scripts de traitement de données qui sont traduits en jobs MapReduce et exécutés sur le cluster Hadoop.

1. Pig c’est quoi?

Pig est un système de traitement des gros volumes de données en utilisant la plateforme Hadoop MapReduce (figure 1). Il est composé  de deux  modules qui sont :

  • Pig Latin: langage procédural de haut niveau
  • Pig Engine : parse, optimise et exécute automatiquement les scripts PigLatin comme  une série de jobs MapReduce au sein d’un cluster Hadoop.

Il fournit les opérations standards pour la manipulation de données (filters, joins, ordering) , des types primitifs, des types complexe (tuples, bags, maps). Simple à comprendre, il ouvre la voie vers Hadoop au non programmeur MapReduce.

 

g3165Figure 1. Pig process

2. Architecture de Pig

Pig s’installe sur la machine local de l’utilisateur. Il ne nécessite aucune installation sur le cluster Hadoop (figure 2).

pig_archFigure 2. Interaction de Pig avec le cluster Hadoop

 

La figure 3 montre les différentes étapes que suit Pig dans la construction d’un Job MapReduce.

 

pig_mr_step_generation

Figure 3. Processus de création d’un job MapReduce avec Pig

  pig_logique_physique_mr

Figure 4. Processus du passage du plan logique au MapReduce

3. Interagir avec Pig

Pig offre trois modes pour exécuter des taches Pig, qui sont :

3.1 Mode script

Il s’agit d’un ensemble d’instructions du langage Pig réunies dans un fichier de type batch.

 

/* id.pig */

A = load 'passwd' using PigStorage(':');  -- load the passwd file 
B = foreach A generate $0 as id; -- extract the user IDs
store B into ‘id.out’; -- write the results to a file name id.out

 

L’exécution du fichier se fait comme indiquez ci-dessous

pig id.pig 

3.2 Mode interactive

Il s’agit d’interagir avec le shell Pig. Dans ce mode, on peut lancer des traitements MapReduce ou interagir avec HDFS.

$ pig 
...  Connecting to ...
grunt> A = load 'passwd' using PigStorage(':');
grunt> B = foreach A generate $0 as id;
grunt> dump B;

3.3 Mode API 

Pig dispose d’une API Java qui permet d’appeler Pig via des programmes Java.

import java.io.IOException;
import org.apache.pig.PigServer;

public class WordCount {
   public static void main(String[] args) {
      
      PigServer pigServer = new PigServer();
        
      try {
         pigServer.registerJar("/mylocation/tokenize.jar");
         runMyQuery(pigServer, "myinput.txt";
        } 
      catch (IOException e) {
         e.printStackTrace();
        }
   }
   
   public static void runMyQuery(PigServer pigServer, String inputFile) throws IOException {        
       pigServer.registerQuery("A = load '" + inputFile + "' using TextLoader();");
       pigServer.registerQuery("B = foreach A generate flatten(tokenize($0));");
       pigServer.registerQuery("C = group B by $1;");
       pigServer.registerQuery("D = foreach C generate flatten(group), COUNT(B.$0);");
      
       pigServer.store("D", "myoutput");
   }
}

 

L’exécution du fichier se fait comme indiquez ci-dessous

java -cp <path>pig.jar WordCount

4. Modèle de données dans Pig

Pig supporte deux types de données. Le premier type de données portent sur les données dites simples, appelées scalaires. Le second type est relatif au type de données complexes.

4.1 Scalaires

Les scalaires représentent les types de données simples qu’on trouvent presque dans tous les langages de programmation. Les types de données scalaires supportés par Pig sont représentées par des interfaces du package java.lang, qui sont :

 

  • Int : ce dernier représente les entiers. Il est représenté par l’interface java.lang.Integer. Il est codé sur sur 4 bits signées.

  • Long : il représente les entiers de type long. Il est représenté par l’interface java.lang.Long. Il est codé sur 8 bits signés.

  • Float : ce dernier désigne les données de type réel. Il est représenté par l’interface java.lang.Float. Il est codé sur 5 bits.

  • Double : il désigne les données de type réels ( double précision). Il est représenté par l’interface java.lang.Double. Il est codé sur 8 bits.

  • Chararray : ce dernier permet de représenter les string ou un tableau de caractère. Il est représenté par l’interface java.lang.String. Le chaines constantes peuvent etre exprimés par un simple quotte. Les caractères de contrôles doivent etre précédés par « \ ».

  • bytearray : il représente une un tableau de byte. Il est représenté par une classe java, appelé DataByteArray, qui a son tour encapsule un tableau de bits (byte[]).

4.2 Type complexe

Pig supporte trois types, les map, les tuples et les bag. Ces trois types peuvent contenir tout type de données, inclut les types complexes. Par consequent, il est possible d’avoir une donnée de type map qui contient des données de types bag ou tuple.

 

Map [key#val[,key#val…]]

Il s’agit d’un map, composé d’une clé et une valeur. La clé est de type chararray, elle est utilisée comme index pour trouver la valeur associée. La valeur est considéré comme un «bytearray». Une opération de « cast » est possible si le type de la valeur est connu.

Depuis la version 0.9 de Pig, il est possible de déclarer des map avec des valeurs « typées ».

 

Tuple (field[,field..])

Il s’agit d’une collection ordonnée. Le tuple est composé de plusieurs champs, chaque champ peut être de n’importe quel type. Les éléments d’un tuple ne sont pas forcement de même type. Il est possible d’accéder à un champs à travers sa position.

Pig permet d’associer un schéma à un tuple pour décrire le type de chaque champ et lui donner un nom. L’association d’un schéma à un tuple, en Pig, est facultatif. Associer un schéma à un tuple permet à Pig de vérifier l’intégrité des données et d’offrir la possibilité d’accéder un champ via son nom.

 

Bag {tuple[,tuple…]}

Il s’agit d’une collection de tuple non ordonnée, c-a-d, la notion de position n’est pas supportée. Dans un bag, il est impossible d’accéder un champ via sa position. Comme les tuples, il est possible d’associer un schéma à un bag pour décrire le type de chaque champs.

{('tom', 'h',34), ('sylvie', 'f',52), ('john', 'h')} 

 

Voici, quelques points relatives aux Bags :

  • Un bag peut avoir des tuples en double.

  • Un bag peut avoir des tuples avec un nombres champs différent. Toutefois, si Pig tente d’accéder à un champ qui n’existe pas, une valeur nulle est substitué.

  • Un bag peut avoir des tuples avec des champs qui ont des types de données différents. Cependant, pour traiter efficacement les bag, les schémas des tuples dans ces bags doivent être les mêmes.

4.3 Relation

Une relation est un bag de tuple. Par analogie, nous pourrons dire qu’une table d’une base de données est l’équivalent d’une relation en Pig. Et un enregistrement d’une table est l’équivalent d’un tuple dans un bag.
Contrairement à une table relationnelle, les relations en Pig n’exigent pas que chaque tuple doit contenir le même nombre de champs ou les champs situés la même position (colonne)  doivent avoir le même type.

 

relation

Figure 4. Relation, Bag, Tuple et champs

 

/* 
 * La relation A est composé des tuple de tuple 
 * de ( chaine, entier, float)
*/
A = LOAD 'student' USING PigStorage() AS (name:chararray, age:int, gpa:float);

4.4 Schéma

Les schémas permettent d’associer les noms et les types des champs dans une relation. Ils sont facultative mais recommandée, car ils permettent le contrôle des erreurs ainsi que une meilleur optimisation dans l’exécution du code.

 

schema_pigFigure 5. Création d’un schéma dans Pig

 

Le tableau ci-dessous  présente les syntaxes de création de schémas :

 

pig_001 

 Tableau 1. Syntaxe de création de schémas

4.5 Référencer un champs d’un tuple

Pig offre la possibilité de référencer un champs soit par sa position, soit par nom. Notons que dans certains cas, certaines structures ne supporte l’accès à ses champs via une position.

 

L’accès par position : pour accéder via la position du champs en question, il suffit d’utiliser l’opérateur $ suivi par le numéro de la position. Notons la première position est désigné par $1. La position n est représentée par $(n-1).

 

L’acces par nom : dans ce cas le nom désigne l’identificateur du champs. L’affectation du nom au champs peut être réalisée :

  • lors de l’utilisation d’un schéma

  • lors de l’appel d’un opérateur « GROUP BY »

Notons que lors de la mise au point de vos script Pig, il est plus intéressant de référencer les champs par leurs noms.

Ci-dessous un exemple qui référencent deux champs. L’accès au premier est réalisé par sa position. Quand au second, l’accès a ce dernier s’effectue via son nom.

 

A = LOAD '/tmp/file' USING PigStorage() AS (name:chararray, age:int, gpa:float);
X = FOREACH A GENERATE name,$2;
DUMP X

 

La 1 ligne du script s’occupe du chargement des données ‘/tmp/file’ en utilisant le schéma (name:chararray, age:int, gpa:float). Ces données chargées sont accessible via la relation A.

La 2 ligne extrait le nom et le champs de la 2 position de la relation A. Les deux champs extraits sont référencés par X

La 3 ligne affiche les données référencées par X.

4.6 Référencer un champs de type complexe 

Comme, il a été signalé précédemment, un tuple peut contenir n’importe quel type de champs, inclus les types complexes tels que les tuples, les maps, et les bags.

 

Afin de faciliter l’écriture et la mise au point des scripts Pig, il est conseillé de :

  • Utiliser les schémas pour les types de données complexes.

  • Utilisez les opérateurs de déréférencement pour référencer et utiliser des champs qui sont des types de données complexes.

cat data.log;
(jim, 6, 8,9) (Rach, 7,5,6) (Dia, 1,4,7) (Livus, 3,7,5) (Alex, 2,5,8) (Alain, 9,5,8) A = LOAD 'data.log' AS (t1:tuple(name:chararray, t1a:int,

t1b:int,t1c:int),t2:tuple(name:chararray, t2a:int,t2b:int,t2c:int)); DUMP A;
((jim, 6, 8,9), (Rach, 7,5,6)) ((Dia, 1,4,7), (Livus, 3,7,5)) ((Alex, 2,5,8), (Alain, 9,5,8)) X = FOREACH A GENERATE t1.name, t1.t1a,t2.$0; DUMP X;
(Jim, 3,7) (Dia, 1,3) (Alex,2,9)

4.7 Nulls

L’implémentation de « Nulls » dans Pig s’inspire de celle de SQL. Un objet est dit nul si il est inconnu. L’état « Nulls » peut se produire lors de la récupération des données ou lors des opérations sur ces dernières.

 

Voici quelle que cas ou cette situation peut se présenter :

  • Opérateurs de comparaison : si l’un des opérandes est null, alors la valeur de retour est nul aussi.

  • Opérateurs arithmitique : si l’un des opérandes est null, la valeur de retour est null aussi

  • Operateur Null (is null ) : si la valeur testée est nulle, alors le retour est « true », sinon « false ».

  • Operateur non Null (is not nulls) : le principe de fonctionnement est similaire a celui du « is null ».

  • Operateur de deferencement (.) : si un tuple ou un map est nul alors valeur de retour est nul.

5. Pig Latin

Un script Pig Latin ce résume en trois étapes, qui sont :

  • Chargement des données à partir du cluster Hadoop et plus précisement a partir du stockage distribué HDFS
  • Transformation des données via des opérations de filtre, de joiunture, d’agrégation, d’ordonessement et bien d’autres.
  • Stockage des données ou bien visualisation sur une sortie adaptée.

transformation-01

Figure 5. Processus de traitement des données dans Pig

 

5.1 Les entrée et sortie

5.1.1 Chargement des données

Dans un flux de données, la premiere étape consiste a specifier l’entrée. En Pig, le chargement des données se fait par l’instruction « Load ».

Par defaut, Pig charge les données à partir de HDFS et selon un path predifnie. En revanche, il est aussi possible d’effectuer un chargement des donnees via un autre systeme de stockage tel que HBase.

La syntaxe generale relative l’instruction Load est :

LOAD 'data' [USING function] [AS schema];

Avec :

  • Data : le nom du fichier ou répertoire entre simple quotte. Si c’est un répertoire, tous les fichier de de dernier seront chargés.

  • Using : un mot clé de Pig. En cas d’omission d’un mot clé, Pig utilise par défaut la fonction PigStorage, ie, le chargement à partir du système HDFS.

  • Function : il s’agit de la fonction de chargement de données. En effet, les données sont stockées dans un format, et cette fonction s’occupe de lire les données en prenant un tel format. Par defaut, Pig fait appel à la fonction PigStorage. En revanche, il est possible de préciser sa propre fonction (UDF).

  • Schema : il est aussi optionnel.

1. A = LOAD 'data.txt';

2. A = LOAD 'data.txt' USING PigStorage('\t');

3. A = LOAD 'data.txt' AS (f1:int, f2:int, f3:int);

4. A = LOAD 'data.txt' USING PigStorage(‘\t’) AS(f1:int,f2:int, f3:int);

5.1.2 La persistance des données en Pig

Après la phase de traitement de données vient la phase du persistance des données. Pig offre des outils relatives à cet effet. Par défaut, Pig stocke les données sur HDFS dans un fichier en faisant appel à PigStorage. Mais, il est possible de préciser d’autre fonction comme HBaseStorage.

 

L’écriture des résultats de traitement nécessite le chemin relatif ou le chemin absolu du fichier.

STORE alias INTO 'name_directory' [USING function];
  • L’instruction precedente a pour objectif de stocker la relation « alias » dans le dossier « name-directory ».

  • Alias : il designe le nom de la relation à stocker

  • directory : il designe le dossier de stockage

  • using function : il s’agit d’effectuer un stockage en faisant appel à une fonction.

  • Cette instruction est optionnel. Par defaut Pig, utilise PigStorage dans HDFS. Il est aussi possible d’utiliser HBaseStorage. Vous pouvez aussi definir votre propore fonction (UDF).

 

Voici 3 manière de stocker les résultats de trainement dans le dossier « resultatTraitement » en utilisant PigStrage()

1. store res into '/data/resultatTriatement';

2. store res into hdfs://data.process.com/data/resultatTriatement;

3. store res into '/data/resultatTriatement'using PigStorage()

5.1.3 L’affichage des données dans Pig

Parfois, il est utile d’afficher le résultat de traitement à l’écran. L’affichage devient nécessaire dans le cadre de la mise au point d’un programme ou la réalisation d’un prototype.

Pig offre des mécanises pour afficher de données l’écran. Pour ce faire, il suffit d’utiliser « DUMP nom_relation ».

Lors de l’affichage des données, Pig adopte un format selon le type de la donnée.

DUMP nom_relation

5.2 Opérateurs relationnels

Cette section est consacré aux opérateurs relationnels. En effet, Pig offre des outils dites de transformation de données tels que le tri, le groupement, la jointure ainsi que le filtrage. Le détails des toutes ces opérations est dans la documentation officiel.

5.2.1 Transformation

foreach

foreach permet de chargement des enregistrement et le traitement de ces dernier si besoin.

 

pig_003

A = load 'input' as (user:chararray, id:long, phone:chararray, preferences:map[]);

B = foreach A generate user, id;

 

Le reste des opérations sont détaillées dans la documentation officiel http://pig.apache.org/docs/r0.10.0/basic.html

6. Extension ou User Defined Functions

Pig permet des traitements personnalisées via le concept de UDF (user defined functions) . Les UDF dans Pig peuvent être implémentées avec quatre langages qui sont : Java, Python, Ruby et JavaScript. Avec les UDF, l’utilisateur peux spécifier des méthodes propres de chargement de données, stockage ou de traitement. Pig fournit un référentiel de fonctions UDF, il est alimenté par les utilisateur de Pig.

 

Plus de détails dans comment implémenter les UDF est dans la documentation officiel.

Référence
  1. Building a High-Level Dataflow System on top of Map-Reduce: The Pig Experience, Alan F. Gates, Olga Natkovich, Shubham Chopra, Pradeep Kamath, Shravan M. Narayanamurthy, Christopher Olston, Benjamin Reed, Santhosh Srinivasan, Utkarsh Srivastava, Août 2009 (Yahoo)
  2. Practical Problem Solving with Hadoop and Pig, Milind Bhandarkar, 2009 ( Yahoo Inc)
  3. Programming Pig, Alan Gates, 2011 O’Reilly
  4. http://pig.apache.org/docs/r0.10.0/

  5. Apache Pig at Twitter, Jonathan Coveney, 2012 (Twitter)

  6. Hadoop Real-World Solutions Cookbook, Jonathan R. Owens,
    2013 Packt Publishing

     

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *


+ 3 = 10

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>