Desplegando un cluster distribuido con Hadoop 2.6.0

Apache Hadohadoopop es un framework que permite el procesamiento distribuido de grandes conjuntos de datos a través de un conjunto de ordenadores utilizando modelos básicos de programación.

Hadoop está diseñado para escalar de un servidor individual a miles de máquinas, ofreciendo computación y almacenamiento local. Por otro lado, en lugar de depender del hardware para ofrecer HA, Hadoop detecta y controla los errores en la capa de aplicación.

Conceptos básicos de Hadoop

  • HDFS (Hadoop Distributed File System): es un sistema de archivos distribuido altamente tolerante a fallos y está diseñado para ser implementado en hardware de bajo coste.
  • YARN (Yet Another Resource Negotiator): es el sistema de gestión de recursos del cluster Hadoop
  • Nodos Masters: Servidores que albergan los servicios de administración del cluster Hadoop:
    • NameNode: Encargado de administrar el almacenamiento HDFS.
    • SecundaryNameNode: Encargado de realizar los checkpoints (puntos de control) periódicos del NameNode.
    • ResourceManager: Supervisa la programación de tareas y gestiona los recursos del cluster Hadoop
  • Nodos Slaves: Servidores encargados de realizar el procesamiento y almacenamiento de los datos. Los servicios que albergan son los siguientes:
    • DataNode: Servicio de HDFS que permite al NameNode almacenar los bloques de datos en un SlaveNode.
    • NodeManager: Coordina los recursos para cada Slave Node y reporta la información el ResourceManager.
    • ApplicationMaster: Realiza el seguimiento del proceso de las tareas que se ejecutan en el cluster para una aplicación específica. Se despliega un ApplicationMaster por cada aplicación cliente.
    • Container: Colección de todos los recursos necesarios para ejecutar las tareas de una aplicación.

Especificaciones de las máquinas

En este tutorial, las máquinas de ejemplo que se utilizan tienen las siguientes especificaciones:

  • Plataforma: Máquina virtual sobre OpenStack
  • SO: Ubuntu Server 14.04
  • Cores: 2
  • RAM: 4GB
  • Disco: 40 GB

Software

La versión de Hadoop utilizada será Hadoop 2.6.0 (Apache Software Fundation)

Arquitectura

La arquitectura, en modalidad cluster que vamos a desplegar es la siguiente:

  • 1 Master Node (ResourceManager y NameNode):
    • hd-master
  • 3 Slaves Nodes (DataNode y NodeManger):
    • hd-slave1
    • hd-slave2
    • hd-slave3

Requisitos Iniciales

Incluimos el nombre FQDN de todos los nodos que conforman el cluster  en el fichero /etc/hosts:

192.168.40.4 hd-master
192.168.40.5 hd-slave1
192.168.40.6 hd-slave2
192.168.40.7 hd-slave3

Creamos el usuario y grupo hadoop:

root@hd-master:~# addgroup hadoop
root@hd-master:~# adduser --ingroup hadoop hadoop
root@hd-master:~# passwd hadoop

Establecemos la relación de confianza SSH entre el MasterNode y los SlavesNodes:

root@hd-master:~#su - hadoop
hadoop@hd-master:~#ssh-keygen -t rsa
hadoop@hd-master:~#ssh-copy-id hadoop@hd-slave1

#Comprobamos el acceso sin password
hadoop@hd-master:~# ssh hadoop@hd-slave1

Instalación de Java:

root@hd-master:~# apt-get install default-jdk
root@hd-master:~# java -version
java version "1.7.0_65"
OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.3-0ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.65-b04, mixed mode)

