Saltar la navegación

Implementación de un cluster

Existen varios tipos de software libre para implementar un cluster de servidores, por ejemplo:

Para la implementación de un cluster en Debian GNU/Linux utilizando Hadoop utilizaremos el repositorio de la empresa Cloudera, pues Debian no lo incluye en los suyos por el momento.

Hadoop es un proyecto desarrollado por la comunidad Apache Software Fundation que aglutina diferentes subproyectos, donde se desarrolla software de código abierto. En concreto, proporciona un framework, escrito en Java, sobre el cual desarrollar aplicaciones distribuidas que requieren un uso intensivo de datos y de alta escalabilidad.

Hadoop implementa, entre otras cosas, un sistema de ficheros distribuido denominado HDFS (Hadoop Distributed File System), el cual está pensado para almacenar grandes cantidades de información, del orden de terabytes o petabytes, tolerante a fallos y diseñado para ser instalado en máquinas de bajo coste. La información es dividida en bloques, que son almacenados y replicados en los discos locales de los nodos del cluster.

HDFS se compone de un grupo de nodos interconectados, donde residen los archivos y directorios. Presenta una arquitectura master/slave basada en un único nodo maestro, denominado NameNode, que maneja y regula el acceso de los clientes a los ficheros, redirigiéndolos a los nodos de datos que contienen la información, denominados DataNodes, que son los encargados de gestionar el almacenamiento en los discos locales del propio nodo. Tanto el NameNode como los DataNodes son componentes software, diseñados para funcionar en máquinas genéricas a través de sistemas operativos heterogéneos.

HDFS ha sido construido utilizando el lenguaje de programación Java, por lo tanto, cualquier máquina que soporte dicho lenguaje puede ejecutar HDFS. Una instalación típica consta de una máquina dedicada, donde se ejecutará el NameNode, y en cada una de las máquinas restantes que constituyen el clúster, se ejecutará un DataNode.

Una aplicación cliente, que desea leer un fichero en HDFS, debe contactar primero con el NameNode, para determinar el lugar en el cual está almacenada la información que se solicita. En respuesta al cliente, el NameNode retorna el identificador del primer bloque del fichero requerido y el nodo en el cual está almacenado. A continuación, el cliente contacta con el DataNode para recuperar toda la información.

Una característica importante del diseño de este sistema de ficheros es que la información nunca se mueve al NameNode. Toda la transferencia de información se produce directamente entre los clientes y los nodos de datos. La comunicación con el NameNode sólo implica transferencia de metainformación. Los DataNodes están periódicamente facilitando información de su estado al NameNode.

Para que el sistema de ficheros sea tolerante a fallos, HDFS replica los bloques de ficheros. Una aplicación puede especificar el número de réplicas para un fichero en el momento en el que es creado, pudiendo ser cambiado en cualquier momento. El NameNode toma las decisiones relativas a la replicación de bloques. Uno de los objetivos principales de HDFS es dar soporte a ficheros de gran tamaño. El tamaño típico de un bloque de fichero en HDFS es 64Mb o 128Mb. Un fichero está compuesto de uno o varios bloques de 64/128Mb y HDFS trata de colocar cada bloque en nodos de datos separados, distribuyendo la información a lo largo del clúster. Los bloques no siempre pueden ser colocados de manera uniforme en los DataNodes, lo que significa que el espacio disponible por uno o más nodos de datos puede estar infrautilizado. Otro caso común, que provoca que la distribución de los datos entre los diferentes nodos no esté balanceada, es la adición de nuevos DataNodes al cluster.

HDFS proporciona rebalanceo de bloques de datos utilizando diferentes modelos. Un modelo permite mover los bloques de un nodo de datos a otro, de forma automática, si el espacio libre en un nodo cae demasiado. Otro modelo permite crear, dinámicamente, réplicas adicionales para un determinado fichero, si se produce un aumento repentino de la demanda, rebalanceando otros bloques en el cluster. HDFS también proporciona comandos que permiten realizar tareas de reajuste de forma manual.

Instalación de un sistema de ficheros distribuido HDFS

