Hadoop y Spark

Hadoop

Apache Hadoop es un framework de software que soporta aplicaciones distribuidas. Permite a las aplicaciones trabajar con miles de nodos y petabytes de dtos.

Arquitectura Hadoop

El Hadoop Distributed File System (HDFS) es un sistema de archivos distribuido, escalable y portátil escrito en Java para el framework Hadoop. Cada nodo en una instancia Hadoop típicamente tiene un único nodo de datos; un clúster de datos forma el clúster HDFS.

Spark

Descripción Spark

Spark es un sistema de computación en clúster de propósito general. Puede implementar y ejecutar aplicaciones paralelas en clústeres que van desde un solo nodo hasta miles de nodos distribuidos. Spark fue diseñado originalmente para ejecutar aplicaciones Scala, pero también es compatible con Java, Python y R

Este cluster de Spark correrá bajo el protocolo Yarn de HADOOP. Los trabajos de Spark pueden ejecutarse en YARN en dos modos: modo de clúster y modo de cliente. Comprender la diferencia entre los dos modos es importante para elegir una configuración de asignación de memoria adecuada y para enviar trabajos como se espera.

Los trabajos de Spark constan de dos partes:

  • Ejecutores Spark. Ejecutan las tareas reales.
  • Controlador Spark. Organiza los ejecutores.

Modo Clúster Todo se ejecuta dentro del clúster. Puede iniciar un trabajo desde cualquier equipo y el trabajo continuará ejecutándose incluso si se cierra el equipo desde donde se lanzo el trabajo. En este modo el controlador Spark se encapsula dentro del YARN Application Master.

Modo Cliente El controlador se ejecuta en el equipo cliente, si el equipo cliente se apaga el trabajo falla. El modo cliente es adecuado para trabajos interactivos pero para trabajos de larga ejecución, el modo el clúster es más apropiado.

Funcionamiento Las aplicaciones Spark se ejecutan como conjuntos independientes de procesos en un clúster, coordinados por el objeto SparkContext (Progama controlador).

Siendo más específico, SparkContext para ejecutarse en el clúster puede conectarse a varios tipos de administradores de clúster (el propio Spark , Mesos o Yarn, siendo este último el de nuestra instalación), que asigna recursos entre las aplicaciones. Una vez conectado, Spark adquiere ejecutores en nodos de clúster, que son procesos que ejecutan cálculos y almacenan datos para su aplicación. A continuación, envía su código de aplicación (definido por los archivos JAR o Python pasados a SparkContext) a los ejecutores. Finalmente, SparkContext envía tareas a los ejecutores para ejecutar.

Funcionamiento-spark.png

Instalación Hadoop

Para la instalación de Hadoop hemos seguido el siguiente tutorial: https://www.linode.com/docs/databases/hadoop/how-to-install-and-set-up-hadoop-cluster/

Equipos para la instalación TEST Spark -> 45.79.207.240 (Maestro y Esclavo) cool-ad14 -> 172.104.214.142 (Esclavo)

Paso 1 Creación de /etc/hosts. Debemos añadir a cada /etc/hosts todos las máquinas que participan en el clúster

45.79.207.240 spark
172.104.214.142 node-ad14

Paso 2 Creación del usuario hadoop y clave pública. Debemos crear un usuario con el nombre hadoop en cada máquina.

   User: hadoop
   Pass: passwd

Solo nos faltará crear una clave pública en el maestro y compartilo con el propio maestro y los esclavos.

   Máquina Spark / Usuario hadoop
   ssk-keygen -b 4096
   ssh-copy-id -i $HOME/.ssh/id_rsa.pub hadoop@spark
   ssh-copy-id -i $HOME/.ssh/id_rsa.pub hadoop@node-ad14

Paso 3 En el Master. Dentro de la carpeta /home/hadoop con el usuario hadoop nos descargamos el fichero.tar.gz que contiene hadoop.

https://hadoop.apache.org/
https://archive.apache.org/dist/hadoop/common/hadoop-3.1.2/hadoop-3.1.2.tar.gz
   Descomprimimos   / tar -xvzf hadoop-3.1.2.tar.gz
   Cambio de nombre / mv hadoop-3.2.1 hadoop


Paso 4 Variables de entorno. En el fichero /home/hadoop/.profile añadimos la siguiente línea. Si el fichero no existe hemos de crearlo:

PATH=/home/hadoop/hadoop/bin:/home/hadoop/hadoop/sbin:$PATH

Paso 5 Configuración de JAVA. Si no tenemos java instalado debemos instalarlo

yum install jdk-1.8.0-devel

Una vez instalado debemos conocer la ubicación de la carpeta jre, para saberlo utilizamos el siguiente comando:

   update-alternatives --display java

Una vez obtenemos la ruta de java, hacemos un export de la variable JAVA_HOME en hadoop-env.sh

/home/hadoop/hadoop/etc/hadoop/hadoop-env.sh

export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre


