Archivo

Archive for the ‘programación’ Category

Monitorización y “self-healing” de AutoScaler/LoadBalancer de Amazon AWS

octubre 14, 2013 3 comentarios

Aunque está cada vez más fiable y con menos fallas, al principio los fallos de sincronización del AutoScaler con el ElasticLoadBalancer eran bastante frecuentes. Aún así todavía pueden ocurrir errores de programas que ponen la CPU de un servidor al 100%, o que se cuelgue algún servicio, o que deje de responder y el LoadBalancer lo elimine de su lista pero aún así sigan ejecutándose y consumiendo vuestro dinero.

El AutoScaler también tiene otro problema derivado de la extrema simplicidad de las reglas (del CloudWatch) para escalar hacia arriba y hacia abajo, especialmente esta última. Supongamos que para minimizar los costes queréis mantener las instancias entre un 70 y 85% de uso de CPU (así lo tenemos en Menéame), para ello usareis las métricas agregadas del grupo del auto escalador, pero en éste no hay forma de indicar una regla que como:

Cuando la carga con una instancia menos sea menor al 70%, decrementar una instancia

Por ello, en 2009 implementé un programa que monitoriza la carga de cada instancia del grupo que implementa este tipo de reglas. Además este programa monitoriza que todas las instancias estén dentro del margen (entre 70 y 85% de CPU), si alguna se desvía mucho toma otras decisiones. Por ejemplo: si una está cercana al 100% y la diferencia con la media de carga es superior al 50%, asume que hay un fallo en esa instancia y la terminará. Lo mismo hará que para instancias que estén muy cercanas al 0% de CPU mientras las demás están bastante por encima (lo típico de instancias “descolgadas” del LoadBalancer, por ejemplo por fallo de hardware o de algún servicio.

La verdad es que además de ahorrarnos bastante dinero manteniendo a todas las instancias “saludables” y dentro de los márgenes de CPU, me quitó dolores de cabeza. Salvo catástrofes y cosas muy raras, no tenía que preocuparme para nada del estado de los servidores web.

Pero nunca liberé ese código, cuando lo programé (hace casi cuatro años) las librerías de Python y Perl estaban bastante mal documentadas, así que lo hice en PHP porque pude entender las clases muy rápidamente. Pero el código era infumable, y ni quería liberarlo. Ahora que las librerías de Python, las boto, tienen muy buena calidad, me decidí a portar el código a Python. Ya está funcionando, y ahora lo libero y explico brevemente (haced con el código lo que queráis).

Precondiciones

Tenéis que tener instalado el paquete boto. Está probado con la versión 2.14, podéis usar el que trae vuestra distribución si es al mínimo la versión 2, o bien instalar la última con el pip (pip install -U boto). Ya está, eso es suficiente, en principio no necesitáis nada más de software.

Lo que hay que hacer es poner la configuración con vuestras claves en el /etc/boto.cfg o ~/boto. En nuestro caso, que tenemos los servidores en Dublin, la configuración es la siguiente:

[Credentials]
aws_access_key_id = XXXXXXXXXXXXXXXXXX
aws_secret_access_key = YYYYYYYYYYYYYYYYYYY

[Boto]
ec2_region_name = eu-west-1
ec2_region_endpoint = ec2.eu-west-1.amazonaws.com
autoscale_region_name = eu-west-1
autoscale_endpoint = autoscaling.eu-west-1.amazonaws.com
elb_region_name = eu-west-1
cloudwatch_region_endpoint = monitoring.eu-west-1.amazonaws.com

El código

Consiste de tres ficheros Python, los dos primeros obligatorios para hacer los controles, el tercero es para visualizar información de las instancias:

ec2_watchdata.py: Define la clase WatchData que implementa los métodos para leer los datos de AWS, manipular datos y hla lógica de controles.

ec2_watch.py: Es el script que ejecuto desde el cron cada minuto y hace lo que he explicado antes. Intenté que la lógica quede muy sencilla, y se puede cambiar todo por argumentos en la línea de comandos (con -h sale una pequeña ayuda). Permite especificar el nombre del grupo del autoescalador, si se quiere que envíe un email de las “emergencias”, para cambiar los límites de CPU, y otra para que grabe los resultados en JSON en la base de datos de Menéame como “annotation” (usado para poder visualizar el estado vía web). Lo podéis ejecutar como queráis, incluso con la opción -d o –dry si sólo queréis ver qué es lo que va a hacer, yo lo tengo en el cron para que se ejecute cada minuto, que es lo que recomiendo:

* * * * * meneame/scripts/ec2_watch.py -g web -a -m gallir@gmail.com > $HOME/watch.log

ec_instances.py: Es un pequeño script (pero que lo usamos mucho) que también usa la clase WatchData, fudamentalmente para visualizar el estado de las instancias del grupo, y también permite cambiar manualmente el número de instancias deseadas (opción -i), o matar instancias (opción -k). La siguiente captura muestra varias ejecuciones de este script, con un par para cambiar el número de instancias deseadas:

ec2_instances.py

Opcional: Si miráis el código, cuando se indica la opción -a llama a la función store_annotation() en el fichero utils.py. Esta es la que guarda los datos en formato JSON en la base de datos de Menéame y que me permite controlar desde la web y mi móvil:

ec2_watch web

Ejemplos de fallos (provocados)

Primero hice que una instancia se ponga al 100% de CPU (con el comando “yes > /dev/null”), así simulaba el fallo de algún programa. ec2_watch lo detectó y primero incrementó el número de instancias de 2 a 3. Como es una “emergencia”, me avisó por email de lo que pasaba, y lo que hizo:

100% de CPU, incrementa una instancia

Minutos después esa instancia seguía al 100%, por lo que la mató:

100% CPU, la mata

La siguiente es otra prueba, pero a la inversa. Desconecté manualmente una instancia del LoadBalancer, así el uso de CPU se pondría casi a cero, lo detectó a los pocos minutos, la terminó y el autoescalador levantó otra instancia nueva (al no cambiar el número de instancias deseadas):

0% de CPU, mata la instancia

Fin

Espero que os sea útil. No aceptaré sugerencias, pero sí parches ;)