Inclusión de variables de entorno de Hadoop y Java en el fichero .bashrc del usuario hadoop:

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
export HADOOP_INSTALL=/usr/local/hadoop
export PATH=$PATH:$HADOOP_INSTALL/bin
export PATH=$PATH:$HADOOP_INSTALL/sbin
export HADOOP_MAPRED_HOME=$HADOOP_INSTALL
export HADOOP_COMMON_HOME=$HADOOP_INSTALL
export HADOOP_HDFS_HOME=$HADOOP_INSTALL
export YARN_HOME=$HADOOP_INSTALL
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_INSTALL/lib/native
export HADOOP_OPTS="-Djava.library.path=$HADOOP_INSTALL/lib"

Instalación y Configuración  de Hadoop

Antes de iniciar la instalación debemos conocer los ficheros de configuración disponibles en Hadoop y que se configura en cada uno de ellos:

Fichero Formato Descripción
hadoop-env.sh Bash script Variables de entorno que son usadas en los scripts que ejecutan Hadoop.
core-site.xml Hadoop configuration XML Configuración para Hadoop Core, como ajustes de I/O que son comunes para HDFS y MapReduce.
hdfs-site.xml Hadoop configuration XML Ajustes de configuración para los daemons de HDFS: NameNode, Secundary NameNode y DataNodes.
mapred-site.xml Hadoop configuration XML Ajustes de configuración para los daemons MapReduce: Jobtracker, Tasktrackers o YARN.
yarn-site.xml Hadoop configuration XML Ajustes de configuración específicos para YARN.
masters Texto Plano Lista de máquinas (una por línea) que iniciarán un Secundary NameNode.
slaves Texto Plano Lista de máquinas (una por línea) que iniciarán un DataNode y un NodeManager

A continuación, descargamos e instalamos Hadoop en el nodo master (después de realizar la configuración, la replicaremos en todos los nodos slaves)

wget http://ftp.cixug.es/apache/hadoop/common/hadoop-2.6.0/hadoop-2.6.0.tar.gz
tar xzvf hadoop-2.6.0.tar.gz
mv hadoop-2.6.0 /usr/local/hadoop
chown -R hadoop:hadoop /usr/local/hadoop

Realizamos la configuración básica en el nodo Master:

Editamos /usr/local/hadoop/etc/hadoop/core-site.xml:

<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://hd-master:9000</value>
    <description>NameNode URI</description>
  </property>
</configuration>

Editamos /usr/local/hadoop/etc/hadoop/hdfs-site.xml:

<configuration>
  <property>
    <name>dfs.replication</name>
    <value>3</value>
    <description>Default block replication</description>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>file:/usr/local/hadoop/hadoop_data/hdfs/namenode</value> 
  </property>
</configuration>

Editamos /usr/local/hadoop/etc/hadoop/mapred-site.xml:

<configuration>
  <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    <description>Execution framework</description>
  </property>
</configuration>

Editamos /usr/local/hadoop/etc/hadoop/yarn-site.xml:

<configuration>
  <property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
    <description>shuffle service for MapReduce</description>
  </property>
  <property>
    <name>yarn.resourcemanager.resource-tracker.address</name>
    <value>hd-master:8025</value>
    <description>ResourceManager for NodeManagers</description>
  </property>
  <property>
    <name>yarn.resourcemanager.scheduler.address</name>
    <value>hd-master:8030</value>
    <description>ResourceManager for ApplicationMasters</description>
  </property>
  <property>
    <name>yarn.resourcemanager.address</name>
    <value>hd-master:8050</value>
    <description>ResourceManager for clients to submit jobs</description>
  </property>
</configuration>

Editamos /usr/local/hadoop/etc/hadoop/slaves:

hd-slave1
hd-slave2
hd-slave3

Creamos el directorio para almacenar los datos HDFS del NameNode:

root@hd-master:~# mkdir -p /usr/local/hadoop/hadoop_data/hdfs/namenode 
root@hd-master:~# chown -R hadoop:hadoop /usr/local/hadoop

Duplicamos la configuracion de Hadoop en todos los Slaves Nodes:

