Apache Hadoop 3.x en Raspberry PI

Lo primero es hacerse con el hardware, que en mi caso es:

  • 4x  Raspberry PI 3 modelo B.
  • 4x tarjetas MicroSD de 16GB de Clase 10 UHS-1
  • 4x cables USB a micro-USB
  • Un alimentador USB o un HUB USB que sea capaz de alimentar cada toma con 2A.
  • Un switch FastEthernet de 5 puertos (yo elegí uno GbE por ancho de banda concurrente).
  • 5 latiguillos RJ45.

Aquí tenéis una foto de los componentes:

mihardware

y otra del montaje, donde la caja naranja y el polispan son el elemento clave   😉

pi_cluster

Vamos al grano:

1.- Instalar y configurar el SO en las Raspberries:

Nos bajamos el SO RASPBIAN y descomprimimos el ZIP generándose un IMG que deberemos de “planchar” sobre una microSD.
Instalamos la versión “Jessie Lite” que solo ocupa unos 850MB y además ya incorpora python 2.7.9.

Mediante el comando raspi-config cambiamos el locale a ES-ISO y el TimeZone a Europe/Madrid y dejamos solo habilitado el SSH.
Deshabitamos todos los overlays, incluyendo BT y WiFi y hacemos un sudo systemctl disable hciuart.service.
Modificamos el swampiness y vfs_cache del sistema en el /etc/sysctl.conf:
   vm.swappiness = 0
   vm.vfs_cache_pressure = 50

Por último le ponemos una IP fija editando el /etc/dhcpcd.conf y  editamos también el /etc/hosts y el /etc/hostname para popular el hostname de los nodos. También  deshabilitamos el demonio AVAHI (update-rc.d avahi-daemon disable).

Una vez lista la instalación hacemos una imagen del disco (tarjeta MicroSD) de primera raspberry (esto se puede hacer indistintamente en OSX o en linux) :
   sudo dd bs=1M if=/dev/disk2 | gzip > rasbian.img.gz

Una vez generada la imagen la “planchamos” en el resto de las MicroSDs que serán los discos del resto de los nodos. De nuevo en OSX o linux ejecutamos lo siguiente:
   gunzip –stdout rasbian.img.gz | sudo dd bs=1M of=/dev/rdisk2

Y luego personalizamos la IP y el nombre del nodo en cada raspberry.

2.- Instalar Java 8 en las Raspberries:

Basta con lanzar un sudo apt-get install oracle-java8-jdk

3.- Crear un usuario apache:

No tiene porqué llamarse “apache”, pero es el usuario que ararncará todos los demonios de Hadoop y será el dueño de los binarios y de los almacenes de bloques de HDFS.

Para ello :
   $ sudo adduser apache
   $ sudo adduser apache root

Y añadimos en el /etc/sudoers (visudo):

   apache  ALL=(ALL:ALL)   NOPASSWD: ALL

Y nos aseguramos que el .bashrc del usuario apache en cada uno de los nodos queda así:
export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt
export HADOOP_HOME=/opt/hadoop
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export PATH=$JAVA_HOME:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

4.- Habilitar comunicación SSH por claves entre las Raspberries:

Para ello ejecutamos el ssh-keygen y aceptamos los valores por defecto:

apache@nodo01:~ $ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/apache/.ssh/id_rsa):
Created directory ‘/home/apache/.ssh’.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/apache/.ssh/id_rsa.
Your public key has been saved in /home/apache/.ssh/id_rsa.pub.

Y copiamos el contenido del .ssh/id_rsa.pub de los otros nodos al fichero .ssh/authorized_keys y repetimos la misma operacion con todos los nodos.

5.- Arquitectura general:

El nodo01 (la primera raspberry) será el MASTER (correrá el demonio NameNode de gestión de bloques HDFS y el demonio Resource Manager de YARN).
Los nodos nodo02-04 serán los SLAVES (correrán el demonio de DataNode o almacén de bloques HDFS y el demonio Node Manager y los contenedores de ejecución de aplicación).
El nodo02, adicionalmente, correrá también el demonio SecondaryNameNode.El esquema es el siguiente:

pi_cluster_arq

6.- Instalar y configurar HDFS:

Iniciamos sesión con el usuario “apache” (a partir de ahora lo utilizaremos para la instalación y ejecución del SW) y nos descargamos la release 3.0.0-alpha de Hadoop desde la página web de Apache.org. Para ello ejecutamos en cada uno de los nodos lo siguiente:

    $ sudo chgrp apache /opt
    $ sudo chmod ug+rwx /opt
    $ cd /opt
    $ wget http://apache.rediris.es/hadoop/common/hadoop-3.0.0-alpha1/hadoop-3.0.0-alpha1.tar.gz
    $ tar -zxvf hadoop-3.0.0-alpha1.tar.gz
    $ ln -s hadoop-3.0.0-alpha1 hadoop

En cada uno de los nodos creamos el directorio /hdfs (apache es el owner) con la estructura de directorios necesaria para alojará el almacén de bloques HDFS del DataNode, y los datos del NameNode:
    $ sudo mkdir /hdfs; sudo chown apache:apache /hdfs
    $ mkdir /hdfs/data
    $ mkdir /hdfs/name
    $ mkdir /hdfs/namesecondary
Ahora solo falta editar los ficheros /opt/hadoop/etc/hadoop/core-site.xml y /opt/hadoop/etc/hadoop/core-site.xml. Aquí dejo los que yo he utilizado:

Configuramos las variables de entorno necesarias en el fichero /opt/hadoop/etc/hadoop/hadoop-env.sh como sigue:

export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt
export PATH=$JAVA_HOME:$PATH
export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop

Y añadimos en el .bashrc del usuario apache en cada uno de los nodos lo siguiente:

export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt
export HADOOP_HOME=/opt/hadoop
export PATH=$JAVA_HOME:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

Definimos las IPs o hostnames de todos los nodos workers (DataNodes) en el fichero /opt/hadoop/etc/hadoop/workers de todos nodos:

$ cat /opt/hadoop/etc/hadoop/workers
nodo02
nodo03
nodo04

Y procedemos a dar formato al namespace:

$ /opt/hadoop/bin/hdfs namenode –format

Y por ultimo arrancamos HDFS desde en NameNode (nodo01):

$ /opt/hadoop/sbin/start-dfs.sh

Comprobamos que el nodo01 es NameNode, que el nodo02 es SecondaryNameNode y DataNode, y que los nodos03-04 solo son DataNodes:
apache@nodo01:$ jps

Comprobamos también con el comando hdfs dfsadmin -report y accederemos al interface Web de HDFS a través de http://nodo01:9870

7.- Configurar YARN:

Editar los ficheros /opt/hadoop/etc/hadoop/yarn-site.xml y /opt/hadoop/etc/hadoop/mapred-site.xml. Aquí dejo los que yo he utilizado:

Ya tenemos las IPs/FQDNs de los nodos esclavos en el /opt/hadoop/etc/hadoop/workers del paso anterior así que seguimos adelante y arrancamos YARN desde el nodo master (nodo01) mediante:

$ /opt/hadoop/sbin/start-yarn.sh

De nuevo mediante un “jps” comprobamos que el nodo01 es Resource Manager y el NameNode, que el nodo02 es SecondaryNameNode, DataNode, y NodeManager y que los nodos03-04 solo son DataNodes y NodeManagers.

Accedemos a la WebApp del ResourceManager http://nodo01:8088 y comprobamos.

Nuestro primer MapReduce:

Descargamos algunos libros en fichero TXT y los fusionamos en un único fichero para contar palabras :

$ wget http://www.gutenberg.org/cache/epub/2000/pg2000.txt
$ wget http://www.gutenberg.org/ebooks/8300.txt.utf-8
$ wget http://www.gutenberg.org/files/48895/48895-0.txt
$ wget http://www.gutenberg.org/ebooks/40435.txt.utf-8
$ wget http://www.gutenberg.org/ebooks/40436.txt.utf-8
$ wget http://www.gutenberg.org/ebooks/40437.txt.utf-8
$ wget http://www.gutenberg.org/ebooks/40438.txt.utf-8
$ cat pg*.txt > libros.txt; cat *utf-8 >> libros.txt

El fichero resultante es de unos 13 MB…lo copiamos al HDFS:
$ hdfs dfs -copyFromLocal libros.txt /data/libros.txt

$ hdfs dfs -ls -h /data
Found 2 items
-rw-r–r–   3 apache supergroup     12.9 M 2016-12-31 00:48 /data/libros.txt
-rw-r–r–   3 apache supergroup      2.1 M 2016-12-29 22:01 /data/quijote.txt

Por suerte los binarios de Hadoop incluyen unos JARs de ejemplo que ya hacen esto:

$ hadoop jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.0.0-alpha1.jar wordcount /data/libros.txt /data/resultado

2017-01-04 16:31:15,400 Connecting to ResourceManager at nodo01/192.168.1.201:8032
. . .
2017-01-04 16:32:38,147 INFO mapreduce.Job:  map 0% reduce 0%
2017-01-04 16:33:29,466 INFO mapreduce.Job:  map 22% reduce 0%
2017-01-04 16:33:32,527 INFO mapreduce.Job:  map 53% reduce 0%
2017-01-04 16:33:38,652 INFO mapreduce.Job:  map 67% reduce 0%
2017-01-04 16:34:05,595 INFO mapreduce.Job:  map 83% reduce 0%
2017-01-04 16:34:31,048 INFO mapreduce.Job:  map 100% reduce 17%
2017-01-04 16:34:34,098 INFO mapreduce.Job:  map 100% reduce 60%
2017-01-04 16:34:38,172 INFO mapreduce.Job:  map 100% reduce 76%
2017-01-04 16:34:42,238 INFO mapreduce.Job:  map 100% reduce 100%
2017-01-04 16:34:46,343 INFO mapreduce.Job: job_1483543761545_0001 completed

Si miramos en el WebUI observaremos que en nuestro caso el job ha tardado 2 minutos y 7 segundos en ejecutarse:
mapreduce_job

 

Anuncios

2 comentarios el “Apache Hadoop 3.x en Raspberry PI

    • Hola,
      Gracias por leerme y por tu comentario.
      Este setup está basado en la primera release alfa de Hadoop 3.0.0. La última release de Pig (la 0.16) aún no soporta Hadoop 3.x (http://pig.apache.org/docs/r0.16.0/start.html#req).
      Si haces un downgrade de este install a la release 2.7.3 te debería de funcionar sin problemas (lo acabo de probar…eso si, tienes que formatear de nuevo el HDFS o crearte uno nuevo si no quieres perder lo anterior y aún sigues queriendo tener la posibilidad de arrancar uno u otro). Si has seguido mis pasos ya tendrás las variables de entorno (HADOOP_HOME, etc) bien configuradas y pig es lo que necesita; además por defecto el modo de ejecución es “mapreduce” por lo que apenas tendrás que tocar el “pig.properties” (yo no lo modifiqué y corrió en modo distribuido como aplicación MapReduce en YARN a la primera).
      Por cierto, en breve sacaré un post sobre cómo añadir SPARK a este setup, la verdad es que hay un antes y un después de SPARK 😉

      Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s