Detección de DoS y bloqueo automático de IPs con el LoadBalancer de Amazon AWS

septiembre 11, 2013 9 comentarios

En Menéame teníamos un problema no solucionado correctamente. Cada vez sufrimos más ataques DoS voluntarios e involuntarios (bots mal programados, como los de Dreamule) que en el mejor de los casos nos ocasionan gastos innecesarios (ancho de banda e instancias adicionales) y en el peor sobrecargan tanto que impiden el acceso normal a las páginas. A esto se suma un gran problema: las instancias webs (que están autoescaladas horizontalmente) están detrás del balanceador de carga de Amazon AWS (ELB, Elastic Load Balancer) y éste no permite gestionar, ni manual ni automáticamente, el bloqueo de direcciones IP.

Por ello había que buscar una solución que detecte los DoS a conexiones que se hacen a las diferentes instancias web, y que sea el propio software de Menéame que lo haga y rechace las conexiones lo más rápido posible, y consumiendo los mínimos recursos. Esto obligaba a que se registren en un sólo servidor todas las conexiones desde las diferentes instancias, se analice en él en “tiempo real” y se guarden los datos en la base de datos para que estén disponibles para todas las instancias. Éstas deberían ser capaces de rechazar esas conexiones consumiendo la cantidad mínima de recursos y ancho de banda (tanto en la de Internet, como a la base de datos, como para enviar los logs al servidor central).

Después de pensarlo durante meses, y de analizar decenas de alternativas, en unos pocos días se me ocurrió la solución “óptima”. Esto ocurrió después de un mes de vacaciones casi completamente desconectado. Es el valor que tiene el descanso, pero eso es otro tema.

Leer más…

Por qué el núcleo Windows NT es peor que Linux: problemas sociales y de incentivos