Paso 6 Archivos de configuración. Establecemos el master. /home/hadoop/hadoop/etc/hadoop/core-site.xml

<configuration>
       <property>
           <name>fs.default.name</name>
           <value>hdfs://node-master:9000</value>
       </property>
</configuration>


Establecemos los path para hdfs. /home/hadoop/hadoop/etc/hadoop/hdfs-site.xml

<configuration>
   <property>
           <name>dfs.namenode.name.dir</name>
           <value>/home/hadoop/data/nameNode</value>
   </property>
   <property>
           <name>dfs.datanode.data.dir</name>
           <value>/home/hadoop/data/dataNode</value>
   </property>
   <property>
           <name>dfs.replication</name>
           <value>1</value>
   </property>
</configuration>

La última propiedad dfs.replication, indica cuántas veces se replican los datos en el clúster. Por ejemplo podríamos configurar con 2 para que todos los datos se duplicasen en ambos nodos, NO INGRESAR UN VALOR MÁS ALTO QUE EL NÚMERO DE NODOS ESCLAVOS.


Establecemos Yarn como el framework por defecto para las operaciones de Mapreduce. /home/hadoop/hadoop/etc/hadoop/mapred-site.xml

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


Configuración Yarn ~/hadoop/etc/hadoop/yarn-site.xml

<configuration>
   <property>
           <name>yarn.acl.enable</name>
           <value>0</value>
   </property>
   <property>
           <name>yarn.resourcemanager.hostname</name>
           <value>node-master</value>
   </property>
   <property>
           <name>yarn.nodemanager.aux-services</name>
           <value>mapreduce_shuffle</value>
   </property>
</configuration>


Configuración de esclavos. En la documentación que hemos leído se utiliza un fichero llamado slaves, pero actualmente se está utilizando un fichero que se llama workers.

Dentro del fichero /home/hadoop/hadoop/etc/hadoop/workers
localhost
node-ad14


Configuración de la asignación memoria. La asignación de memoria puede ser complicada en nodos de RAM baja porque los valores predeterminados no son adecuados para nodos con menos de 8GB de RAM. Vamos a destacar como funciona la asignación de memoria para los trabajos de MapReduce y veremos una configuración para nodos de 2GB de RAM.


Propiedades de la asignación de memoria. Un operación con Yarn tiene dos tipos de procesos:

  • Application Master(AM) Responsable de monitorizar la aplicación y coordinar los ejecutores distribuidos por el clúster.
  • Ejecutores propios para realizar los actuales trabajos.

Ambos tipos de procesos se ejecutan en los nodos esclavos. Cada nodo esclavo ejecuta un demonio NodeManager que es responsable de la creación del contenedor en el nodo. Todo el clúster es administrado por un ResourceManager que programa la asignación de contenedores en todos los nodos esclavos, según los requisitos de capacidad y el cargo actual.

Tenemos cuatro tipos de asignación deben configurarse para el clúster funcione correctamente.

Cuánta memoria se puede asignar para los contenedores YARN en un solo nodo. Este límite debe ser más alto que todos los demás, de lo contrario la asignación de contenedores será rechazada y las aplicaciones fallan. Sin embargo no debe ser la cantidad total de RAM en el Nodo.

yarn.nodemanager.resource.memory-mb

Cuánta memoria puede consumir un contenedor y la asignación de memoria mínima permitida. Un contenedor nunca será más grande que el máximo, o la asignación fallará y siempre se asignará como un múltiplo de la cantidad mínima de RAM.

yarn.scheduler.maximum-allocation-mb
yarn.scheduler.minimum-allocation-mb


Cuánta memoria se le asignará al AplicationMaster. Este es un valor constante que debe ser inferior al de tamaño máximo del contenedor.

yarn.app.mapreduce.am.resource.mb


Cuańta memoria se le asignará a cada mapa.

mapreduce.map.memory.mb
mapreduce.reduce.memory.mb

   

Ejemplo de configuración de 2GB de RAM por NODO.

yarn.nodemanager.resource.memory-mb    1536
yarn.scheduler.maximum-allocation-mb    1536
yarn.scheduler.minimum-allocation-mb    128
yarn.app.mapreduce.am.resource.mb    512
mapreduce.map.memory.mb            256
mapreduce.reduce.memory.mb        256

~/hadoop/etc/hadoop/yarn-site.xml

<property>
       <name>yarn.nodemanager.resource.memory-mb</name>
       <value>1536</value>
</property>
<property>
       <name>yarn.scheduler.maximum-allocation-mb</name>
       <value>1536</value>
</property>
<property>
       <name>yarn.scheduler.minimum-allocation-mb</name>
       <value>128</value>
</property>
<property>
       <name>yarn.nodemanager.vmem-check-enabled</name>
       <value>false</value>
</property>

~/hadoop/etc/hadoop/mapred-site.xml

<property>
       <name>yarn.app.mapreduce.am.resource.mb</name>
       <value>512</value>
</property>
<property>
       <name>mapreduce.map.memory.mb</name>
       <value>256</value>
