jueves, 23 de mayo de 2013

WordCount: testing Hadoop

En la anterior entrada hablé de Ambari, la plataforma para el control de clusters Hadoop y servicios asociados. Hoy vamos a poner a prueba el funcionamiento de cluster. Para ello lanzaremos nuestro primer programa paralelo. Para lo ocasión usaremos uno de ejemplo de los que podréis encontrar en la Wiki de Hadoop y cuya función es contar las palabras que aparecen en uno (o varios) archivos de texto.

Antes de ello, repasemos algunos conceptos asociados a Hadoop. Como ya vimos anteriormente, su objetivo es proveer un entorno para el trabajo paralelo bajo el paradigma MapReduce, trabajos que se distribuyen para su procesamiento en un cluster. HDFS es el sistema de ficheros en dicho cluster que soporta esta operativa. Este sistema de ficheros permite, usando el disco local de cada máquina, generar un espacio unificado que desde el punto de vista lógico se comporta y gestiona como si de un solo disco se tratase. En realidad por debajo HDFS lo que hace es replicar la información en los diferentes nodos del cluster asegurando en todo momento la coherencia de datos y la tolerancia a fallos por caídas puntuales de nodos.

Lo primero que necesitaremos en un fichero de entrada con palabras que contar. Como es un test tampoco importa mucho cómo sea ese fichero. Por ejemplo, he generado uno de nombre input1.txt concatenando varios ficheros de logs del sistema. El fichero ocupa 542MB y tiene mas de 6 millones de líneas:


Como puede verse en la imagen anterior, primero deberemos copiar el fichero al espacio de disco HDFS del cluster. Eso se consigue haciendo uso de los comandos Hadoop asociados al tratamiento del almacenamiento (dfs), en concreto tendremos que crear un nuevo directorio que contenga el fichero de entrada y copiarlo en dicha localización dentro del espacio HDFS.

Pero antes de lanzar nuestro programa tendremos que crearlo. Hadoop está desarrollado con tecnología Java por lo que ofrece todo un conjunto completo de librerías bajo este lenguaje para desarrollar los aplicativos paralelos. En nuestro caso el código que especifica cómo debe ser tratada la entrada, wordcount, debe definir las acciones tanto para el mapeo (Map) como la reducción (Reduce). Siguiendo el ejemplo de la wiki comentado anteriormente, el código quedaría de la siguiente forma:

Es bastante intuitivo interpretar lo definido anteriormente. Se puede apreciar que están definidas claramente tres secciones:
  1. La función Map: en la que a cada palabra se le asigna el valor 1 (one)
  2. La función Reduce: en la que se agrega dicho valor por cada palabra mapeada
  3. La función main: principal, que es la que controla la creación de la tarea (Job), establece los parámetros iniciales de lanzamiento y controla su estado.
Definido el fichero de entrada y el programa paralelo solo resta ejecutarlo en nuestro cluster:

Como acabamos de comprobar, nuestro job paralelo se ha ejecutado en el cluster Hadoop satisfactoriamente, obteniendo una respuesta a nuestra necesidad: contar el numero de veces que cada palabra aparecía en el fichero de entrada. Pero recordemos que disponemos de la plataforma Ambari, nuestro controlador del cluster Hadoop. Si revisamos en su interfaz web podremos ver detalles interesantes como, por ejemplo, la información asociada al job:


De forma rápida tenemos acceso a información detallada sobre el trabajo en ejecución. Y si pulsamos sobre el job en concreto obtendremos un detalle aun mayor de cómo y cuando se han ido ejecutando las diferentes fases del trabajo:


Visualmente obtenemos información tan interesante como:
  • El estado de ejecución: exitoso (SUCCESS) o erróneo (FAILED)
  • La duración total del trabajo, casi 212 segundos
  • 5 de los 6 nodos disponibles han estado implicados en el trabajo
  • Detalles sobre el estado de ejecución de la tarea en el tiempo, como cuantos nodos han participado en las diferentes fases Map y Reduce.
Si comparamos esta tarea con realizar el cálculo haciendo uso de un script tradicional (secuencial) observamos el siguiente resultado:


En este caso, la ejecución completa del trabajo ha tardado 4 minutos y 35 segundos, es decir, 275 segundos. Comparativamente se ha obtenido una reducción del 30% en tiempo de ejecución gracias al uso del cluster.

Y esto es solo un ejemplo. Con tareas mejor diseñadas las reducciones podrían ser mas significativas. Y no olvidemos que el cluster, y su filosofía de trabajo paralelizada, nos permiten abordar problemas de cálculo con volúmenes de entrada muy grandes. En este ejemplo hemos usando un fichero con unas 6 millones de lineas. Pero imaginad que tuviera, por ejemplo, 10 o 100 veces más. El problema seguiría siendo resoluble en nuestro cluster Hadoop y sin embargo, por limitaciones de memoria, una sola máquina de forma secuencial dificilmente podría abordarlo.

domingo, 19 de mayo de 2013

Ambari: Plataforma para el procesamiento paralelo

Hoy quiero hablar de Ambari, un proyecto bajo el auspicio de la Fundación Apache y que cuenta con el apoyo de la gente de Hortonworks. El objetivo de Ambari es proveer de un framework amigable para el uso de Hadoop y sus aplicaciones complementarias (HDFS, MapReduce, Hive, HCatalog, HBase, etc) en una solución integrada y facilmente escalable. Si tu pregunta es ¿qué es Hadoop?, pues Hadoop es una solución de software libre para el tratamiento de lo que ahora está tan de moda: el Bigdata.

Bigdata es (según la Wikipedia), en el sector de tecnologías de la información y la comunicación, una referencia a los sistemas que manipulan grandes conjuntos de datos. A grandes rasgos se trata de analizar ingentes cantidades de datos con el objetivo de obtener información relevante de ellos. Pero procesar grandes volúmenes de información no es una tarea fácil. Muchas veces el conjunto de datos a analizar es tan grande que excede las capacidades de espacio, en disco y memoria, de los sistemas convencionales y el tiempo que requeriría su análisis secuencial sería considerable. ¿Cómo resolver el problema? Divide y vencerás.

En 2004 los gurus de Google publicaron una documentación relativa al paradigma MapReduce el cual toma un problema complejo y lo divide en varios trozos procesables de forma paralela. Cada uno de estos trozos son enviados un servidor, o nodo del cluster, que trabaja con ellos en dos fases claramente diferenciadas:
  • Map: Fase de mapeo en la que se toma el conjunto de datos de entrada y se mapea esa entrada de una determinada forma
  • Reduce: Fase en la que se toman los valores mapeados previamente y se aplica un determinado procesamiento para reducirlos y obtener la información de interés
Tomando el ejemplo descrito en el documento de Google, imaginad que quereis contar el número de veces que aparecen las palabras en un determinado documento. Expresado en pseudo-código el ejemplo tendría mas o menos de la siguiente forma:


En la primera fase (Map) se mapearia cada palabra al valor 1. En la segunda fase (Reduce) por cada palabra se agregarán sucesivamente los valores a un contador. Como resultado tendremos el conteo requerido. Algunos pensareis --- ¡qué tontería! podría haberlo calculado facilmente con un pequeño script secuencial. De acuerdo, si el documento es pequeño es una opción valida para resolver el problema. Imaginad ahora que en lugar de un documento quieres contar las ocurrencias en un libro, o en la colección de libros de una gran biblioteca. El problema se complica y la solución no es alcanzable si no cambiamos el paradigma de programación y paralelizamos el problema. Eso es lo que hace Hadoop:


Hadoop, y el conjunto de programas anexos, nos ayudan a trabajar de forma paralela. Haciendo uso de HDFS, un sistema de ficheros distribuido que permite alojar grandes cantidades de datos bajo hardware económico. La idea es conseguir potencia a base de unir nodos, equipos de prestaciones normales y económicos. Si un nodo se estropea es facilmente reemplazable por otro. Si necesitamos mas potencia solo necesitaremos añadir nodos al cluster creciendo de forma prácticamente lineal las capacidades disponibles. Interesante, ¿no?

