Saltar navegación

Instalación manual de un cluster

Objetivos

Instalaremos un cluster Hadoop usando 3 máquinas virtuales del cloud del CESGA:

  • Un minicluster de 3 máquinas: 1 NameNode/ResourceManager, 1 DataNode/NodeManager/Checkpoint node, y 1 DataNode/NodeManager/JobHistoryServer (más adelante se añadirán 1 DataNode/NodeManager adicional).

Máquina virtual base

Preparación para conexión a la maquina virtual en la nube del CESGA

Para podernos conectar a la máquina virtual del CESGA necesitamos una clave pública:

  • En Linux puedes crearla con ssh-keygen
    • Se crean dos ficheros, id_rsa que contiene la clave privada e id_rsa.pub con la pública.
    • Necesitaremos la pública para conectarnos a la MV
  • En Windows puedes usar puedes usar PuTTYgen

Adicionalmente, tenemos que activar la VPN del CESGA

Preparar una máquina virtual que nos sirva para los nodos del cluster Hadoop

1. Conectarse a http://nebula.cesga.es/ y validarse

  • En el lado derecho, abrid el menú desplegable con el vuestro nombre de usuario y ir a las Settings
  • En "Cambiar vista", elegid "user" y "Actualizar vista"

2. En la nueva vista, ir,  en el menú izquierdo, a "Tienda de Aplicaciones"

  • Seleccionad "Ubuntu 16.04 LTS" y dadle a "Importar"
  • Dejad el datastore a su valor por defecto y poned el nombre de la imagen a NameNodeImagen, y el nombre de la plantilla a NameNodePlantilla, o algo similar

3. Una vez importada, id a "Recursos Virtuales" -> "Imágenes"

  • La imagen que acabáis de importar aparecerá en estado "BLOQUEADA"
    • Esperad a que pase a "LISTO"
    • Refrescad de vez en cuando para ver si cambia
  • Una vez lista, seleccionad la máquina y en el desplegable del lado derecho seleccionar "Hacer persistente"
  • Pinchad en el nombre de la imagen y comprobad que aparece como persistente

4. Id ahora a "Recursos Virtuales" -> "Plantillas", seleccionad la plantilla que se ha creado y dadle a "Actualizar"

  • En el menú "General", cambiad la memoria a 2048 MB
  • En "Almacenamiento" añadir otro disco, de tipo Disco Volátil, tamaño 4096 y tipo Swap
  • En "Contexto", copiad el contenido del fichero de clave pública id_rsa.pub al cuadro de texto correspondiente
  • Acordaros de darle al botón "Actualizar"

5. Creamos la máquina virtual que nos servirá para el NameNode/ResourceManager de Hadoop, a partir de esta plantilla, en el menú "Recursos Virtuales" -> "Máquinas Virtuales"

  • Añadid una nueva MV (botón verde con el signo +)
  • Seleccionad la plantilla que tenemos y ponedle como nombre a la MV NameNode
  • Dejad el resto de opciones a su valor por defecto y dadle a crear
  • La MV estará lista cuando deje el estado PENDING y pase a EJECUTANDO

6. Para conectarse a la MV, una vez activada la VPN del CESGA, conectaros como root usando la clave privada y la IP de la máquina

  • ssh -i path_al_fichero_id_rsa root@ip_máquina_virtual

 

Descarga e instalación de Hadoop

1. Una vez dentro de la MV instala Java (OpenJDK v8) y otras librerías que usa Hadoop..

        # apt-get update
        # apt-get install openjdk-8-jre libssl-dev

2. Crea el directorio /opt/bd y descarga en el mismo la última versión estable de  Hadoop (en el momento de escribir este documento era la 2.7.4), crea un enlace simbólico y define la variable HADOOP_PREFIX.

        # mkdir /opt/bd
        # cd /opt/bd
        # wget http://apache.uvigo.es/hadoop/common/stable/hadoop-2.7.4.tar.gz
        # tar xvzf hadoop-2.7.4.tar.gz
        # rm hadoop-2.7.4.tar.gz
        # ln -s hadoop-2.7.4 hadoop
        # export HADOOP_PREFIX=/opt/bd/hadoop