</property>
<property>
       <name>mapreduce.reduce.memory.mb</name>
       <value>256</value>
</property>

Paso 7

Replicación de los binarios de hadoop y los archivos de configuración. Pasamos los binarios y las configuración que hicimos anteriormente en el maestro hacia los esclavos asignados.

Paso 8 Formatear HDFS. HDFS necesita ser formateado como cualquier clásico sistema de ficheros. En no nodo maestro ejecutar el siguiente comando:

   /home/hadoop/hadoop/bin/hdfs namenode -format

Una vez termina hadoop está listo para iniciarse.

Paso 9 y último Antes de levantar Hadoop vamos a securizar los puertos de escucha controlando las conexiones desde el iptables tanto del nodo-maestro como de los nodos-esclavos.

Lista de puertos a controlar en el< nodo maestro

9000 - 9684 -9866 - 9867 - 9868 - 9870
8040 - 8042 - 8088 - 8030 - 8031 - 8033 
40773 - 36550 - 27017

Preparamos el firewall y levantamos.

Arranque de Hadoop

Esta sección explicará cómo iniciar HDFS en NameNode y DataNodes, y controlará que todo funcione correctamente e interactúe con los datos HDFS.

Inicio y parada de HDFS En el nodo maestro lanzamos con el usuario hadoop:

/home/hadoop/hadoop/sbin/start-dfs.sh

Una vez finalizado la ejecución comprobamos los procesos java con el comando jps, tanto en el nodo maestro como en los esclavos, nos tiene que aparecer algo así:

NODO MAESTRO

21922 Jps
21603 NameNode
21787 SecondaryNameNode

NODO ESCLAVO

19728 DataNode
19819 Jps

Si queremos ver un reporte de los nodos conectados y del clúster utilizamos el comando

/home/hadoop/hadoop/bin/hdfs dfsadmin -report

Para parar el funcionamiento de hadoop:

/home/hadoop/hadoop/sbin/stop-dfs.sh

Inicio y parada de Yarn En el nodo maestro lanzamos con el usuario hadoop:

/home/hadoop/hadoop/sbin/start-yarn.sh


Para comprobar que los nodos están trabajando con yarn

/home/hadoop/hadoop/bin/yarn node -list

Plataforma web de yarn http://spark:8080

Instalación de Spark

Para la instalació de Apache Spark, simplemente necesitamos realizar la descarga de los ficheros de binarios y descomprimirlos, y clonar el repositorio para el conector con Cassandra.

Nos descargamos el tar de ficheros binarios de Apache Spark del siguiente enlace: http://apache.rediris.es/spark/spark-<version>/spark-<version>-bin-hadoop2.7.tgz P.e:

  1. cd /install
  2. wget http://apache.rediris.es/spark/spark-2.3.0/spark-2.3.0-bin-hadoop2.7.tgz

Ya solo debemos descomprimir el archivo en /usr/local (o en otra ruta si fuera mas pertinente):

  1. cd /usr/local
  2. tar -zxf /install/spark-2.3.0-bin-hadoop2.7.tgz

Hacemos un clone del repositorio de git del conector de Cassandra:

  1. git clone https://github.com/datastax/spark-cassandra-connector

Integración de Spark con Hadoop

Para la comunicación con el administrador de recursos YARN, Spark debe conocer la configuración de Hadoop. Esto se hace a través de la variable de entorno HADOOP_CONF_DIR

Editamos /home/hadoop/.profile

export HADOOP_CONF_DIR=/home/hadoop/hadoop/etc/hadoop
export SPARK_HOME=/usr/local/spark
export LD_LIBRARY_PATH=/home/hadoop/hadoop/lib/native:$LD_LIBRARY_PATH

Reiniciamos la sesión.

Renombramos el archivo spark-defaults.conf.template ha spark-defaults.conf Este archivo se encuentra en la ubicación de Spark, normalmente en:

/usr/local/spark

ASIGNACIÓN DE MEMORIA EN SPARK Como le hemos pasado la ruta de la configuración de Hadoop, Spark cogerá la configuración de memoria para contenedores y a se la aplicará, aún así hemos de configurar algunas asignaciones de memoria en spark y otras cosas, hago un breve resumen más abajo con las variables necesarias.

Editamos spark-defaults.conf, le añadimos la siguiente líneas al final del archivo:

  1. Para qué spark sepa que ha de funcionar con Yarn.
spark.master yarn
  1. Cantidad predeterminada de memoria asignada a Spark.driver en el clúster.
spark.driver.memory     512m
spark.yarn.am.memory    512m
spark.executor.memory   896m
  1. Monitorización
spark.eventLog.enabled false
spark.eventLog.dir hdfs://spark:9000/spark-logs
spark.history.provider            org.apache.spark.deploy.history.FsHistoryProvider
spark.history.fs.logDirectory     hdfs://spark:9000/spark-logs
spark.history.fs.update.interval  10s
spark.history.ui.port             18080