Pero Hadoop y sus aplicaciones anexas no son demasiado user friendly. Si a eso unimos que para el trabajo necesitaremos desplegar los aplicativos en multiples nodos, controlar su estado, etc, la tarea se vuelve mas y mas compleja. No nos olvidemos que nuestro objetivo es procesar la información para obtener datos relevantes no el cluster en si mismo (el cluster es solo la herramienta). Para eso está Ambari: simplifica el despliegue de estos aplicativos, monitoriza su estado y proporciona herramientas para controlar el correcto funcionamiento tanto del cluster como de los trabajos desplegados, todo desde un entorno web muy agradable.

Para instalar Ambari lo mejor es seguir la guía (versión 1.2.2 en el momento de realizar este artículo) que los desarrolladores proporcionan en su web. Yo voy a comentar cómo he desplegado mi cluster Hadoop de pruebas y haré foco de atención en puntos importantes que hay que tener en cuenta para montar correctamente el cluster. Empecemos.

Ambari se despliega sobre REHL5/6, CentOS 5/6 y SLES 11. Importante es que solo admite versión x86_64 (64bits) como sistema operativo. Hace unos meses quise desplegar Ambari sobre equipos antiguos (HP Proliant G3) y me llevé un chasco al verificar con los desarrolladores del producto que al ser plataforma de 32bits no podía hacerlo.  Como lo mio es una prueba de concepto lo he desplegado sobre máquinas virtuales alojadas en mi PC: procesador Intel i7-2600K 3.4GHz (4 cores con HyperThreading) y 16GB de RAM. Pero podría hacerse igualmente sobre máquinas físicas o incluso sobre plataformas en la nube como AWS de Amazon.

Como sistema operativo base para los nodos del cluster he usado CentOS 6.4 minimal. Mi consejo es que, useis la distro que useis (dentro de las permitidas) instaleis una version mínima para reducir los requisitos de paquetes instalados. No os preocupeis porque Ambari, cuando lo necesite, instalará los paquetes que sean necesarios. Configuré 6 nodos con las siguientes características:
  • master-node: El nodo maestro. Donde instalaré el servidor de Ambari y las aplicaciones principales. 4GB de RAM y 2 cores. 7GB para disco de sistema (/) y 20GB para disco de cluster (/cluster)
  • backup-node: El nodo secundario. Donde se instalarán las aplicaciones maestras secundarias. 4GB de RAM y 1 core. 5GB para disco de sistema (/) y 20GB para disco de cluster (/cluster)
  • node02: Nodo cliente. 2GB de RAM y 1 core. 5GB para disco de sistema (/) y 20GB para disco de cluster (/cluster)
  • node03: Nodo cliente. 2GB de RAM y 1 core. 5GB para disco de sistema (/) y 20GB para disco de cluster (/cluster)
  • node04: Nodo cliente. 2GB de RAM y 1 core. 5GB para disco de sistema (/) y 20GB para disco de cluster (/cluster)
  • node05: Nodo cliente. 2GB de RAM y 1 core. 5GB para disco de sistema (/) y 20GB para disco de cluster (/cluster)
Mi consejo es que instaleis primero un CentOS base, casi sin nada, y una vez listo, haciendo uso de la utilidad de clonación de MV de VMWare, crear el resto. El resultado final en la consola de VMWare es el siguiente:



Paso previo a instalar y MUY IMPORTANTE es que los nodos deben verse entre sí. Para ello la resolución de nombres debe funcionar correctamente. Si no tienes un DNS donde dar de alta a los nodos del cluster una solución eficaz es meter la resolución de nombres en cada fichero '/etc/hosts' y asegurar que el hostname de cada nodo corresponde exactamente con dicha resolución:


Si lo anterior no está puesto correctamente fallará la fase de detección de nodos del cluster. Bien, ya tenemos todo listo para empezar. Lanzamos desde la interfaz web de administración de Ambari la configuración del nuevo cluster: establecer nombre, incluir los nombres de los nodos que lo forman (los nombres añadidos en el fichero de hosts). Listo, ahora deberemos seleccionar los aplicativos que queremos desplegar en nuestro cluster Hadoop:


