Recuerda que puedes descargarte algunos de los ejemplos en la pestaña de Código Fuente

martes, 26 de febrero de 2013

Hadoop: Introducción al desarrollo en Java (Parte I)

En esta entrada voy a explicar una introducción al desarrollo de un programa MapReduce en Java.

Este blog lo estoy desarrollando a partir de la versión 1.0.4. Esta versión permite usar tanto la nueva API de Hadoop como la vieja API (me referiré a ellas como "new API" -releases 1.x- y "old API" -releases 0.20-x). En esta entrada la voy a aprovechar para mostrar las diferencias entre estas dos APIs pero las próximas entradas y desarrollos ya estarán hechas únicamente con la nueva API.

Para explicar una introducción al desarrollo de un programa MapReduce utilizaré el "Hola Mundo" de Hadoop, que es el "Word Count", básicamente se coge un fichero, se cuenta las veces que aparece una palabra y la salida será un listado de palabras (keys) con el número de veces que aparece (values).

Para desarrollar este tipo de programas necesitamos básicamente tres clases:
También antes de empezar a explicar código, hay que tener en cuenta cuáles son los tipos de datos que vamos a utilizar, ya que las clases hay que definirlas con los tipos de entrada y de salida.

En el WordCount el Mapper va a recibir como key elementos de tipo numérico ya que, como ya he explicado en otros artículos, normalmente va a ser el offset del fichero y ese valor no lo vamos a utilizar.
El value que recibe el map es cada una de las líneas del fichero, es decir, valores de tipo texto.
El map va a retornar una lista de pares key/value, donde la key es la palabra localizada (de tipo texto) y el value es un número (en este caso siempre va a devolver un 1 por cada palabra que encuentre).

El Reducer va a recibir una key que será la palabra (dada en el Mapper) de tipo texto y como valores una lista de números. Y finalmente emitirá la palabra que estamos contanto de tipo texto como key, y como value el resultado de las veces que aparece esa palabra, es decir, de tipo número.

En la clase map y en la clase reduce los tipos de entrada no tienen por qué ser los mismos que los de salida. Pero es muy importante tener en cuenta los tipos de la salida del map deben ser los mismos que los de entrada del reduce.

Con el fin de que este artículo no quede demasiado largo, lo he dividido en varios artículos e iré explicando el código escribiendo los comentarios correspondientes.

Para ejecutar y probar el programa en Eclipse podéis leer este artículo.

Continuar con:
Introducción al desarrollo en Java (Parte II): El Mapper (Ejemplo Word Count)
Introducción al desarrollo en Java (Parte III): El Reducer (Ejemplo Word Count)
Introducción al desarrollo en Java (Parte IV): El Driver (Ejemplo Word Count)
Introducción al desarrollo en Java (Parte V): Métodos setup() y cleanup()

jueves, 21 de febrero de 2013

Configuración de Eclipse con Hadoop (Local y Pseudo-Distribuído)

En esta entrada voy a explicar cómo configurar eclipse para poder trabajar con Hadoop.

Por decirlo de alguna forma, hay dos formas de trabajar:
Una realizando una aplicación para ejecutarla en modo pseudo-distribuído a través de los demonios que hemos configurado e instalado (como hemos visto en esta entrada).
Y la otra instalándole al eclipse un plugin que nos permitirá trabajar en modo local, sin necesidad de lanzar los demonios.

Si no tenemos ya el eclipse instalado, descargamos la última versión disponible (actualmente Juno) en http://www.eclipse.org/downloads/





Crear una aplicación y ejecutarla en modo local


Descargamos el plugin de hadoop para eclipse en.
http://wiki.apache.org/hadoop/EclipsePlugIn

Guardamos el jar descargado en {ruta_eclipse}/eclipse/plugins
Arrancamos el eclipse, seleccionamos un workspace. Ahora, si vamos a Window-Open Perspective-Other, podremos seleccionar la vista MapReduce.

Primero hay que configurar Hadoop en el eclipse en Eclipse-Preferencias-Hadoop, ponemos la ruta de donde habíamos instalado hadoop (/usr/local/hadoop/hadoop-1.0.4)




Ahora ya podemos crear nuevas aplicaciones de tipo MapReduce.



Una vez creada la nueva aplicación, el plugin nos permite añadir clases de tipo Mapper, Reduccer y el Driver:


Además, a la hora de crear un nuevo Driver, si le indicamos cuál es el Mapper y el Reducer lo creará con las configuraciones y las relaciones a estas clases hechas.



Hay que tener cuidado que este plugin va a crear las clases con los encabezados y tipos de la "old API", si vamos a querer desarrollar con la "new API" vamos a tener que cambiarlos a mano, tanto los paquetes importados, como los tipos y los encabezados.

También otra cosa en la que hay que tener cuidado, que al desarrollar en Eclipse y en modo local hay tener cuidad con el paso de parámetros entre el Driver y el Mapper o el Reducer.




Crear una aplicación y ejecutarla en modo pseudo-distribuído


Para lanzar Jobs MapReduce hay que seguir todos estos pasos.