root@hd-master:~# scp -r /usr/local/hadoop/etc/hadoop/* hadoop@hd-slave1:/usr/local/hadoop/etc/hadoop
root@hd-master:~# scp -r /usr/local/hadoop/etc/hadoop/* hadoop@hd-slave2:/usr/local/hadoop/etc/hadoop
root@hd-master:~# scp -r /usr/local/hadoop/etc/hadoop/* hadoop@hd-slave3:/usr/local/hadoop/etc/hadoop

root@hd-slave[1-3]:~# chown -R hadoop:hadoop /usr/local/hadoop/etc/hadoop

Creamos el directorio para almacenar los datos HDFS den DataNode:

root@hd-slave[1-3]:~# mkdir -p /usr/local/hadoop/hadoop_data/hdfs/datanode 
root@hd-slave[1-3]:~# chown -R hadoop:hadoop /usr/local/hadoop

Cambiamos configuración del NameNode por DataNode en todos los Slaves Nodes:

<configuration>
  <property>
    <name>dfs.replication</name>
    <value>3</value>
    <description>Default block replication</description>
  </property>
  <property>
    <name>dfs.datanode.name.dir</name>
    <value>file:/usr/local/hadoop/hadoop_data/hdfs/datanode</value> 
  </property>
</configuration>

Damos formato al nuevo filesystem distribuido:

hadoop@hd-master:~#hdfs namenode -format

Iniciamos YARN/HDFS manualmente:

Master Nodes:

#Start Services
hadoop-daemon.sh --script hdfs start namenode
yarn-daemon.sh start resourcemanager

#Stop Services
yarn-daemon.sh stop resourcemanager
hadoop-daemon.sh --script hdfs stop namenode

  Slaves Nodes:

#Start Services
hadoop-daemon.sh --script hdfs start datanode
yarn-daemon.sh start nodemanager

#Stop Services
yarn-daemon.sh stop nodemanager
hadoop-daemon.sh --script hdfs stop datanode

Testing Cluster Hadoop

Creamos un directorio para almacenar los datos del usuario hadoop:

hadoop@hd-master:~#hadoop fs -mkdir /user
hadoop@hd-master:~#hadoop fs -mkdir /user/hadoop

Subimos el directorio de los ficheros de configuración:

hadoop@hd-master:~#hadoop fs -put /usr/local/hadoop/etc/hadoop /user/hadoop/hadoop-config

Comprobamos que se ha subido los datos correctamente:

hadoop@hd-master:~#hdfs dfs -ls /user/hadoop/hadoop-config

Ejecutamos un trabajo de ejemplo:

hadoop@hd-master:~#hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar grep /user/hadoop/hadoop-config /user/hadoop/output 'dfs[a-z.]+'

Comprobamos la información del directorio output:

hadoop@hd-master:~#hdfs dfs -ls /user/hadoop/output/

6.El fichero part-r-00000 contiene el resultado de nuestro trabajo:

hadoop@hd-master:~#hdfs dfs -cat /user/hadoop/output/part-r-00000
6       dfs.audit.logger
4       dfs.class
3       dfs.server.namenode.
2       dfs.period
2       dfs.audit.log.maxfilesize
2       dfs.audit.log.maxbackupindex
1       dfsmetrics.log
1       dfsadmin
1       dfs.servers
1       dfs.replication
1       dfs.namenode.name.dir
1       dfs.file

Acceso Web a los Servicios Hadoop

Hadoop NameNode se levanta por defecto en el puerto 50070 del Master Node, es posible acceder a la información utilizando un navegador web.

http://hd-master:50070

namenode

Para obtener la información sobre el cluster y todas la aplicaciones, podemos acceder Resource Manager a través del puerto 8088 del Nodo Master:

http://hd-master:8088

resourcemanager

Y hasta aquí, con el cluster desplegado y funcionando, la primera experiencia Hadoop a modo de tutorial, posiblemente sigamos profundizando sobre este tema en próximos artículos.