El único que es obligatorio es el sistema de ficheros de cluster HDFS. Mi recomendación es que los añadas todos (no ocupan demasiado espacio y siempre puedes detenerlos después si no vas a hacer uso de ellos). Una vez elegidos los servicios a incluir, deberemos distribuirlos entre los nodos del cluster:


Yo he distribuido los servicios mas o menos para que todos los principales estén en el nodo maestro y backup. Seguramente haya una mejor distribución pero como mi objetivo sobre todo es evaluarlo no me preocupé demasiado en cómo distribuirlos. Ambari si precisa que algún servicio esté en varios nodos ya se preocupa de que así sea. Una vez distribuidos, proseguimos con la instalación.

Esta parte es delicada ya que, según como hayamos distribuido los servicios, Ambari tendrá que instalar unos u otros paquetes en los diferentes nodos del cluster. ¿Cómo hace este trabajo? La forma de interactuar de Ambari con los nodos del cluster usa dos caminos: SSH (si has seguido la guía de instalación oficial habrás tenido que configurar para que nodo maestro pueda acceder mediante este protocolo de forma directa, sin tener que proporcionar password alguna) y ambari-agent. En todos los nodos que formen parte del cluster se instalará el cliente de Ambari (via SSH) y, una vez provisionado, este será el método de comunicación. El cliente no es mas que una customizada adaptación de puppet. El nodo maestro, haciendo uso de los manifiestos (manifest), traslada configuraciones de un nodo del cluster a otro asegurando la coherencia en todo momento.

Como decía, esta parte es delicada ya que puede requerir instalar muchos paquetes en los diferentes nodos. A mi me dio error y revisando los nodos me percaté que no es que hubiera fallado la instalación, es que en varios nodos aun se estaban instalando muchos paquetes habiéndose llegado a una situación de timeout por el trabajo que ello requiere. ambari-agent recibe el manifiesto desde el nodo maestro, empieza a instalar paquetes (que requieren hacer uso de Internet via yum en muchas ocasiones). Mi consejo es que mireis en cada nodo y aseguraos que no hay procesos pendientes. Es facil detectarlo mirando la lista de procesos. Vereis que ambari-agent está ejecutando procesos relacionados con la instalación de paquetes:


Cuando veáis que la actividad en los nodos ha cesado, pulsar el botón de reintento. Debe aparecer una ventana similar a esta mostrando el progreso de instalación de los servicios en los nodos:


Y finalmente, si todo va bien, llegaremos a un estado donde todos los servicios se han desplegado correctamente en los diferentes nodos del cluster:


Entramos ahora en la ventana de dashboard de Ambari:


Esta ventana nos muestra una imagen general de cómo se encuentra nuestro cluster: los servicios activos y gráficas de las principales métricas asociadas al estado de computación: carga, uso de CPU, memoria, etc. Si pulsamos sobre cualquier gráfica, nos abre una ventana que nos permite ver interactivamente el detalle de la misma:


Como puede apreciarse, se ofrecen formas simples, interactivas e intuitivas para conocer el estado de salud de nuestro cluster, monitorizando los diferentes servicios, y ofreciendo información precisa gracias a los agentes de control integrados en el cluster como Ganglia y Nagios. Todo ello de forma cómoda: si necesitas mas potencia basta con añadir nuevos nodos al cluster. Ambari gestionará la provisión automática para integrar los nuevos nodos dentro de los procesos de control y gestión del cluster:






En la pestaña de Jobs podremos revisar el estado de ejecución de los diferentes procesos lanzados en la plataforma:


Como hemos visto, Ambari puede facilitarnos la gestión de nuestro cluster Hadoop. Ahora que tenemos una plataforma adecuada para desplegar nuestros jobs paralelos es el momento de empezar a usarla para procesar esa información que nos ayude a obtener datos significativos y, en definitiva, nos permita tomar mejores decisiones para el desarrollo de nuestra empresa a futuro.