Si hemos instalado el plugin de Hadoop para Eclipse, crearíamos una nueva aplicación MapReduce (tal y como hemos visto en la parte de creación y ejecución para modo local).
Si no hemos instalado el plugin de Hadoop, crearíamos una aplicación Java estándar y tendríamos que añadir al build path las librerías que se encuentran en /usr/local/hadoop/hadoop-1.0.4/lib más las que se llaman hadoop-***.jar que se encuentran en la raíz /usr/local/hadoop/hadoop-1.0.4






La instalación de Hadoop la había hecho en el directorio /usr/local/hadoop, así que en ese nivel he creado este sistema de carpetas:
 /usr/local/hadoop/training/jars -> Donde depositaré mis aplicaciones
 /usr/local/hadoop/training/docs -> Donde depositaré ficheros sobre los que quiera trabajar posteriormente en HDFS.

Después de haber desarrollado nuestra aplicación, con el botón derecho sobre el proyecto vamos a Export, seleccionamos Jar File y como destino  /usr/local/hadoop/training/jars/nombreAplicacion.jar



Y por último, a través del terminal arrancar todos los demonios, y lanzar la aplicación a través de los comandos hadoop.

Ahora sólo queda que si la aplicación da algún tipo de error, volveremos al eclipse, corregiremos los cambios y tendremos que volver a exportar el nuevo jar.


Ejecución de Jobs HDFS

Si vamos usar Hadoop sin necesidad de lanzar un Job MapReduce (por ejemplo, si sólo estamos haciendo operaciones HDFS), hay una forma más fácil de lanzarlo.

Tras haber creado la nueva aplicación (bien sea a través del plugin, o a siendo una aplicación Java estándar a la que le hemos incluído las librerías), vamos a las propiedades del proyecto-Java Build Path-Libraries  y luego pulsando sobre "Add External Class Folder" y añadimos la carpeta conf de Hadoop en la ruta /usr/local/hadoop/hadoop-1.0.4/conf



También en este caso tendríamos arrancar el clúster Hadoop a partir de la línea de comandos del terminal.

Pero a partir de ahora, cuando desarrollemos con el Eclipse este tipo de aplicaciones, podremos ejecutarlas en modo pseudo-distribuído sin necesidad de exportar el Jar y haciendo simplemente un Run As Java Application (si es sin el plugin) y con el plugin valdría tanto como Java Application como Run On Hadoop


lunes, 18 de febrero de 2013

Hadoop Ecosystem

¿A qué llamamos Ecosistema Hadoop?
Desde que nació esta tecnología se han creado varios proyectos con distintas utilidades que nos pueden solucionar muchas cosas a la hora de trabajar con Hadoop.

Hadoop es la parte central del sistema y el ecosistema Hadoop es todo el conjunto de proyectos que ayudan a implementar esta solución.

Algunos de los proyectos del Ecosistema son:
  • Hive: Es un sistema de almacenamiento de datos (Data Warehouse) para Hadoop y basado en metadatos. Tiene un lenguaje parecido a SQL (HiveQL) y genera código MapReduce que funciona sobre Hadoop. En Facebook, más del 99% de los Jobs MapReduce se generan a partir de Hive.
  • Pig: Al igual que Hive, tiene un lenguaje propio (pero más tipo scripting) llamado PigLatin y que también se convierte en Jobs MapReduce que funcionan en el clúster. En este caso no tiene metadatos (por eso es más sencillo de instalar que Hive).
  • Impala: Permite queries en tiempo real sobre datos en HDFS. No usa MapReduce, usa sus propios demonios y luego ejecutándose en cada nodo esclavo. Su lenguaje es similar a HiveQL y tanto los datos como los metadatos que usa son los mismos que los de Hive.
  • Flume: Es un software para importar datos en tiempo real en un cluster Hadoop (sirve para la ETL: Extraction Transformation and Load). Ideal para recolectar logs de múltiples sistemas y almacenarlos a HDFS. Soporta una gran variedad de fuentes (como syslog, log4j, etc).
  • Chuckwa: Este proyecto realiza ETL de una forma parecida a Flume. También contiene un módulo de visualización de los mismos.
  • Sqoop: Es un proyecto desarrollado para importar datos desde bases de datos relacionales a HDFS y por lo tanto, es también un sistema de ETL. Se puede importar toda la BD, sólo algunas tablas o sólo partes de la tabla. También permite realizar la operación inversa: exportar datos en HDFS a una base de datos relacional.
  • Oozie: Se puede decir que es un motor de workflow utilizado para el encadenamiento de Jobs. Se ejecuta en un servidor fuera del clúster y se suele utilizar para workflows complejos, que sean lineales o gráfos. Puede encadenar Jobs MapReduce, Pig, Hive, etc.
  • HBase: Se podría decir que "es la Base de Datos NoSql Hadoop". Puede almacenar hasta petabytes de datos, está orientado a columnas (las relacionales a filas), permite miles de insert por segundo, las tablas pueden tener varios miles de columnas. Al contrario de Hive, su lenguaje de query no es intuitivo y no se parece a SQL.
  • Avro: Es un sistema para la serialización de datos que se usa como alternativa a los SquenceFiles. Tiene un formato propio de compresión, se puede exportar a otros lenguajes que no sean Java y tiene sus propios formatos para el Mapper y el Reducer (AvroMapper y AvroReducer).
  • ZooKeeper: Herramienta para la configuración y sincronización de aplicaciones distribuídas.

En otras entradas profundizaré más sobre algunos de estos proyectos.