Computación distribuida con Hadoop I

dom, 17 ene 2010 by Foron

Allá por el año 2003, cuando Google ya dominaba el mundo de los buscadores, muchos administradores de sistemas nos preguntábamos por la tecnología que usarían para indexar páginas, calcular Pageranks, gestionar el almacenamiento ....

En ese momento Google publicó varios documentos al respecto, como este sobre MapReduce y este otro sobre su sistema de ficheros GFS (Google File System), que daban algunas pistas, y que a la larga han sido la base de varios proyectos, como Hadoop.

Pretendo que este blog sea sobre todo práctico, así que no voy a escribir demasiado ni sobre la teoría que hay detrás de MapReduce (programación funcional, map/reduce, bla bla bla) ni sobre Google y GFS. Para el que quiera leer algo más sobre la tecnología de Google recomiendo este excelente blog en el que se pueden encontrar varios posts sobre el buscador.

El problema

El problema es sencillo y se resume en el volumen de datos, cada vez mayor, que generan las aplicaciones; y que por supuesto hay que tratar. Por dar un ejemplo, en el 2008 Yahoo! gestionaba unos 5PB de almacenamiento para generar su "webmap" [1], que es uno de los componentes que usa su buscador. Otro ejemplo es Rackspace, y su división de correo, Mailtrust, que genera más de 150GB de logs de correo al día. Por supuesto, además de ser mucho volumen acomulado, es fundamental que se pueda tratar de una forma ágil para dar una respuesta rápida a clientes que piden cosas como "el correo que me mandó fulanito hace 3 meses no me ha llegado" o "quiero todos los correos recibidos en mi dominio en los últimos 5 meses". Esto es razonablemente sencillo cuando se controlan unos pocos cientos de GB, pero se hace mucho más difícil cuando la escala pasa al Tera.

El que haya nombrado estos dos ejemplos no es casual, ya que Yahoo! y Rackspace son dos de los usuarios más notables (junto a Facebook, LastFM, ...) del software que voy a describir en los siguientes posts: Hadoop.

¿Qué es Hadoop?

Resumiendo mucho, Hadoop es un framework software que intenta implementar los conceptos de MapReduce y GFS que presentó Google. Está pensado, por lo tanto, para el tratamiento distribuido de grandes cantidades de datos en máquinas de bajo coste y con poca fiabilidad.

Partiendo de esta base, parece claro que hace falta un sistema de ficheros pensado para almacenar mucha información y con tolerancia ante fallos. Aquí es donde aparece HDFS (Hadoop Distributed File System). Algunas de sus características:

  • El tamaño de bloque por defecto en este sistema de ficheros es de 64MB, pero muchas veces se aumenta a 128MB.
  • Ofrece la mencionada disponibilidad al dejar varias copias de cada bloque en máquinas diferentes.
  • Usa el concepto de "rack awareness", para saber dónde está cada bloque y qué proceso de cálculo puede acceder más rápido a él.
  • Su diseño facilita la lectura secuencial de datos (razonable en discos estándar de bajo coste), pero lo hace sacrificando otras características propias de los sistemas de ficheros POSIX. Por ejemplo, que nadie piense editar un fichero en HDFS y borrar la línea número 2000.

Por otro lado, el framework implementa el concepto MapReduce, que como ya he escrito consiste en dividir el trabajo entre n servidores para presentar el resultado después de forma coherente. Veamos un ejemplo:

Digamos [2] que tenemos un cluster de 4 máquinas Hadoop que guardan logs de apache de 40 servidores balanceados, para un total de 100GB al día. Nuestro objetivo es diseñar un trabajo MapReduce para sumar los accesos que ha hecho cada IP en todos los frontales.

Los logs van a ser sencillos y se van a limitar a "FECHA IP URL".

Servidor 1:

  FECHA 172.17.2.34 /index.html
  FECHA 172.17.7.13 /contenido/futbol.html
  FECHA 172.17.2.34 /img/banner.jpg
  FECHA 172.17.2.42 /index.html

Servidor 2:

  FECHA 172.17.2.34 /contenido/peliculas.html
  FECHA 172.17.7.13 /img/futbol.jpg

Servidor 3:

  FECHA 172.17.7.13 /index.html
  FECHA 172.17.2.34 /peliculas/bladerunner.html
  FECHA 172.17.2.42 /img/banner.jpg

Servidor 4:

  FECHA 172.17.2.42 /contenido/series.html
  FECHA 172.17.2.42 /img/series.jpg

A partir de estos datos Hadoop empezará la fase Map, que se ejecuta paralelamente en las máquinas del cluster, y que consiste en adaptar las líneas de log al formato clave< tabulador >valor.

Volviendo al ejemplo, la clave será la IP, y el valor la URL (no necesitamos la fecha). El resultado de la fase Map es el siguiente [3]:

  (172.17.2.34 [/index.html /img/banner.jpg /contenido/peliculas.html /peliculas/bladerunner.html])
  (172.17.2.42 [/index.html /img/banner.jpg /contenido/series.html /img/series.jpg])
  (172.17.7.13 [/contenido/futbol.html /img/futbol.jpg /index.html])

Hemos generado un listado ordenado por IP, en el que se identifican todos los accesos que ha habido.

Una vez hecho esto Hadoop entrega trozos de esta salida a n procesos Reduce, que en este sencillo ejemplo sólo tienen que contar las URL que aparecen en el valor, para generar algo como lo siguiente:

  (172.17.2.34    4)
  (172.17.2.42    4)
  (172.17.7.13    3)

Esto no es más que un ejemplo. En la realidad, Hadoop se ha usado para cosas tan diversas como convertir 4TB de artículos de periódico escaneados en formato tiff en 11 millones de pdfs; todo usando unas 100 instancias de amazon y en menos de 24 horas, por un total de 240$ sin contar ancho de banda, como se puede ver aquí.

El próximo post describirá una instalación básica del sistema, y el siguiente será una prueba algo más interesante de uso con logs de postfix+amavis, muy al estilo Mailtrust, y usando perl y quizá alguno de los proyectos de apoyo que han surgido alrededor de Hadoop; como Hive, que fue desarrollado por Facebook para crear trabajos MapReduce desde una consola con sintaxis muy similar a SQL.

Notas

[1]En el 2008 el webmap de Yahoo! era un grafo de un trillón de vértices(enlaces web) y 100 billones de nodos (URL únicas).
[2]Los tres o cuatro lectores de este blog se enfadan si no uso al menos un "digamos" o "supongamos" en cada post.
[3]En realidad hay más fases, como sort-suffle.

Comments