4. Crea un grupo hadoop y un usuario hdmaster para ejecutar los diferentes demonios (HDFS y YARN). Cambia el propietario del directorio /opt/bd

        # groupadd -r hadoop
        # useradd -r -g hadoop -d /opt/bd -s /bin/bash hdmaster
        # chown -R hdmaster:hadoop /opt/bd 

5. Crea directorios para los datos de HDFS (NameNode, DataNodes y Checkpoint node) y haz que sean propiedad del usuario hdmaster. En un sistema real, estos directorios deberían estar en particiones separadas con suficiente espacio libre.

        # mkdir -p /var/data/hadoop/hdfs/nn
        # mkdir -p /var/data/hadoop/hdfs/cpn
        # mkdir -p /var/data/hadoop/hdfs/dn
        # chown -R hdmaster:hadoop /var/data/hadoop/hdfs

 6. Crea directorios para los ficheros de log y haz que sean propiedad del usuario hdmaster.

        # mkdir -p /var/log/hadoop/yarn
        # mkdir -p /var/log/hadoop/hdfs
        # mkdir -p /var/log/hadoop/mapred
        # chown -R hdmaster:hadoop /var/log/hadoop

7. Modifica el fichero /etc/ssh/ssh_config y pon el parámetro StrictHostKeyChecking a no

Pasos como usuario hdmaster

1. Como usuario hdmaster (su - hdmaster) copiar los ficheros de /etc/skel (cp /etc/skel/.* ~) y añadir a ~/.bashrc las lineas: 

        export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
        export HADOOP_PREFIX=/opt/bd/hadoop 

        export PATH=$PATH:$HADOOP_PREFIX/bin

y ejecutar . ~/.bashrc

2. Chequear que hadoop funciona con:

        $ hadoop version

3. El usuario hdmaster debe poder conectarse entre los nodoes del cluster por ssh sin password. Ejecutar lo siguiente como usuario hdmaster:

        $ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
        $ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
        $ chmod 644 ~/.ssh/authorized_keys

 Prueba que puedes hacer ssh localhost y no te pide contraseña

Configuración de los demonios de Hadoop.

Configuración de los demonios

Estos demonios se configuran principalmente mediante cuatro ficheros, localizados en /opt/yarn/hadoop/etc/hadoop/, en los que se pueden indicar un gran número de propiedades (ver http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/ClusterSetup.html para más información):


Como usuario hdmaster, cambia los siguientes ficheros en $HADOOP_PREFIX/etc/hadoop/:

  • core-site.xml: configuración general de Hadoop
<configuration>
  <property>
    <!-- nombre del Namenode -->
    <name>fs.defaultFS</name>
    <value>hdfs://namenode:9000/</value>
    <final>true</final>
  </property>
  <property>
    <!-- Almacenamiento temporal (debe tener suficiente espacio) -->
    <name>hadoop.tmp.dir</name>
    <value>/var/tmp</value>
    <final>true</final>
  </property>
  <property>    
    <!-- Usuario por defecto para el interfaz web -->
    <name>hadoop.http.staticuser.user</name>
    <value>hdfs</value>
    <final>true</final>
  </property>
</configuration>
  • hdfs-site.xml: configuración de HDFS