En el artículo “I Contribute to the Windows Kernel. We Are Slower Than Other Operating Systems. Here Is Why.” se transcribe el comentario (luego eliminado) de un anónimo que se identificó y aportó pruebas como programador de Microsoft. En el comentario explica su opinión de por qué el núcleo Windows NT (el que se usa en todos los siguientes, 2000,XP, Vista, 7 y 8). Más allá de las anécdotas, y de que es una visión parcial y subjetiva, es muy interesante lo que desvela. En pocas palabras, la carencia de calidad y eficiencia son más un problema social más que técnico:

  • Falta de incentivos, o incentivos equivocados.
  • Dar mayor importancia a cumplir los planes establecidos sin desviaciones que aceptar cambios no planificados para mejorar la calidad del producto.
  • La carencia de programadores con experiencia, o el exceso de programadores recién graduados.

Es muy interesante la lectura, desvela los problemas de gestionar y programar sistemas complejos. Cualquier economista explicaría que hay que establecer los incentivos adecuados, sobre todo en entornos como la programación donde se trata de desarrollar sistemas tan complejos que tienen más componentes que el avión más grande del mundo y tantas formas de interacción -muchas órdenes de magnitud superior a cualquier sistema de componentes físicos- que escapan a nuestra capacidad de comprensión.

Ese incapacidad cognitiva de siquiera conocer la magnitud de la complejidad hace que sea imposible hacer un diseño inicial que tenga en cuenta todas las interacciones y casos. Por ello es imposible asegurar que no haya bugs y, por supuesto, que el sistema desarrollado sea eficiente. Eso requiere, tal como ya lo contaba Brooks en los ’70, el “mantenimiento” de los programas, que consiste en la mayor parte del ciclo de vida del software. Ese mantenimiento no consiste sólo en arreglar problemas, también en mejorar el código (para controlar mejor la creciente complejidad) y la eficiencia.

En el núcleo Linux es un buen ejemplo en ese sentido: se usaron las ideas y principios de modularidad de Unix, es software libre con todo a la vista del público (el código, y las discusiones técnicas), la gestión de Linus Torvalds (y los responsables de módulos) han creado una comunidad muy meritocrática (talk is cheap, show me the code) donde el respeto a los clientes (desarrolladores de programas a nivel usuario) es prioritaria, revisión de pares, se debate con dureza cada propuesta y cambio, se critica duro al que presenta propuestas malas, pero también se reconoce y halaga al que consigue mejorar funcionalidades ya establecidas y maduras.

Esa es una de las principales diferencias que se extraen del artículo.

En Microsoft [presuntamente] no funciona así, los responsables de módulos tienen más razones para rechazar mejoras que para introducirlas,  los Project Managers no ven con buenos ojos que haya desvíos del plan de trabajo, los grupos de testing no quieren saber nada de volver a probar y adaptar unidades de verificación. Es decir, no hay incentivos para mejorar las funcionalidades existentes y que no sean prioritarias en la empresa. En consecuencia, la eficiencia de sistemas con modelos de desarrollo más similares a Linux acaban siendo superior, sobre todo en las áreas y funcionalidades ya maduras.

Otro de los problemas que se menciona es el abandono de los programadores senior y la contratación de nuevos que acaban de salir de la universidad. Estos no son capaces de valorar la complejidad del sistema, ni de conocer por qué fueron tomadas las decisiones técnicas anteriores.

Este último punto es interesante, sobre todo en un gremio -y en un país- donde se valora poco la experiencia de los programadores. Salvo las empresas punteras en desarrollo de software equiparan los [excelentes] salarios de los programadores con la de los gestores (no es nada raro que un programador senior de Google cobre 150.000€). Ocurre en muchos países, pero sobre todo en España, tener 40 años y seguir programando parece más un fracaso profesional que el éxito de un programador apasionado.

Tampoco es culpa de las “empresas” o el “mercado”, desde la propia universidad solemos transmitir el mensaje equivocado:

Un ingeniero informático no programa, dirige proyectos

Ese mantra lo oí muchas veces y los alumnos lo escuchan frecuentemente en clases. El error es múltiple, por un lado transmitimos la idea que un ingeniero graduado sabe todo lo necesario, que no hace falta experiencia en programación, y que programar es de pringaos.

Además de lo mejorable que es nuestra educación, y como últimamente me está apasionando el tema de gestión de desarrollo de software, del comentario me han quedado algunas cosas más claras:

  • Los planes y metodologías son herramientas, no un fin en sí mismo, como terminan de creerse sus responsables y evangelistas.
  • Se deben crear incentivos, no sólo monetarios, para motivar a que los programadores desarrollen mejoras para cualquier parte del sistema. Esto implica, entre otras cosas, descontar un porcentaje de los recursos disponibles para implementar nuevas funcionalidades y reservarlos para mejora de la “calidad global”.
  • Valorar debidamente a los programadores experimentados, que empieza por reconocer -sobre todo entre nosotros mismos- las carencias inevitables de un recién graduado, y la rápida evolución de la ciencia y tecnologías informáticas.
  • Debemos empezar a esforzarnos en formar a profesionales cuyo objetivo sean jubilarse como programadores, no sólo un camino intermedio para lograr mejores salarios en otros puestos de gestión o dirección.
  • Sobre todo, reconocer que tenemos problemas cognitivos para visualizar mental y adecuadamente la enorme complejidad de los grandes sistemas informáticos.

Lo que se aprende, o debería, en la carrera de informática

marzo 28, 2013 46 comentarios

En mi apunte anterior “Lo que demanda el mercado…” critiqué la obstinación de algunas autoridades universitarias, especialmente las de la mía, en su posicionamiento extremamente conservadora contra el GNU/Linux… y cómo el tiempo les ha quitado la razón (yo diría que debería haberles avergonzado). A pesar de los dos enlaces que puse en la posdata, muchos interpretaron que pensaba que la universidad debe enseñar GNU/Linux porque tiene más salida laboral. Otros opinaron (sobre todo en Twitter) sobre lo poco que se aprende en la universidad de las últimas tecnologías [de moda].

Hace cinco años escribí un apunte muy largo sobre este tema: Sintonizar universidades y empresas, pero ¿qué debe saber un ingeniero? (y hay más, de gente más importante y valiosa que yo, como ¿Qué deberíamos enseñar a los nuevos desarrolladores? de Bjarne Stroustrup), ahora intentaré ser muy breve para contestar a esos dos temas.

Leer más…

SpokenPic liberado

marzo 18, 2013 5 comentarios

Resumen para vagos: el código liberado de la app SpokenPic está en Github. Punto ;)

Hace unos días fue la presentación del Galaxy S4, entre otras cosas mostraron su “novedosa” y “exclusiva” aplicación para poner voz a las fotos, muy similar al SpokenPic (prometo que sonreía, no hay mejor halago que una gran multinacional tecnológica haga algo igual casi un año después, y que lo presenten en un gran cutre show como una “innovación”). Eso me hizo acordar que habíamos prometido liberar el código,  que estaba prácticamente abandonado.

7415952232_95b203182b_cEl SpokenPic fue un fracaso, sin paliativos[*]. Aunque tiene buenas críticas y estrellitas en Google Play, sólo tuvo 2.000 descargas, y ahora hay sólo 600 instalaciones activas. Aunque nos llevó dos meses de trabajo a tope (no sé cómo sobreviví haber pasado tantos días durmiendo sólo 4 horas, y dándome de hostias con el Java, el API de Android, y hasta la documentación oficial errónea de la cámara), hasta con lanzamiento grupal emocionado (foto de la derecha), lo cierto es que no caló, y que no tuvimos tiempo para mejorarlo, ni siquiera en las funcionalidades que teníamos previstas (como la de clips con múltiples fotos). Visto en retrospectiva, fue el desánimo que nos desmotivó.

