Tabla de Contenidos
Qué es Hadoop
Apache Hadoop es un framework de código abierto utilizado para el almacenado y procesamiento de grandes volúmenes de datos en forma distribuida. Para esto utiliza lo que se conoce como commodity hardware, es decir, un conjunto de computadoras genéricas. Por sus características, Hadoop es ampliamente utilizado en Big Data, ya que permite trabajar con grandes volumenes de información a muy bajo costo.
En este post comentaremos los componentes principales del framework, e instalaremos Hadoop en una computadora virtual en modo pseudo-distribuido. Estos nos permitirá, en próximos post, comenzar a utilizarlo y aprender sin necesidad de estar en un entorno real de producción. En caso que deseen profundizar en Hadoop, les invito a que visiten la sección Getting Started del proyecto.
Arquitectura
La arquitectura de Hadoop sigue el paradigma de arquitectura master/slave. En el siguiente diagrama se representa esta:
El master viene siendo el NameNode. Este nodo es el más importante de la arquitectura, y controla el acceso por parte de los clientes a la información, a la vez que gestiona el almacenamiento y procesamiento de los datos en los DataNodes. Esto últimos serían los slaves, también llamados workers.
Los componentes principales de la arquitectura de Hadoop son:
- HDSF: es el sistema de archivos de Hadoop. Está diseñado para utilizar múltiples computadoras genéricas (commodity machines) agrupadas en clústers. Este es tolerante a fallas y provee una alta tasa de acceso a los datos.
- NameNode: es el Corazón del Sistema Hadoop, y se encarga de gestionar el clúster. Almacena los metadatos de los bloques de datos, los cuales son almacenados permanentemente en el disco local en lo que es el namespace. A su vez, también conoce la ubicación de los bloques de datos en los DataNodes.
- Secondary NameNode (opcional): tiene la responsabilidad de periódicamente copiar el namespace. En caso de que el NameNode falle, entonces el namespace almacenado en este nodo puede ser usado para reiniciar el sistema.
- DataNode: almacenan los bloques de datos y entregan la información cuando se les solicita. Estos nodos también reportan periódicamente los metadatos asociados a los bloques de información al NameNode. En esto se ejecutan las tareas MapReduce.
- JobTracker: es responsable de coordinar los trabajos (jobs) solicitados por los clientes. Crea las tareas MapReduce y las asigna a los diferentes TaskTrackers en los DataNodes. También comprueba si las tareas fallaron, y en tal caso las reprograma en otro DataNode. Puede ser ejecutado en el NameNode, o en un nodo separado.
- TaskTracker: Es responsable de correr los MapReduce asignados por el JobTracker y reportar el estado de la tarea a este. Se ejecuta en los DataNodes.
HDFS
El sistema de archivos de Hadoop (HDFS, Hadoop Distributed File System) almacena los datos en bloques de gran tamaño. Por defecto, el tamaño de estos bloques es 64MB, con un máximo configurable de 128MB. Entonces, cuando vamos a almacenar un archivo, este el dividido en bloques de 64MB, y luego almacenado en múltiples nodos (por defecto, se almacena 1 copia de cada bloque en 3 DataNodes diferentes, cada una en un nodo diferente).
La razón principal de que se use un tamaño grande para los bloques, siendo que lo usual en otros sistemas de archivos es que esté en el orden de los KB, es para reducir el tiempo de búsqueda en estos. En general, el tiempo de búsqueda ronda los 10ms, y luego la transferencia de datos es de 100MB/s. De esta forma, el tiempo de búsqueda para bloques de 100MB es el 1% del tiempo de transferencia.
Los demás beneficios de este diseño son:
- Como los bloques son de tamaño fijo, es fácil calcular el número de bloques que pueden ser almacenados en cada DataNodes.
- Simplifica el almacenamiento de los datos en los DataNodes, ya que estos no necesitan conocer acerca de los mata-datos de los bloques. El NameNode es el que se ocupa de mantener esta información.
- Los bloques son fáciles de replicar entre los DataNodes, y de esta forma proveen alta tolerancia a fallas y alta disponibilidad. Por defecto se hacen 3 copias de cada bloque de datos que son puestas en diferentes nodos. Si uno de estos falla, entonces los datos pueden ser recuperados de los otros bloques.
MapReduce
Hadoop se base en el paradigma MapReduce para paralelizar los procesos en dos fases. La primer fase es la de mapeo (map). En esta se realiza un escaneo de los datos de entrada y se genera una lista de pares clave-valor. Estos pares son agrupados por clave y pasados a la función reduce que se encarga de procesarlos y generar un resultado agrupado de los mismos.
En futuros post veremos más detalladamente, y con ejemplos concretos, como se realiza esto.
Instalación de Hadoop
Modos de funcionamiento
Hadoop tiene tres modos de funcionamiento:
- Modo local: se ejecuta en un único nodo como un solo proceso java.
- Modo local pseudo-distribuido: se ejecuta en un único nodo, pero cada demonio se ejecuta en un proceso java diferente.
- Modo distribuido: se ejecuta utilizando múltiples nodos completamente distribuido.
Cuando se va a montar Hadoop en producción se lo utiliza en modo distribuido, mientras que el modo pseudo-distribuido se lo suele utilizar para desarrollo, y en nuestro caso, aprendizaje.
Entorno
Hadoop funciona en entornos Linux. Lo aconsejable es que para comenzar adentrarse en Hadoop se utilice una máquina virtual. De este modo, en caso que rompamos algo bastaría con hacer un rollback a un estado previo del sistema, o simplemente reinstalar la máquina virtual sin poner el riego nuestra máquina. Yo en este caso tengo instalado en una máquina virtual en VMware un Ubuntu 16.04 (la versión LTS más actual de Ubuntu al momento de escribir este post).
A su vez, vamos a necesitar que en esta máquina tengamos instalado java. Para comprobar si es así podemos ejecutar:
$ java -version
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-3ubuntu1~16.04.1-b14)
OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)
En caso de no tenes instalado java, bastaría con ingresar:
$ sudo apt-get install sun-java*
y luego generar la variable de entorno correspondiente:
$ export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
Estos comando pueden variar levemente de PC en PC, pero googleando un poco no deberían tener problemas para la instalación en caso de tener inconvenientes.
Instalación
Ahora comenzamos con la instalación de Hadoop. Desde este momento voy a asumir que contamos con conocimientos básicos de Linux, por lo que no me detendré a explicar los comandos que utilicemos ni demás temas vinculados al sistema operativo. En caso de que tengan dudas en algún punto, sobre Linux hay mucho escrito en la web, de modo que estoy seguro podrán encontrar sin problemas las respuestas a todas ellas.
Luego, debemos descargar Hadoop desde la sección de descarga de su web oficial. Al día de escribir este post, la versión estable más reciente es la 2.7.3, por lo que procedo a descargar los binarios. Una vez los tenemos descargados, debemos descomprimir el archivo hadoop-2.7.3.tar.gz, y mover la carpeta resultante a ‘/usr/local/’:
$ mv hadoop-2.7.3 /usr/local/hadoop
A continuación creamos un usuario para administrar y configurar Hadoop:
$ useradd -d /home/hadoop -m hadoop $ passwd hadoop $ usermod -a -G sudo hadoop $ usermod -s /bin/bash hadoop
Luego, nos logueamos con el usuario creado, y agregamos las variables de entorno para este en el ‘~/.bashrc’:
$ export HADOOP_HOME=/usr/local/hadoop $ export PATH=$PATH:$HADOOP_HOME/bin $ export PATH=$PATH:$HADOOP_HOME/sbin $ export HADOOP_MAPRED_HOME=${HADOOP_HOME} $ export HADOOP_COMMON_HOME=${HADOOP_HOME} $ export HADOOP_HDFS_HOME=${HADOOP_HOME} $ export YARN_HOME=${HADOOP_HOME}
Hecho esto, ejecutamos ‘source .bashrd’ para cargar la nueva configuración, y comprobamos que todo vaya bien con:
$ hadoop version
Hadoop 2.7.3
Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r baa91f7c6bc9cb92be5982de4719c1c8af91ccff
Compiled by root on 2016-08-18T01:41Z
Compiled with protoc 2.5.0
From source with checksum 2e4ce5f957ea4db193bce3734ff29ff4
This command was run using /usr/local/hadoop/share/hadoop/common/hadoop-common-2.7.3.jar
Configuración de SSH
Los nodos en Hadoop se comunican mediante SSH, por lo que debemos configurar este protocolo:
$ sudo apt-get install ssh $ ssh-keygen -t rsa -f ~/.ssh/id_rsa $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
y otorgarle permisos:
$ sudo chmod go-w $HOME $HOME/.ssh $ sudo chmod 600 $HOME/.ssh/authorized_keys $ sudo chown `whoami` $HOME/.ssh/authorized_keys
Una vez hecho esto, comprobamos la conexión:
$ ssh localhost
Lo siguiente a realizar es desactivar de protocolo IPv6 según indica la documentación oficial. Para esto debemos modificar las siguientes lineas del archivo ‘/etc/sysctl.conf’:
$ net.ipv6.conf.all.disable_ipv6 = 1 $ net.ipv6.conf.default.disable_ipv6 = 1 $ net.ipv6.conf.lo.disable_ipv6 = 1
Configuración del HDFS
Hasta el momento tenemos montado Hadoop para ejecutarse en modo local. Si queremos que se ejecute en modo speudo-aleatorio debemos tocar algunos archivos para configurar el HDFS.
core-site.xml
Nos vamos a ‘/usr/local/hadoop/etc/hadoop’ y encontramos el archivo core-site.xml. En este se pueden indicar numerosas opciones de configuración, de las cuales la que nos interesa en este momento es configurar el directorio HDFS por defecto en el localhost:
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>fs.default.name</name> <value>hdfs://localhost:8020</value> </property> </configuration>
hdfs-site.xml
El hdfs-site.xml contiene información sobre como Hadoop almacenará la informacion en el clúster.
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>dfs.namenode.name.dir</name> <value>file:/home/hadoop/workspace/dfs/name</value> <description>Ruta del sistema de archivos donde el NameNode almacenará los metadatos.</description> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:/home/hadoop/workspace/dfs/data</value> <description>Ruta del sistema de archivos donde el DataNode almacenerá los bloques.</description> </property> <property> <name>dfs.replication</name> <value>1</value> <description>Factor de replicación. Como tenemos una única computadora en el clúster lo ponemos a 1.</description> </property> </configuration>
Y crear los directorios ‘/home/hadoop/workspace/dfs/name’ y ‘/home/hadoop/workspace/dfs/data’.
mapred-site.xml
Se utiliza para especificar quien realiza el MapReduce y el lugar donde se lleva a cabo. En cuanto a lo primero, lo configuramos para que sea hecho por el YARN (Yet Another Resource Negotiator), el cual es el componente del framework encargado de esta tarea. Como tenemos un único nodo en nuestro clúster, solo habrá una job map y otro reduce.
Antes de tocar el archivo, debemos renombrarlo. El nombre por defecto es mapred-site.xml.template y queremos que pase a ser mapred-site.xml. Hecho esto, pasamos a modificarlo.
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapred.system.dir</name> <value>file:/home/hadoop/workspace/mapred/system</value> <final>true</final> </property> <property> <name>mapred.local.dir</name> <value>file:/home/hadoop/workspace/mapred/local</value> <final>true</final> </property> </configuration>
Y crear los directorios ‘/home/hadoop/workspace/mapred/system‘ y ‘/home/hadoop/workspace/mapred/local’.
yarn-site.xml
Este archivo se utiliza para configurar YARN en Hadoop. Lo que vamos a hacer es habilitar la fase de Suffle para que se pueda hacer entre las fases Map y Reduce.
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> </configuration>
Últimos pasos
Ahora que tenemos lista la configuración debemos formatear el HDSF con:
hadoop namenode -format
y arrancar el clúster. Para esto último nos vamos a ‘/usr/local/hadoop/sbin/’ y ejecutamos:
./start-dfs.sh ./start-yarn.sh
con esto ya podemos ver, mediante el comando jps, como se han iniciado todos los procesos:
$ jps
11363 Jps
7572 SecondaryNameNode
8038 NodeManager
7239 NameNode
7384 DataNode
7737 ResourceManager
Una vez arrancado el clúster, desde un navegador web podemos verificar que se haya hecho exitosamente ingresando a ‘http://localhost:50070/’, en donde podemos ver información del NameNode y del HDFS:
o si quisiésemos hacer seguimiento de los jobs que se vayan ejecutando podemos ir a ‘http://localhost:8088/cluster/nodes’:
Cierre
Hasta acá hemos visto de que se trata Hadoop, y hemos realizado una instalación que nos servirá para en futuros post seguir explorando el framework. Si les ha gustado, no olviden suscribirse al newsletter para estar al tanto cuando vaya subiendo nuevo contenidos. Y si tienen alguna duda, comentario o feedback, no duden en dejarlo abajo en los comentario.
Comentarios
Quisiera aprender mas sobre Hadoop…gracias
Excelente articulo!!! me encantó, me sirvió de mucho.
Me pareció excelente !
Excelente articulo!
Gracias Diego, me alegro que lo hayas encontrado interesante!!
Te comento que próximamente estaré publicando más artículos vinculados a Hadoop y su ecosistema. Si te interesa el tema, puedes mantenerte en contacto mediante facebook, twitter, o suscribirte al newsletter.
Saludos!! Mauricio