Configurando el entorno de desarrollo
El primer paso para poder crear una aplicación en MapReduce es configurar un entorno de desarrollo, en donde poder escribir las funciones map y reduce.
Utilizaré Eclipse para desarrollar las aplicaciones MapReduce en Java, utilizando Maven para definir los proyectos:
- Eclipse es un programa informático compuesto por un conjunto de herramientas de programación de código abierto multiplataforma. Esta plataforma, típicamente ha sido usada para desarrollar entornos de desarrollo integrados (del inglés IDE), como el IDE de Java llamado Java Development Toolkit (JDT) y el compilador (ECJ) que se entrega como parte de Eclipse (y que son usados también para desarrollar el mismo Eclipse).
- Maven es una herramienta de software para la gestión y construcción de proyectos Java creada por Jason van Zyl, de Sonatype, en 2002. Tiene un modelo de configuración de construcción simple, basado en un formato XML. Es un proyecto de nivel superior de la Apache Software Foundation. Maven utiliza un Project Object Model (POM) para describir el proyecto de software a construir, sus dependencias de otros módulos y componentes externos, y el orden de construcción de los elementos. Viene con objetivos predefinidos para realizar ciertas tareas claramente definidas, como la compilación del código y su empaquetado. Como casi todo el ecosistema de Apache Hadoop está escrito en Java, Maven es una gran herramienta para gestionar proyectos construido sobre las APIs de Hadoop.
He de decir que parto de cero, puesto que nunca he utilizado ni Eclipse para desarrollar aplicaciones Java, ni había oído nada sobre Maven, por lo que me he tenido que documentar y estudiar un poquito... Recomiendo unos cuantos enlaces que me han ayudado:
Primeros pasos con Maven -
Integrando Maven y Eclipse
Cómo desarrollar aplicaciones CDH con Maven y Eclipse
Usando el repositorio de Maven de CDH5
Manejando las dependencias de la API de Hadoop en CDH5
Creando mi primera aplicación
En la página de documentación de Cloudera Manager podemos encontrar un pequeño
tutorial para crear una aplicación MapReduce que lee todos los ficheros de texto contenidos en un directorio y cuenta el número de veces que aparece cada palabra.
Creamos un proyecto básico en Maven:
astwin@astwin-H87-HD3:~$ mvn archetype:create -DgroupId=astwin.hadoop -DartifactId=Ejemplo_WordCount
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-archetype-plugin:2.2:create (default-cli) @ standalone-pom ---
[WARNING] This goal is deprecated. Please use mvn archetype:generate instead
[INFO] Defaulting package to group ID: astwin.hadoop
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:RELEASE
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: astwin.hadoop
[INFO] Parameter: packageName, Value: astwin.hadoop
[INFO] Parameter: package, Value: astwin.hadoop
[INFO] Parameter: artifactId, Value: Ejemplo_WordCount
[INFO] Parameter: basedir, Value: /home/astwin
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /home/astwin/Ejemplo_WordCount
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.790s
[INFO] Finished at: Wed Mar 12 11:28:23 CET 2014
[INFO] Final Memory: 8M/239M
[INFO] ------------------------------------------------------------------------
astwin@astwin-H87-HD3:~$ cd Ejemplo_WordCount/
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ sudo gedit pom.xml
Modificamos el archivo pom.xml para configurar el proyecto:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>astwin.hadoop</groupId>
<artifactId>Ejemplo_WordCount</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>EjemploWordCount</name>
<url>http://maven.apache.org</url>
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.2.0-cdh5.0.0-beta-1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Creamos el proyecto para cargarlo con el IDE (Eclipse):
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ mvn eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=True
Lo importamos en Eclipse, añadimos las clases de la aplicación y construimos el archivo JAR.
|
Proyecto WordCount compilado |
Ejecutando mi primera aplicación
Almacenando en HDFS los ficheros
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ hadoop fs -mkdir /astwin/Ejemplo_WordCount
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ echo "uno dos dos tres tres tres" > file01
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ echo "Ejecutando mi primer programa creado en MapReduce" > file02
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ hadoop fs -put file* /astwin/Ejemplo_WordCount
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ hadoop fs -ls /astwin/Ejemplo_WordCount
Found 2 items
-rw-r--r-- 3 astwin supergroup 27 2014-03-12 11:44 /astwin/Ejemplo_WordCount/file01
-rw-r--r-- 3 astwin supergroup 50 2014-03-12 11:44 /astwin/Ejemplo_WordCount/file02
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ hadoop fs -cat /astwin/Ejemplo_WordCount/file01
uno dos dos tres tres tres
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ hadoop fs -cat /astwin/Ejemplo_WordCount/file02
Ejecutando mi primer programa creado en MapReduce
Ejecutando el programa
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ sudo -u hdfs hadoop jar /home/astwin/Ejemplo_WordCount/target/Ejemplo_WordCount-1.0-SNAPSHOT.jar astwin.hadoop.WordCount /astwin/Ejemplo_WordCount /astwin/Ejemplo_WordCount/output
...
14/03/12 11:51:33 INFO mapreduce.Job: Running job: job_1394612204892_0002
14/03/12 11:51:37 INFO mapreduce.Job: Job job_1394612204892_0002 running in uber mode : false
14/03/12 11:51:37 INFO mapreduce.Job: map 0% reduce 0%
14/03/12 11:51:41 INFO mapreduce.Job: map 33% reduce 0%
14/03/12 11:51:42 INFO mapreduce.Job: map 67% reduce 0%
14/03/12 11:51:44 INFO mapreduce.Job: map 100% reduce 0%
14/03/12 11:51:48 INFO mapreduce.Job: map 100% reduce 20%
14/03/12 11:51:49 INFO mapreduce.Job: map 100% reduce 40%
14/03/12 11:51:51 INFO mapreduce.Job: map 100% reduce 80%
14/03/12 11:51:52 INFO mapreduce.Job: map 100% reduce 100%
14/03/12 11:51:53 INFO mapreduce.Job: Job job_1394612204892_0002 completed successfully
14/03/12 11:51:53 INFO mapreduce.Job: Counters: 43
......
Comprobamos la salida
Comprobamos como la salida es la esperada:
astwin@astwin-H87-HD3:~/Ejemplo_WordCount$ hadoop fs -cat /astwin/Ejemplo_WordCount/output/part*
creado 1
mi 1
dos 2
en 1
tres 3
MapReduce 1
primer 1
programa 1
Ejecutando 1
uno 1