PD: Lectura recomendada: MapReduce Design Patterns (O'Reilly)

sábado, 27 de abril de 2013

Spotify: la ingeniería IT en el siglo XXI

Llevo un tiempo estudiando cómo diseñan el futuro de la IT y en especial la parte que afecta directamente a la ingeniería de sistemas. Recientemente me he centrado en el análisis de Spotify por ser una de las start-ups mas importantes del momento y que curiosamente no tiene su sede central en California sino en Europa, concretamente en Estocolmo. Antes de comentar su método de funcionamiento interno me gustaría hablar un poco de cómo funcionan las empresas tradicionales. Y creedme que las conozco bien porque llevo bastantes años trabajando en una de ellas.

En una empresa de IT tradicional existe una fuerte jerarquización. Internamente tenemos directores generales, directores de departamento, jefes de area, responsables de unidad, jefes de proyecto, técnicos, etc. La comunicación entre las diferentes partes de la empresa en la mayoría de los casos es de abajo a arriba. Unido a la alta jerarquización hace que la comunicación sea poco fluida y muy susceptible de sufrir ruidos en las retransmisiones. En los procesos de aprobaciones tambien se debe seguir esta estructura rígida y las fases pueden extenderse incluso fuera de la empresa implicando validaciones de aun mas alto nivel (Consejerías/Organismos). Como os podeis imaginar, este desarrollo hace que sea especialmente lento el tramite de cualquier solicitud. Es algo que diariamente SUFRO (en mayúsculas)  en los procesos de compras, por ejemplo. Pero pasa con muchos otros procedimientos. Esto convierte a la empresa en un dinosaurio con graves problemas de adaptación a los cambios y que se mueve a paso muy muy lento. El trabajo interno y responsabilidades suele estar diluido a nivel de Unidad. Esta unidad es responsable de proveer un determinado servicio (ya sea interno o externo). Cuando alguien necesita algo que provee otra unidad debe realizar una solicitud que impilar seguir el flujo interno de aprobaciones tedioso anteriormente comentado. En definitiva llegamos a un escenario en el que las solicitudes, y su gestión (aprobaciones, pasos de una jerarquia a otra, etc), consumen un tiempo significativo del trabajo, ya bien sea por la gestión directa o por lo tiempos que la solicitud se lleva en transito de un estado (unidad, o area) a otro. Esto unido a un extraño proteccionismo que algunas unidades/areas infieren sobre determinados elementos llevan a crear lo que yo llamo reinos de taifas donde el sultán aplica un estricto control al flujo de información y lo protege como si de un reino se tratara.

Una vez puestos en antecedentes veamos cómo se estructura la IT en una empresa actual como Spotify.


En Spotify no existe una jerarquización fuerte. Son conscientes que el mudo IT se mueve rápido, muy rápido, y la organización debe estar preparada para responder de forma eficaz a esos cambios. Además es una empresa que se encuentra actualmente en un periodo de fuerte expansión. No se pueden permitir el lujo de consumir tiempo en estructuras rígidas que, en muchas ocasiones, aportan poco o nada al desarrollo del producto que es el foco del negocio.

Con esta filosofía Spotify se organiza internamente en lo que ellos denominan squads (escuadrones). Estos escuadrones debe ser completamente autónomos, es decir, su trabajo no debe depender del que hagan otros. Incluso si entre varios escuadrones hay dependencias siempre existe una forma en la que un escuadrón pueda moverse independientemente. Esta estratégia en la definición del grupo es clave para asegurar la agilidad que requieren. Si un escuadrón necesita infraestructuras para probar un nuevo servicio, o hacer un desarrollo, la toman directamente de una plataforma de autoprovisión. En su filosofía está el hacer uso de metodologías Agile pensando en la mejor forma para resolver un problema y buscando simplicidad: pienso, hago una pequeña prueba, evalúo,  ajusto y si se adapta a lo que se requiere se incluye como solución en la empresa. Conceptos básicos que llevan en las ingenierías con mas solera (aeronautica, construcción) aplicándose con éxito hace tiempo.

Compartir la información es clave. No existen reinos de taifa, como en las empresas tradicionales, sino que toda la información está compartida para toda la empresa. Por ejemplo, el código que se genera está centralizado en un servidor GIT al que todo el mundo tiene acceso. Cualquiera puede aportar cambios a cualquier parte y esto asegura que el producto siempre se mueva hacia delante. Hacen uso de tecnologías de software libre siempre que es posible y casi no utilizan software propietario. Promueven el talento dentro de la empresa y la movilidad entre los escuadrones de forma que cada una de las personas pueda sentirse valioso y aplicar su conocimiento y experiencia en aquellas partes donde cree que es mas necesaria. Internamente promueven la realización de hackdays en los que la gente se relaciona y puede probar ideas un poco mas locas. Son conscientes que potenciar el talento y favorecer su desarrollo es clave para el éxito.

El cliente de Spotify es el producto core de la empresa. Para su desarrollo se divide éste en particiones de características del que luego uno, o varios escuadrones, desarrollarán:


Divide y vencerás, es la estrategia que siguen muchas de las grandes empresas hoy en día y es que para conseguir el éxito es imprescindible pensar a lo grande. Al igual que los escuadrones las particiones de características se hacen de forma que no existan dependencias entre ellas (o de existir que sean de bajo acoplamiento). Esto asegura que ante el fallo de una característica el resto funcionen con normalidad.

Esta filosofía de trabajo y forma de organización requiere que la provisión de infraestructuras sea muy ágil. En Spotify se organizan de forma que los escuadrones tengan mecanismos de autoprovisión disponibles bien en datacenter propios, cuando el servicio requiere una baja latencia y una alta confiabilidad, o externos tipo AWS. La decisión dependerá de los requisitos del servicio (criticidad, localización geográfica, etc). Muchos de estos tendrán como denominador común la necesidad de comunicación entre diferentes localizaciones y una capacidad de almacenamiento potencialmente alta. Hacer uso de tecnologías tipo ZeroMQ o Cassandra se tornan claves en el desarrollo de la característica. Cada escuadrón monitoriza los servicios de los que son responsables para poder detectar cuellos de botella y realizar nuevas provisiones, cuando sean requeridas. Spotify está trabajando en un mecanismo que permita la provisión automática (sin intervención humana) de infraestructuras cuando estas sean requeridas, pero por ahora esta tarea depende de los hackers:


En conclusión la cultura de Spotify se fundamente en:

  1. Mejora continua: incluyendo nuevas características  promoviendo el talento de los ingenieros dentro de los escuadrones, etc.
  2. Desarrollo interactivo: cada escuadrón es autonomo para desarrollar lo que crea adecuado, generalmente bajo el modelo de Demo and release.
  3. Simplicidad: Un concepto heredado de las ingenierías mas tradicionales reduciendo los problemas mediante aproximaciones de divide y vencerás y generando partes independientes que se integren entre sí.
  4. Confianza: en sus escuadrones lo que reduce, e incluso en algunos puntos elimina, las necesidades de jerarquias de aprobación.
  5. Liderazgo de servicio: En la que los gestores se encargan principalmente de potenciar el talento mas que en dictar soluciones, resolver problemas entre escuadrones que no puedan ser resueltos por ellos mismos (en escasas ocasiones) y el coaching de los ingenieros.
Bienvenidos a la IT del siglo XXI.

sábado, 23 de marzo de 2013

FSX

Microsoft Flight Simulator X, la última versión disponible del simulador de vuelo editado por la compañía de Redmond, es uno de los mejores simuladores jamas editados. Pero si pensamos que fue lanzado en 2006 tiene el importante lastre de no estar adaptado a las mejoras de las CPU/GPU(s) actuales. Para intentar sacar el máximo partido existen una serie de recomendaciones enfocadas principalmente a modificar parámetros del principal fichero de configuración, FSX.CFG. Aquí expondré el contenido del fichero FSX.CFG, las opciones de configuración en FSX y la configuración gráfica asociada a GPU, via NVidia Inspector: