Cómo abordamos la caída del 6 de diciembre: pasos y soluciones
El 6 de diciembre ocurrió aquello que siempre tememos más. A las 13:23 detectamos problemas de capacidad en nuestra plataforma. Pronto resultó ser un problema grave que provocó una interrupción del servicio en muchos casos de uso. Lamentamos muchísimo haber permitido que esto sucediera. El tiempo de actividad y la fiabilidad son esenciales para el servicio que ofrecemos a nuestros clientes, por lo que trabajamos duro para que estas caídas sean lo menos frecuentes posible.

Sin embargo, en lugar de limitarnos a pedirte disculpas, queremos mostrarte lo que pasó entre bastidores y explicarte exactamente qué hicimos para resolver el problema lo más rápido posible.
Veamos un post-mortem detallado de los hechos.
Cronología de los hechos:
13:12 - Desplegamos los preparativos para migrar a una infraestructura basada en VPC. Esto incluía nuevas variables de entorno, que contenían configuraciones (como las subredes, los grupos de seguridad y los balanceadores de carga a los que añadir máquinas) específicas de la nueva VPC que estamos creando para cada región. Además, contenía cambios en GoInstance, una herramienta que escribimos en Go que gestiona el lanzamiento y la activación de máquinas, y también su retirada. El cambio no suponía la migración real a VPC, solo sentaba las bases, a la vez que mantenía la retrocompatibilidad con nuestra configuración actual sin VPC. Pasar a VPC nos permite mejorar la seguridad y aprovechar funciones exclusivas de AWS VPC, como tipos de instancia que ofrecen un mayor rendimiento a menor costo. El cambio se probó a fondo, tanto en local como en CI, pero, como las variables de entorno son distintas en producción que en dev o staging, una discrepancia pudo colarse sin que la viéramos.
13:23 - Llegó la primera alerta del pager, que indicaba que estábamos funcionando con menos instancias de uploader de las que deberíamos. El problema pasó desapercibido durante un tiempo porque cargar el nuevo entorno requiere procesos nuevos, y nuestro despliegue blue/green tardó un rato en reemplazar todos los procesos activos.
13:26 - Se convocó al Equipo de Respuesta ante Emergencias (ERT, por sus siglas en inglés).
13:32 - Se determinó que no podíamos lanzar máquinas nuevas debido a variables de entorno no válidas (discrepancia en los AMI-IDs y en los nombres de los Security Group). En algunos casos, GoInstance hacía referencia a valores inexistentes.
13:39 - A medida que las máquinas antiguas se retiraban por rotación o dejaban de ser accesibles, pasamos a funcionar con una sola máquina por región, que los autoscalers se negaban a retirar.
13:40 - El ERT corrigió la discrepancia y lanzó una compilación.
13:45 - Actualizamos Twitter y la página de estado.
13:49 - Se desplegó la compilación.
13:51 - Debido a un error no relacionado en la forma en que se compila GoInstance, resultó que los cambios no llegaron a producción.
13:55 - Desconcertado por esto, el equipo intentó revertir por completo la compilación defectuosa.
14:01 - Debido al mismo error, la reversión tampoco activó los cambios. Como se vio más tarde, si hubiéramos revertido a un punto más atrás en el tiempo, habría funcionado. Para explicarlo: hace unos meses, cuando migramos nuestro stack a Nix, introdujimos un error que solo recompilaba GoInstance si los cambios en él se agrupaban con cambios en otras partes de nuestro stack. Cuando intentamos parchear GoInstance, los cambios no se recogieron ni se desplegaron en producción. Al ERT le llevó un tiempo descubrir esto.
14:08 - El ERT parcheó el problema mencionado en nuestra configuración de Nix y pudimos volver a desplegar cambios. Lanzamos otra compilación y la desplegamos.
14:17 - Las flotas de la UE y de EE. UU. volvieron a estar en su capacidad deseada. Hace poco se añadió una parte importante del stack que aún no se había incorporado a nuestras AMI, por lo que los lanzamientos de máquinas fueron más lentos de lo habitual.
14:34 - Verificamos que todos los servicios estaban restablecidos, resolvimos todas las conversaciones con clientes relacionadas y actualizamos Twitter y la página de estado.
¿Qué medidas hemos tomado?
-
Se han creado nuevas AMI para todas las regiones y tipos de máquina, con lo que nuestros tiempos de lanzamiento de máquinas vuelven a acercarse a los tres minutos
-
Se corrigió el error en nuestra configuración de Nix, de modo que los cambios en GoInstance siempre se reflejen en nuestra compilación
-
Se corrigió la discrepancia en nuestro entorno
En conjunto, estas medidas permitieron que todo volviera a funcionar sin problemas. Sin embargo, somos conscientes de que, de cara al futuro, necesitaremos medidas adicionales para asegurarnos de que algo así no pueda volver a ocurrir nunca.
¿Qué otras medidas tomaremos?
Como parte de nuestro despliegue, hacemos que los autoscalers lancen máquinas; esto debería haber detenido el despliegue en seco antes de causar daños. Por desgracia, resulta que, debido a un problema no relacionado, esta prueba de preflight se ejecutó en el entorno anterior y no en el que estaba desplegado en ese momento. Vamos a solucionarlo para que esta prueba funcione de forma fiable en adelante y pueda detectar problemas como este.
Otras partes de nuestro conjunto de pruebas automatizadas también podrían haber detectado el entorno no válido, pero no lo comprobaban porque el entorno de staging difiere del entorno de producción. Actualmente estamos investigando si podemos hacer que nuestros entornos se parezcan más.
Lo sentimos
De nuevo, sentimos mucho las molestias que te hemos causado. Esperamos que este post-mortem haya servido para arrojar algo de luz sobre qué causó exactamente la caída y qué estamos haciendo para asegurarnos de que no vuelva a ocurrir. Si esta caída te afectó, por favor, ponte en contacto con nuestro equipo de soporte y trataremos de compensarlo.