Tras instalar el HDFS, conseguiremos aumentar la velocidad en las operaciones de lectura y escritura sobre el sistema de archivos (el trabajo se reparte entre los diferentes nodos del cluster), así como aumentar la disponibilidad de los datos, al comportarse el cluster como un sistema RAID1 al establecerse una replicación entre varios nodos de la red, de tal forma que si alguno de los nodos cae, siempre se pueden recuperar los datos a través de otro de los nodos donde haya una réplica. Como ya se verá más adelante, por defecto, hadoop establece una replicación de 3 (comportamiento equivalente a un sistema RAID1 formado por 3 discos), aunque esto puede configurarse a posteriori.

Después de la instalación de hadoop, configuraremos un servicio de transferencia de archivos (FTP, SMB, etc.), el cual hará uso del sistema HDFS para almacenar los archivos, de tal forma que podríamos hacer pruebas de rendimiento (velocidad y disponibilidad).

La implementación del cluster la vamos a hacer sobre tres máquinas virtuales donde una de ellas funcionará como controlador del cluster (NameNode) y nodo de datos (DataNode) a la vez, y las otras dos solo como nodos de datos. Todo esto dentro de la red 192.168.1.0/24 (se podría haber elegido cualquier otra red).

No debemos olvidar que el objetivo fundamental de esta instalación es la de comprender la base de los clusters y los beneficios que aportan. Es por ello, que para simplificar los aspectos de la instalación del software, se hará uso de unos repositorios de hadoop cloudera correspondientes a una versión antigua, en lugar del código fuente disponible  correspondiente a la última versión de Apache hadoop. Pero la finalidad última de la práctica sería implementar el cluster sobre un entorno real formado por equipos con sistemas operativos de escritorio, donde los usuarios estarían trabajando en sus equipos con sus herramientas habituales, al mismo tiempo que en background estarían formando parte de un sistema de archivos distribuido HDFS, destinando parte de su potencia en ello, pues hoy en día, la mayor parte de los equipos están funcionando por debajo de su capacidad de procesamiento.

En primer lugar, vamos a preparar las máquinas virtuales para que tengan nombre, configuración de red y dos discos cada una, en uno de los discos estará el sistema operativo y el segundo será el que se utilice para el almacenamiento de los datos del cluster. El sistema operativo de estas máquinas será la versión Squeeze de Debian (versión 6), y esto es debido a que vamos a usar una versión antigua de Hadoop, con el objetivo de simplificar la instalación de éste, y centrarnos fundamentalmente en lo que es un cluster, como se mencionó en el párrafo anterior.

Estas máquinas virtuales tendrán los siguientes valores:

  • La primera máquina virtual tendrá de nombre hadoop1 (/etc/hostname), funcionará como NameNode y DataNode, IP 192.168.1.10, GW 192.168.1.1, DNS 8.8.8.8  y sus discos son /dev/sda y /dev/sdb.
  • La segunda máquina virtual: hadoop2 (/etc/hostname), DataNode, 192.168.1.20, 192.168.1.1, 8.8.8.8 y sus discos son /dev/sda y /dev/sdb.
  • La tercera máquina virtual: hadoop3 (/etc/hostname), DataNode, 192.168.1.30, 192.168.1.1, 8.8.8.8 y sus discos son /dev/sda y /dev/sdb.

El software que necesitamos instalar es el siguiente: java, hadoop y hadoop-fuse-dfs (nos permitirá montar el sistema HDFS en nuestro sistema). Para ello necesitamos agregar repositorios PPA a nuestro sistema operativo Debian GNU/Linux versión Squeeze.

Instalaremos Java en todos los equipos del cluster mediante los paquetes oracle-java7-installer y oracle-java7-set-default. La forma de hacerlo es la siguiente:

  1. Añadimos el repositorio PPA para instalar Java creando el fichero /etc/apt/sources.list.d/webupd8team-java.list y le añadimos las dos líneas siguientes:

deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main
deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu precise main

  1. Instalamos la clave pública del repositorio:
# apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886
  1. Por último instalamos los paquetes:
# aptitude update
# aptitude install oracle-java7-installer
# update-java-alternatives -s java-7-oracle
# aptitude install oracle-java7-set-default

En este último paso, aceptamos y respondemos afirmativamente a las dos preguntas que sobre aceptación de licencias se nos hace.

Preparamos a continuación, también en todos los equipos, el repositorio de Apache Hadoop de Cloudera, lo cual puede hacerse de forma simple instalando el paquete cdh3-repository_1.0_all.deb que se encuentra en http://archive.cloudera.com/one-click-install/squeeze/:

  1. Descargamos el paquete:
# wget http://archive.cloudera.com/one-click-install/squeeze/cdh3-repository_1.0_all.deb
  1.  Lo instalamos y actualizamos la base de datos local de paquetes:
# dpkg -i cdh3-repository_1.0_all.deb
# aptitude update

Para terminar con la instalación del software, instalamos los paquetes de Hadoop que necesitamos. Si hasta ahora, todo lo que hemos hecho ha afectado a todos los equipos, en este punto instalaremos los paquetes adecuados a cada equipo según su papel dentro del cluster:

  • Para el equipo que hará de namenode y datanode a la vez:
# aptitude install hadoop-0.20 hadoop-0.20-namenode hadoop-0.20-datanode hadoop-0.20-fuse
# reboot
  • Para cada uno de los equipos que sólo harán de datanode:
# aptitude install hadoop-0.20 hadoop-0.20-datanode
# reboot

A continuación, preparamos (en todas las máquinas) el disco /dev/sdb que es donde habíamos decidido almacenar los datos del cluster:

  1. Creamos una única partición (/dev/sdb1) para todo el disco.
  2. Le damos ext4 como sistema de ficheros.
  3. La partición se montará de forma automática al arrancar el sistema en el directorio /cluster con las opciones por defecto (defaults).
  4. Montamos la partición y creamos la estructura de directorios necesaria para el cluster, la cual está formada en todos los nodos por los directorios /cluster/dfs/name y /cluster/dfs/data.
  5. Hacemos que la estructura anterior pertenezca al usuario hdfs, creado durante la instalación de Hadoop y es quien maneja el servicio hdfs.
  6. El único usuario que tendrá permisos sobre el directorio /cluster/dfs/data será hdfs y los tendrá todos.

Pasamos ahora a configurar Hadoop a través de los fichero core-site.xml y hdfs-site.xml que se encuentran en /etc/hadoop/conf/. Haremos lo siguiente en todos los nodos del cluster:

  1. En core-site.xml estableceremos la propiedad fs.default.name con el valor de la IP del equipo namenode y el puerto del servicio hdfs:
<configuration>
...
<property>
<name>fs.default.name</name>
<value>hdfs://192.168.1.10:9000</value>
<description>URI del NameNode</description>
</property>
...
</configuration>
  1. En hdfs-site.xml estableceremos las propiedades dfs.name.dir (indica el directorio donde se almacenará la metainformación del servicio) y dfs.data.dir (indica el directorio donde se almacenarán los bloques de datos de los ficheros):
<configuration>
...
<property>
<name>dfs.name.dir</name>
<value>/cluster/dfs/name</value>
<description>Directorio de la metainformación del cluster</description>
</property>

<property>
<name>dfs.data.dir</name>
<value>/cluster/dfs/data</value>
<description>Directorio de los datos del cluster</description>
</property>
...
</configuration>

Aunque para el funcionamiento del cluster Apache Hadoop sólo es necesario configurar las tres propiedades anteriores, existen muchas otras, como por ejemplo dfs.replication (hdfs-site.xml), que determina el número de nodos de datos donde se replicará cada uno de los archivos que se almacenen en el cluster. Su valor por defecto es 3, lo que equivale a implementar un volumen RAID1 con 3 discos distribuidos.

Una vez terminada la configuración de Apache Hadoop arrancamos el namenode y los datanodes.

Comenzamos con el namenode que es el equipo hadoop1 y lo primero que haremos será convertirnos en el usuario hdfs:

# su hdfs
$

A continuación le damos formato al nodo y lo activamos en segundo plano:

$ hadoop namenode -format
$ hadoop namenode &