<configuration>
 <property>
   <!-- Factor de replicacion de los bloques -->
    <name>dfs.replication</name>
    <value>2</value>
    <final>true</final>
  </property>
  <property>
   <!-- Tamano del bloque (por defecto 128m) -->
    <name>dfs.blocksize</name>
    <value>64m</value>
    <final>true</final>
  </property>
  <property>
    <!-- Lista (separada por comas) de directorios donde el namenode guarda los metadatos.
         En un sistema real debería incluir por lo menos dos directorios:
         uno en el disco local del namenode y otro remoto montado por NFS -->
    <name>dfs.namenode.name.dir</name>
    <value>file:///var/data/hadoop/hdfs/nn</value>
    <final>true</final>
  </property>
  <property>
  <property>
    <!-- Lista (separada por comas) de directorios donde el checkpoint node guarda los checkpoints.
         Igual que el el dfs.namenode.name.dir, deberían indicarse un directorio local y uno remoto -->
    <name>fs.checkpoint.dir</name>
    <value>file:///var/data/hadoop/hdfs/cpn</value>
    <final>true</final>
  </property>
  <property>
    <!-- Lista (separada por comas) de directorios donde el checkpoint node guarda los edits temporales -->
    <name>fs.checkpoint.edits.dir</name>
    <value>file:///var/data/hadoop/hdfs/cpn</value>
    <final>true</final>
  </property>
    <!-- Lista (separada por comas) de directorios donde los datanodes guardan los datos: 
         por rendimiento, si los nodos tiene varios discos es conveniente 
         especificar un directorio en cada uno de los discos locales -->
    <name>dfs.datanode.data.dir</name>
    <value>file:///var/data/hadoop/hdfs/dn</value>
    <final>true</final>
  </property>
  <property>
    <!-- Dirección y puerto del interfaz web del namenode -->
    <name>dfs.namenode.http-address</name>
    <value>namenode:50070</value>
    <final>true</final>
  </property>
  <property>
    <!-- Dirección y puerto del interfaz web del checkpoint node (aka secondary namenode) -->
    <name>dfs.namenode.secondary.http-address</name>
    <value>checkpointnode:50090</value>
    <final>true</final>
  </property>
 </configuration>
  • yarn-site.xml: configuración de YARN
<configuration>
  <property>
    <!-- El ResourceManager -->
    <name>yarn.resourcemanager.hostname</name>
    <value>resourcemanager</value>
    <final>true</final>
  </property>
  <property>
    <!-- Indica a los NodeManagers que tienen que implementar el servicio de barajado mapreduce -->
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
    <final>true</final>
  </property>
  <property>
    <!-- Clase que implementa el servicio de barajado mapreduce -->
    <name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
    <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    <final>true</final>
  </property>
  <property>
    <!-- Numero de cores del NodeManager (por defecto: 8) -->
    <name>yarn.nodemanager.resource.cpu-vcores</name>
    <value>1</value>
    <final>true</final>
  </property>
  <property>
    <!-- Memoria física (MB) que puede ser reservada por los contenedores (por defecto: 8192) -->
    <!-- debe ser menor que la RAM física, para que funcionen otros servicios -->
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>1536</value>
    <final>true</final>
  </property>
  <property>
    <!-- Ratio memoria virtual/memoria fisica (por defecto: 2.1) -->
    <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>2</value>
    <final>true</final>
  </property>
  <property>
    <!-- Numero maximo de cores por container (por defecto: 32) -->
    <name>yarn.scheduler.maximum-allocation-vcores</name>
    <value>1</value>
    <final>true</final>
  </property>
  <property>
    <!-- Mínima reserva permitida por contenedor al Resource Managet (MBs) -->
    <!-- Solicitudes menores lanzan una InvalidResourceRequestException.(por defecto: 1024) -->
    <name>yarn.scheduler.minimum-allocation-mb</name>
    <value>512</value>
    <final>true</final>
  </property>
  <property>
    <!-- Máxima reserva permitida por contenedor al Resource Managet (MBs) -->
    <!-- Solicitudes mayores lanzan una InvalidResourceRequestException.(por defecto: 8192) -->
    <name>yarn.scheduler.maximum-allocation-mb</name>
    <value>1536</value>
    <final>true</final>
  </property>
  <property>
    <!-- Permite agregacion de logs en el historyserver -->
   
<name>yarn.log-aggregation-enable</name>
    <value>true</value>
  </property>
</configuration>
  • mapred-site.xml: configuración de MapReduce (copiad primero el fichero mapred-site.xml.template a mapred-site.xml)