Leer más…

“Particionado funcional” económico en Amazon RDS… y cachea todo ¡estúpido!

marzo 17, 2013 6 comentarios

El miércoles pasado di una charla de cómo tenemos Menéame en Amazon AWS. Iba a explicar, al final de la charla, un truco de “particionado” [ver nota al final] económico, pero que no pudo ser: me tocó vivir en directo una saturación de la base de datos, producida por el nombramiento del nuevo Papa. Ahora explico cuál es ese “truco” de “particionado” económico y sencillo que sirve para ahorrar costes en RDS, y luego qué pasó y cómo solucioné la saturación de una de las bases de datos (de allí la frase “cachea todo ¡estúpido!”, el estúpido soy yo ;) ).

La base de datos principal de Menéame está en MySQL sobre Amazon RDS, con Multi AZ, lo que significa que tenemos failback y failover over automático y desantendido si el master falla. Da mucha comodidad, pero también tiene su coste: se paga el doble (el tamaño que tenemos es el large).

Leer más…

Un par de bellezas de algoritmos distribuidos que deberías implementar tú mismo

marzo 16, 2013 2 comentarios

Antes de irme a acostar pensé: “En vez de escribir quejas o de temas políticos-sociales, ¿qué tweet puedo dejar sobre temas de programación que entusiasme y sirva de algo a un programador”. Lo hice, pero luego pensé, son tweets a las 2:30 de la madrugada, los leerán sólo un par de insomnes frikis que no salen de marcha un viernes. Así que mejor lo dejo en mi blog (no pondré ningún enlace, todo está en Internet y es fácil encontrarlo con los nombres).

Este año me tocó dar Programación Concurrente y Distribuida, por lo que tuve que dedicar tiempo no sólo a aprender los algoritmos, sino a estudiarlos en profundidad para poder explicarlos, responder a todas las preguntas posibles, y además diseñar las prácticas en laboratorio. Así, de tanto estudiarlos llegó un momento que dije ¡hostia, que guapo y simple es!. Me pasó con el algoritmo de Chandy-Lamport para “snapshots” de sistemas distribuidos.

El estado de un sistema distribuido en un momento dado es imposible de obtener, ni tiene sentido. Pero sí que tiene encontrar un “estado consistente”. Este estado se refiere a qué mensajes se enviaron desde cada nodo (u ordenador), y qué mensajes estaban en tránsito en cada arista (o canal de comunicación). Es lo que hace el algoritmo de Chandy-Lamport. Si estás flojo en algoritmos distribuidos, o no recuerdas, o piensas que es muy complicado, te recomiendo que lo implementes. Es una “belleza”, en muchos sentidos. Pero mejor que lo saborees tú mismo ;)

Alerta

Implementar y probar algoritmos distribuidos en un único ordenador suele ser un coñazo. Hay muchos sistemas, pero hay que aprenderlos. Yo encontré que lo mejor es un sistema de paso de mensajes distribuidos, pero usándolo desde un único ordenador. Creo que no hay sistema de mensajes más simple, y con librerías para casi todos los lenguajes, que el Beanstalkd. Te lo recomiendo. De paso aprendes los conceptos básicos de estos sistemas, si es que no lo sabes. Recomendación: que cada nodo tenga un canal (o tubería en terminología beanstalkd) para recibir mensajes hacia él, es lo más simple, y simula perfectamente un sistema distribuido (cada nodo puede ser un proceso, o un hilo, tanto monta, siempre que las variables de los algoritmos no sean compartidas).

Quizás es recomendable implementar antes el algoritmo de “terminación distribuida” de Dijkstra-Scholten. Se usa la misma estructura de procesos y colas de mensajes, es más sencillo de entender (creo), y también es un algoritmo guapo.

Si implementas esto, y los entiendes, será como andar en bicicleta, no te olvidarás más. Y te gustará más la informática ;)

Categorías:píldoras, pijadas, programación Etiquetas:
Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 476 seguidores