Podemos comprobar que el namenode está funcionando conectándonos a él vía web por el puerto 50070 desde cualquier ordenador de la red (http://192.168.1.10:50070):

Estado del NameNode

Vemos que el apartado Live Nodes tiene valor 0, debido a que no hemos activado aún los datanodes. También se observa que la capacidad del cluster en este memento es de 0 KB, lo cual se especifica en el apartado Configured Capacity. Por tanto, pasamos ahora a activar los datanodes, que son los equipos hadoop1 (también es namenode), hadoop2 y hadoop3; en estos tres equipos habrá que ejecutar:

# su hdfs
$ hadoop datanode &

Conforme vamos activando los datanode, podríamos ir viendo cómo cambia la información del cluster. Al activar los tres, tendríamos una información parecida a la siguiente (dependerá del tamaño de los discos):

Cluster con 3 datanodes

En el directorio /etc/init.d se han creado los script hadoop-0.20-namenode y hadoop-0.20-datanode con los que poder detener, iniciar, etc. el servicio Apache Hadoop:

# /etc/init.d/hadoop-0.20-namenode
Usage: /etc/init.d/hadoop-0.20-namenode {start|stop|restart|force-reload|status|force-stop|upgrade|rollback}
# /etc/init.d/hadoop-0.20-datanode
Usage: /etc/init.d/hadoop-0.20-datanode {start|stop|restart|force-reload|status|force-stop|rollback}

Por otro lado, en el directorio /var/log/hadoop se encuentran los ficheros log donde consultar los avisos y errores del servicio.

El valor de todas las propiedades de configuración de hadoop la podemos consultar en la dirección http://192.168.1.10:50070/conf, y ahí, se nos dice también si el valor es por defecto o leído de alguno de los ficheros de configuración:

Propiedades de Hadoop

Como último paso, previo al uso del cluster, montaremos el sistema de archivos distribuido HDFS en el namenode mediante la ayuda de la herramienta hadoop-fuse-dfs instalada previamente, con la finalidad de que pueda ser utilizado como una unidad de almacenamiento más por el sistema. El montaje y desmontaje del sistema de ficheros se haría así:

# mkdir /hdfs
# ls -ld /hdfs
drwxr-xr-x 2 root root 4096 ene 26 19:27 /hdfs
# hadoop-fuse-dfs dfs://192.168.1.10:9000 /hdfs
INFO fuse_options.c:165 Adding FUSE arg /hdfs
# ls -ld /hdfs
drwxr-xr-x 3 hdfs 99 4096 ene 26 22:12 /hdfs
# fusermount -u /hdfs
# ls -ld /hdfs
drwxr-xr-x 2 root root 4096 ene 26 19:27 /hdfs

Se ha creado el directorio /hdfs que funcionará como punto de montaje del cluster, pero podría haber sido cualquier otro directorio. Después, observamos que el dueño de /hdfs es root, pero cuando se monta, el dueño es el usuario hdfs, que es el único que podrá escribir sobre él, por lo que habrá que suplantarlo para utilizar el cluster. En el proceso de montaje se especifica la IP del namenode y el puerto por el que escucha, por defecto el 9000. Para desmontarlo se usa el comando fusermount con la opción -u y el punto de montaje.

Vamos ahora a crear un servicio de ftp anónimo en el namenode mediante el servidor ftp proftpd. Lo configuraremos para que suplante al usuario hdfs. Con este servicio podríamos hacer pruebas de rendimiento y alta disponibilidad del cluster.

# hadoop-fuse-dfs dfs://192.168.1.10:9000 /hdfs
INFO fuse_options.c:165 Adding FUSE arg /hdfs
# aptitude install proftpd
# nano /etc/proftpd/proftpd.conf

En el fichero proftpd.conf introducimos lo siguiente para configurar su acceso anónimo:

<Anonymous /mnt/hdfs>
  User hdfs
  UserAlias anonymous hdfs
  <Limit LOGIN>
    AllowAll
  </Limit>
</Anonymous>

Reiniciamos el servicio ftp:

# /etc/init.d/proftpd restart
Stopping ftp server: proftpd.
Starting ftp server: proftpd.

A partir de este momento podemos conectarnos al servidor ftp (192.168.1.10) con el usuario anonymous y podemos hacer uso del cluster.

Otro ejemplo de uso del cluster que acabamos de crear podría ser el de crear un directorio público para nuestra red, usando para ello samba.

# mkdir /publico
# aptitude install samba
# nano /etc/samba/smb.conf

Añadimos al fichero smb.conf el recurso compartido al que llamaremos publico y que será el directorio /hdfs donde tenemos montado el cluster:

[publico]
path = /hdfs
writable = yes
browseable = yes
guest ok = no
force user = hdfs

Comprobamos el fichero de configuración de samba y reiniciamos el servicio si no hay errores:

# testparm
# /etc/init.d/samba restart
Stopping Samba daemons: nmbd smbd.
Starting Samba daemons: nmbd smbd.

Creamos claves de samba a los usuarios que se les va a permitir el uso de este servicio:

# smbpasswd -a usuario
New SMB password:
Retype new SMB password

Podemos conectarnos ahora desde windows, por ejemplo, escribiendo en el explorador de archivos la dirección \\192.168.1.10.