<configuration>
  <property>
    <!-- Framework que realiza el MapReduce -->
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    <final>true</final>
  </property>
  <property>
    <!-- Memoria maxima (MB) por map (por defecto: 1536) -->
    <name>mapreduce.map.memory.mb</name>
    <value>768</value>
    <final>true</final>
  </property>
  <property>
    <!-- Memoria maxima (MB) por reduce (por defecto: 3072)-->
    <name>mapreduce.reduce.memory.mb</name>
    <value>768</value>
    <final>true</final>
  </property>
  <property>
    <!-- Heap maximo para las JVM de los maps (por defecto: -Xmx1024M)-->
    <name>mapreduce.map.java.opts</name>
    <value>-Xmx512M</value>
    <final>true</final>
  </property>
  <property>
    <!-- Heap maxima para las JVM de los reduces (por defecto: -Xmx2560M)-->
    <name>mapreduce.reduce.java.opts</name>
    <value>-Xmx512M</value>
    <final>true</final>
  </property>
  <property>
    <!-- El JobHistory Server -->
    <name>mapreduce.jobhistory.address</name>
    <value>jobhistoryserver:10020</value>
    <final>true</final>
  </property>
  <property>
    <!-- Interfaz web del JobHistory Server -->
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>jobhistoryserver:19888</value>
    <final>true</final>
  </property>
</configuration>
  

Configuración del entorno

Otros ficheros de configuración son los ficheros $HADOOP_PREFIX/etc/hadoop/*-env.sh. Modificad los siguientes:

  • hadoop-env.sh:
    • JAVA_HOME: definidlo como /usr/lib/jvm/java-8-openjdk-amd64
    • HADOOP_LOG_DIR: directorio donde se guardan los logs de hdfs. Definidlo como /var/log/hadoop/hdfs
  • yarn-env.sh
    • JAVA_HOME: definidlo como /usr/lib/jvm/java-8-openjdk-amd64
    • YARN_LOG_DIR: directorio donde se guardan los logs de YARN. Definidlo como /var/log/hadoop/yarn
  • mapred-env.sh
    • JAVA_HOME: definidlo como /usr/lib/jvm/java-8-openjdk-amd64
    • HADOOP_MAPRED_LOG_DIR: directorio donde se guardan los logs de MapReduce. Definidlo como /var/log/hadoop/mapred 

 

Crear el cluster hadoop

Clonar la imagen y la plantilla

  • Salimos de la conexión ssh y apagamos máquina virtual desde la web
    • Botón rojo -> "Apagar" (si la opción aparece desactivada, esperad un rato)
    • La MV desaparece una vez apagada
  • En el menú de Imágenes, seleccionar la imagen que tenemos y clonadla tres veces
    • Llamadle a estas copias DataNode1Imagen, DataNode2Imagen y DataNode3Imagen respectivamente
    • Esperad a que estas copias estén en estado LISTO
  • En el menú de Plantillas, seleccionar la plantilla que tenemos y clonadla tres veces
    • Llamadle a estas copias DataNode1Plantilla,  DataNode2Plantilla y DataNode3Plantilla respectivamente
    • Selecciona cada una de las nuevas plantillas y en el menú de "Actualizar", apartado "Almacenamiento", cambia el "Disco 0" para que asociarle la imagen correspondiente

Iniciar el cluster

De momento solo usaremos las plantillas NameNodePlantilla, DataNode1Plantilla y DataNode2Plantilla (la DataNode3Plantilla la usaremos más adelamnte)

A partir de esas plantillas crearemos tres máquinas virtuales

  • En el menú "Máquinas Virtuales" crea tres máquinas, cada una con una plantilla
  • Llamales NameNode, DataNode1 y DataNode2

 

Añadimos las IPs al DNS local de las MVs

Actualiza el fichero /etc/hosts de las tres máquinas virtuales con estas tres líneas (cambiando xx, yy, zz por los valores de las IPs de cada MV), para que sean accesibles por nombre en vez de IP:

10.38.3.xx       namenode resourcemanager
10.38.3.yy datanode1 checkpointnode
10.38.3.zz datanode2 jobhistoryserver

Adicionalmente, actualiza el fichero /etc/hosts de tu PC con estas tres líneas, para que los servicios Web sean accesibles por nombre en vez de IP.

Por último, ejecuta el comando hostname y cambia el fichero /etc/hostname de cada MV para que tenga el nombre bien (namenode, datanode1, datanode2)

 

Licenciado baixo a GNU Free Documentation License (Versión local)