Hadoop es un ecosistema, es decir, un conjunto de componentes que implementan las distintas funciones necesarias para trabajar en entornos Big Data. Esta pensado para trabajar con Clusters de ordenadores de bajo coste. Y es un proyecto de la fundación Apache, por lo que cuenta con una licencia de software libre, lo que significa que cualquiera puede usarlo sin tener que pagar por ello.
Hay dos componentes fundamentales en el ecosistema Hadoop:
- El sistema de ficheros distribuidos HDFS (Hadoop Distributed File System): Basado en la Big Table de Google que fue el primer sistema de ficheros distribuidos para trabajar con Big Data. Es el sistema de ficheros para trabajar con los ordenadores del clusters, realizando todas las funciones clásicas de un sistema de ficheros: guardar datos, localizar y acceder a ellos.
- El sistema de procesamiento MapReduce: Es el sistema para procesar los datos en el Cluster, que también está tomado de Google, quien lo desarrollo para procesar la información de las distintas páginas web que recogía para las búsquedas.
La clave del éxito de Hadoop es que divide el almacenamiento de los datos y el trabajo de procesamiento entre los distintos ordenadores del cluster, realizando varias operaciones en paralelo, pudiendo así manejar muchos datos en menor tiempo.
Contenidos
HDFS (Hadoop Distributed File System)
Como he comentado antes, HDFS es el Sistema de ficheros del ecosistema Hadoop. La filosofía de funcionamiento es la misma que cualquier sistema de ficheros tradicional, guarda una tabla de índices con la información de donde están almacenados todos los ficheros. Cuando queremos recuperar un fichero, el sistema de ficheros irá a consultar esa tabla para saber en que parte del soporte físico de memoria se encuentra nuestro fichero. Cuando guardemos o actualicemos un fichero, el sistema de ficheros modificará la tabla de índices acorde con la modificación que hayamos hecho, manteniendo la tabla de índices actualizada.
Hasta aquí todo muy similar a antes del Big Data, sin embargo, en un entorno Big Data en un cluster de ordenadores de bajo coste, fácilmente podemos encontrarnos con la situación de que nuestro fichero de datos sea mayor que la capacidad del disco duro de un ordenador del cluster. HDFS soluciona este tema fragmentando el fichero en varias partes que almacenará en distintos ordenadores del cluster. Y lógicamente guardara en sus tablas de índices donde ha almacenado cada fragmento.
Otro problema con el que tiene que lidiar Hadoop en un cluster de ordenadores es la tolerancia a fallos. Con tantos ordenadores, la probabilidad estadística de que tengamos un fallo se multiplica considerablemente, y en Big Data tenemos que ofrecer un entorno seguro y robusto.
Para asegurar la tolerancia a fallos, Hadoop utiliza la redundancia. Sencillamente hace varias copias de los fragmentos de datos en varios ordenadores distintos, y si un ordenador falla, sabe que otros ordenadores tienen dichos datos y puede ir a recuperarlos a estos, y seguir trabajando mientras se sustituye el nodo que fallo. Una solución sencilla que sin embargo requiere de más gasto en capacidad de almacenamiento, pero es el precio a pagar para asegurar la tolerancia a fallos.
Ejemplo de partición de un fichero:
Veamos con un ejemplo como se acelera el acceso a los datos con esta estrategia de fragmentación del fichero de datos en partes más pequeñas, que se llevan a cada ordenador del cluster.
Supongamos que nuestro fichero de datos es de 30 GB y que la conexión a los discos duros de los ordenadores del cluster es una SATA III, estándar habitual que tiene una velocidad de transferencia de 600 MB/seg.
El tiempo de acceso a los datos será la suma de dos tiempos, el de acceso y el de transferencia. El primero es el tiempo necesario para que los cabezales del disco duro se sitúen en la posición para empezar a leer, y es independiente de la cantidad de datos que leamos, podemos considerarlo fijo para cada disco duro y estimarlo en unos 15 milisegundos. El segundo es el tiempo que tardamos en leer los datos, lo cual en el estándar SATA III lo hacemos a razón de 600MB por segundo.
Si trabajamos con un único ordenador, tardaríamos en leer los 30 GB unos 50 segundos. Si empleáramos 10 ordenadores, tendríamos 10 fragmentos de 3 GB que leeríamos en paralelo, lo que nos llevaría un tiempo total de 5 segundos. Y si tuviéramos un cluster de 1.000 ordenadores, nuestros fragmentos serían de 30 MB y tardaríamos 65 milisegundos en la lectura de todos los datos.
En la tabla siguiente se pueden apreciar estos tiempos en función del número de equipos en el cluster:
Se puede apreciar como a partir de un cierto tamaño de fragmento, las mejoras en los tiempos de lectura empiezan a no ser apreciables. Sin embargo, el sistema de ficheros HDFS incrementa su tabla de índices cada vez que hacemos fragmentos más pequeños, ya que tiene más fragmentos que direccionar. En la practica hay que fragmentar el fichero hasta unos niveles razonables que reduzcan los tiempos de acceso a datos pero sin sobrecargar el sistema de ficheros.
MapReduce
MapReduce es un modelo de programación diseñado para trabajar con procesamiento paralelo, repartiendo la computación entre varios ordenadores. Lógicamente, esto encaja perfectamente con el entorno Big Data que venimos viendo, funcionando en un cluster de ordenadores de bajo coste, aunque solamente podremos aplicarlo con aquellos algoritmos susceptibles de ser paralelizados.
Cuando trabajamos con bases de datos, lo más habitual es mover los datos al equipo donde realizamos las tareas de computación. Esta manera de operar tiene grandes inconvenientes en Big Data, ya que la cantidad de datos que manejamos puede ser inmensa y resulta muy ineficiente andar trasladando los datos, o parte de ellos, desde los equipos que los almacenan a los equipos que tienen que procesarlos.
La filosofía de MapReduce es de computación distribuida, lo que básicamente significa que en lugar de mover los datos a un servidor, movemos el esfuerzo de computación a los ordenadores del cluster que almacenan los datos. De esta forma no tenemos que andar moviendo grandes cantidades de datos por la red, lo que moveremos será el código del programa MapReduce para que se ejecute en cada ordenador. Obviamente, la cantidad de datos que supone este código es muy pequeña, probablemente no llegue ni al Mega de memoria, con lo que el ahorro frente a la opción de mover todos los datos, es bastante apreciable.
Funciones Map y Reduce
El modelo MapReduce en realidad se compone de dos funciones: Map y Reduce, que se aplican de forma consecutiva. Primero aplicamos la función Map, y al resultado de esta le aplicamos la función Reduce.
Ambas funciones están definidas para trabajar con datos agrupados en Tuplas, es decir, pares clave – valor. Y puesto que se trata de un modelo de programación paralela, ambas funciones se ejecutan en paralelo en distintos ordenadores.
La función Map trabaja directamente sobre los datos, que le son suministrados en una estructura de Tupla (clave, valor), generando un mapeo de los mismos, una especie de primera clasificación. El resultado de esta función también está estructurado en forma de tuplas.
La función Reduce trabaja sobre el resultado de la función Map. En realidad es la que realiza la operación final que queramos ejecutar, agrupa, cuenta, suma, lo que sea que hayamos programado. Mientras que la función Map puede verse como un mapeo de los datos para prepararlos para la entrada de la función Reduce.
¿Cómo funciona MapReduce?
Antes de entrar en funcionamiento MapReduce, necesitamos que los datos sobre los que vamos a actuar ya estén almacenados en el cluster. De esta primera circunstancia se ha ocupado HDFS, que ha dividido el fichero de datos en varias particiones que almacena en distintos ordenadores del cluster. En este punto, conviene recordar que HDFS guarda varias copias de los citados fragmentos para asegurar de esta forma la tolerancia a fallos.
A partir de ahí, los pasos serían los siguientes:
- Se distribuye el programa MapReduce a los ordenadores del Cluster.
- Uno de los ordenadores tomará el rol de “maestro”, que como podemos imaginar será el que coordine todo. Al resto de ordenadores se les llama “workers” y ejecutaran las tareas map y reduce, según las asigne el maestro.
- Un worker puede estar en tres estados: en reposo, trabajando o completado. El maestro va buscando workers en reposo para ir asignándoles las tareas.
- Las tareas Map asignadas a cada worker, se realizan sobre el fragmento de datos que dicho ordenador tiene almacenada en local. Como no podía ser de otra forma, si tuviéramos que andar moviendo datos de unos ordenadores a otros, perderíamos toda la ventaja.
- El resultado de aplicar la función Map al fragmento de datos almacenados en el ordenador, se denominan datos intermedios, que se almacenan en el disco duro local de cada ordenador.
- El maestro recibe información de estos datos intermedios, y la emplea para redirigir a los workers que tienen tareas reduce asignadas.
- Entonces, los workers con tareas reduce, se comunican con los workers con tareas map que le corresponda, según asignación del maestro. Leen los datos intermedios almacenados en los discos duros de los workers tipo map y ejecutan la función Reduce. Los workers tipo Map, a menudo realizan tareas de agrupación para simplificar la tarea a los Reduce.
- En ocasiones, si los datos intermedios ocupan mucho espacio, puede resultar necesario emplear ordenamiento externo.
- El resultado de las funciones Reduce, constituye el resultado de salida del modelo MapReduce. Este resultado se almacena en un fichero gestionado por HDFS, de tal forma que puede ser empleado como entrada de otro proceso MapReduce o por cualquier aplicación que requiera los datos.
El proceso presenta una alta tolerancia a fallos. El master está continuamente comprobando el estado de los workers y si detecta algún fallo, reasigna las tareas del worker caído a otro equipo que este disponible. En cuanto un worker termina la tarea que se le ha encomendado, inmediatamente vuelve al estado reposo, indicándole al master que esta disponible para que se le asignen otras tareas.
Ejemplo de MapReduce
El funcionamiento del proceso MapReduce, puede resultar un poco complejo. Probablemente, la mejor manera de entenderlo sea con un ejemplo. Y un ejemplo, que a mi modo de ver, explica bastante bien el empleo de MapReduce es el contador de palabras.
Supongamos que tenemos un texto y queremos saber las palabras que aparecen en él, y cuantas veces aparecen. Obviamente, trabajando en Big Data, los datos serían muchos, la actualización de los mismos sería de manera continua y tendríamos gran variedad de estructuras de datos. Un buen ejemplo sería emplear este contador de palabras con todos los tweets de twitter realizados en un día. Y para el ejemplo pondré algunos datos numéricos ficticios pero que nos ayudaran a entenderlo mejor.
1.- Lo primero de todo, son los datos sobre los que aplicaríamos el proceso MapReduce que contaría el número de veces que aparece cada palabra. Supongamos que ese día se han realizado 1.000.000 de tweets por poner un dato redondo, aunque ciertamente muy bajo.
El sistema de ficheros HDFS divide los datos en 500 fragmentos con 2.000 tweets cada uno, alojándolos en 500 ordenadores diferentes de nuestro cluster, que tiene 1.000 ordenadores. Lógicamente, HDFS opera con redundancia para ser tolerante a fallos, es decir, guarda varias copias de cada fragmento en distintos ordenadores.
2.- La estructura de los datos tiene que estar organizada en tuplas, pares clave – valor. Supongamos que estas tuplas serían del tipo:
– (clave: 1 ; valor: el día es soleado y hace calor)
– (clave: 2 ; valor: el calor es alto y el gasto también es alto)
…..
– (clave: n ; valor: texto del tweet n)
Donde la clave sería el número del tweet y el valor sería el texto del tweet.
Estas tuplas serían los inputs para la función Map
3.- Se envía el programa MapReduce a los ordenadores del cluster. Uno de ellos, toma el rol de maestro y empieza a distribuir el trabajo.
4.- La función Map produciría una serie de Tuplas como las siguientes:
(“ el”,1); (“ día”,1); (“es”,1); (“soleado”,1); (“y”,1); (“hace”,1); (“calor”,1); (“el”,1); (“calor”,1); (“es”,1); (“alto”,1); (“y”,1); (“el”,1); (“gasto”,1); (“también”,1); (“es”,1); (“alto”,1)
Por razones prácticas, lo aplico sólo a las dos primeras Tuplas de un fragmento de datos de un ordenador. Pero no perdamos de vista que teníamos 500 fragmentos a procesar en 500 ordenadores, cada uno de ellos con 2.000 tweets.
5.- Este resultado de la función Map, es mapeado para generar los datos intermedios:
(“ el”,[1,1,1]); (“ día”,[1]); (“es”,[1,1,1]); (“soleado”,[1]); (“y”,[1,1]); (“hace”,[1]); (“calor”,[1,1]); (“alto”,[1,1]); (“gasto”,[1]); (“también”,[1])
6.- Y finalmente, la función Reduce realizaría el conteo, quedando el siguiente resultado:
(“ el”,3); (“ día”,1); (“es”,3); (“soleado”,1); (“y”,2); (“hace”,1); (“calor”,2); (“alto”,2); (“gasto”,1); (“también”,1)
NOTA:
Este post es parte de la colección “Arquitectura de Datos” que reproduce los apuntes de la clase que imparto sobre el tema en ESIC. Puedes ver el índice de esta colección aquí.
Deja una respuesta