La historia del pájaro Dodo del género Phoenix. La gran caída de Dodo es

Cada año, el 21 de abril, recordamos la historia de la Gran Caída de Dodo IS en 2018. El pasado es un maestro cruel pero justo. Vale la pena recordarlo, repetir las lecciones, transmitir el conocimiento acumulado a las nuevas generaciones y tratar con gratitud en lo que nos hemos convertido. Debajo del corte, queremos contarte una historia sobre cómo fue y compartir conclusiones. Ni siquiera puedes desear esta situación al enemigo.




Gran historia de otoño


Día 1. El accidente que nos costó millones de rublos.


El sábado 21 de abril de 2018, el sistema Dodo IS cayó. Cayó muy mal. Durante varias horas, nuestros clientes no pudieron realizar un pedido ni a través del sitio ni a través de la aplicación móvil. La línea de llamadas al centro de llamadas ha crecido hasta tal estado que la voz automática del contestador automático dice: "Volveremos a llamar en 4 horas".



Ese día experimentamos una de las caídas más graves de Dodo IS. Lo peor fue que el día anterior lanzamos la primera campaña publicitaria de televisión federal con un presupuesto de 100 millones de rublos. Fue un gran evento para Dodo Pizza. El equipo de TI también estaba bien preparado para la campaña. Automatizamos y simplificamos la implementación; ahora, con la ayuda de un solo botón en TeamCity, podríamos implementar un monolito en 12 países. No hicimos todo lo posible y, por lo tanto, la jodimos.

La campaña publicitaria fue increíble. Recibimos entre 100 y 150 pedidos por minuto. Esa fue una buena noticia. La mala noticia: Dodo IS no pudo soportar tal carga y murió. Alcanzamos el límite de escala vertical y ya no pudimos procesar pedidos. El sistema estuvo inestable durante aproximadamente tres horas, recuperándose periódicamente, pero inmediatamente volvió a caer. Cada minuto de tiempo de inactividad nos costó decenas de miles de rublos, sin contar la pérdida de respeto de los clientes enojados. El equipo de desarrollo decepcionó a todos: clientes, socios, chicos de pizzerías y un centro de llamadas.



No tuvimos más remedio que arremangarnos y sentarnos para corregir la situación. Desde el domingo (22 de abril), trabajamos en modo difícil, no teníamos derecho a cometer un error.

El siguiente es nuestro resumen de experiencia sobre cómo encontrarnos en tal situación y cómo salir de ella más tarde. Amigos, no cometan nuestros errores.

Dos fallas que lanzaron el efecto dominó


Vale la pena comenzar con cómo comenzó todo y dónde nos equivocamos.



El sábado 21/04/2018, aproximadamente a las 5:00 p.m., notamos que el número de bloqueos en la base de datos comenzó a crecer, lo que es un presagio de problemas. Teníamos un runbook listo para resolver, ya que entendíamos de dónde venían estos bloqueos.

Todo salió mal después de que el runbook fallara dos veces. Durante un par de minutos, la base volvió a la normalidad, y luego nuevamente comenzó a ahogarse con las cerraduras. Por desgracia, la base de datos maestra rollback_on_timeout tenía 600 segundos, razón por la cual se acumulaban todos los bloqueos. Este es el primer archivo importante en esta historia. Una configuración simple podría salvarlo todo.

Luego hubo intentos de revivir el sistema de muchas maneras, ninguna de las cuales tuvo éxito. Hasta que nos dimos cuenta de que hay una diferencia en el esquema de recepción de pedidos en la aplicación móvil y en el nuevo sitio. Cortándolos a su vez, pudimos entender dónde están los agujeros en el antiguo esquema de toma de pedidos.

El sistema de aceptación de pedidos fue escrito hace mucho tiempo. En ese momento, ya se estaba procesando y se implementó en el nuevo sitio dodopizza.ru. No se usó en la aplicación móvil. Inicialmente, las razones para crear un nuevo esquema de pedidos estaban relacionadas con reglas puramente comerciales; los problemas de rendimiento ni siquiera estaban en la agenda. Este es el segundo archivo importante: no conocíamos los límites de nuestro sistema.

Día 2. Eliminación de accidentes


La respuesta del equipo fue muy reveladora. Nuestra estación de servicio escribió una publicación sobre Slack, y todos vinieron al día siguiente: el 22 de abril, el trabajo comenzó a las 8:30 de la mañana. Nadie necesitaba ser persuadido o pedirle que viniera en su día libre. Todos entendieron todo: lo que necesita ser apoyado, ayudado, con sus manos, con su cabeza, en pruebas, optimización de consultas, infraestructura. ¡Algunos incluso vinieron con toda la familia! Los muchachos de los equipos vecinos, no relacionados con TI, llegaron a la oficina con comida, y el centro de llamadas trajo fuerzas adicionales por si acaso. Todos los equipos unidos en un solo objetivo: ¡levantarse!



Una nueva recepción de la orden fue el objetivo principal el domingo 22 de abril. Entendimos que el pico de pedidos sería comparable al del sábado. Tuvimos el plazo más severo: a las 17 en punto caerá una nueva oleada de pedidos.

En este día, actuamos de acuerdo con el plan "para asegurarnos de que no se caiga", que elaboramos en la víspera del día 21 a última hora de la tarde, cuando ya habíamos elevado el sistema y entendido lo que había sucedido. El plan se dividió condicionalmente en 2 partes:

  1. Implementación del esquema con un nuevo orden en la aplicación móvil.
  2. Optimización del proceso de creación de pedidos.

Al implementar estas cosas, podemos estar seguros de que Dodo IS no caerá.

Determinamos el frente del trabajo y el trabajo.


La implementación del esquema con un nuevo orden en una aplicación móvil fue la máxima prioridad. No teníamos números exactos para todo el esquema, pero en algunas partes, el número y la calidad de las consultas a la base de datos, entendimos de manera experta que aumentaría la productividad. Un equipo de 15 personas trabajó en la tarea día tras día.

Aunque, de hecho, la introducción de un nuevo esquema de pedidos, comenzamos antes de la caída del 04.21., Pero no terminamos el trato. Todavía había errores activos y la tarea colgaba en un estado semiactivo.

El equipo dividió la regresión en partes: la regresión desde dos plataformas móviles, más la gestión de pizzerías. Pasamos mucho tiempo manualmente para preparar pizzerías de prueba, pero una separación clara ayudó a paralelizar la regresión manual.

Tan pronto como se introdujo algún cambio, se implementó inmediatamente en el entorno de preproducción y se probó al instante. El equipo siempre estaba en contacto entre ellos, simplemente se sentaban en una sala grande con lugares de reunión. Los muchachos de Nizhny Novgorod y Syktyvkar también estaban siempre en contacto. Si había un enchufe, decidió de inmediato.

Por lo general, presentamos nuevas funcionalidades gradualmente: 1 pizzería, 5 pizzerías, 10 pizzerías, 20 pizzerías, etc., a toda la red gradualmente. Esa vez necesitábamos actuar con más decisión. No tuvimos tiempo: a las 5 p.m., comenzó un nuevo pico. Simplemente no podíamos dejar de atraparlo.

Aproximadamente a las 15:00 la actualización se implementó en la mitad de la red (esto es aproximadamente 200 pizzerías). A las 15:30 nos aseguramos de que todo funcionaba bien y activamos toda la red. Alternar características, implementaciones rápidas, regresión dividida en partes y API fija ayudaron a hacer todo esto.

El resto del equipo se ocupó de diferentes opciones de optimización al crear un pedido. El nuevo esquema no era completamente nuevo, todavía usaba la parte heredada. Guardar direcciones, aplicar códigos promocionales, generar números de pedido: estas partes fueron y siguieron siendo comunes. Su optimización se redujo a reescribir las consultas SQL, a deshacerse de ellas en el código o a optimizar sus llamadas. Algo salió en modo asíncrono, algo que resultó ser llamado varias veces en lugar de uno.

El equipo de infraestructura se comprometió a asignar parte de los componentes a instancias separadas simplemente para no cruzar la carga. Nuestro principal componente problemático fue la fachada de Legacy, que fue a la base de Legacy. Todo el trabajo se dedicó a él, incluida la división de instancias.

Organiza el proceso


Por la mañana, tuvimos la única sincronización del día, nos dividimos en equipos y nos fuimos a trabajar.

Al principio, mantuvimos todo el registro de cambios y tareas directamente en Slack, porque al principio no había tantas tareas. Pero su número estaba creciendo, así que nos mudamos rápidamente a Trello. La integración configurada entre Slack y Trello notificó cualquier cambio de estado en el rompecabezas.

Además, era importante para nosotros ver todo el registro de cambios de producción. La versión electrónica estaba en Trello, la versión de respaldo estaba en la placa de infraestructura en forma de tarjetas. En caso de que algo saliera mal, necesitábamos averiguar rápidamente qué cambios revertir. La regresión completa fue solo para el esquema con un nuevo orden, el resto de los cambios se probaron de manera más leal.

Las tareas volaron a producción a una velocidad de bala. En total, actualizamos el sistema 15 veces ese día. Los chicos fueron desplegados en bancos de pruebas, uno por equipo. Desarrollo, verificación rápida, implementación en producción.

Además del proceso principal de CTO, Sasha Andronov constantemente se encontró con equipos con la pregunta "¿Cómo ayudar?". Esto ayudó a redistribuir los esfuerzos y no perder tiempo en el hecho de que alguien no pensó en pedir ayuda. Gestión de desarrollo semi-manual, un mínimo de distracciones y trabajo al límite.

Después de ese día, fue necesario salir con la sensación de que hicimos todo lo posible. Y aun más. Y lo hicimos! A las 15:30 se lanzó un nuevo esquema para recibir un pedido para una aplicación móvil en toda la red. Modo Hackathon, ¡menos de 20 implementaciones por producción por día!

La tarde del 22 de abril fue tranquila y clara. Ni caídas ni una sola pista es que el sistema puede ser malo.

Alrededor de las 10 p.m., nos reunimos nuevamente y delineamos un plan de acción semanal. Limitación, pruebas de rendimiento, orden asincrónico y mucho más. Fue un día largo y había largas semanas por delante.

Renacimiento


La semana del 23 de abril fue infernal. Después de eso, nos dijimos que habíamos hecho nuestro mejor 200% e hicimos todo lo posible.

Tuvimos que salvar Dodo IS y decidimos aplicar alguna analogía médica. En general, este es el primer caso real de usar una metáfora (como en el XP original), que realmente ayudó a comprender lo que estaba sucediendo:

  • Reanimación: cuando necesita salvar a un paciente que está muriendo.
  • Tratamiento: cuando hay síntomas, pero el paciente aún está vivo.




Resucitación


La primera etapa de la reanimación es el runbook estándar para restaurar el sistema en caso de falla de acuerdo con algunos parámetros. Una cosa ha caído, lo estamos haciendo, esa ha caído, lo estamos haciendo, y así sucesivamente. En el caso de un bloqueo, encontramos rápidamente el runbook deseado, todos se encuentran en GitHub y están estructurados por problemas.

La segunda etapa de la reanimación es la limitación de las órdenes. Adoptamos esta práctica de nuestras propias pizzerías. Cuando se descargan muchos pedidos en la pizzería, y entienden que no pueden cocinarlos rápidamente, se detienen en la parada durante 5 minutos. Solo para despejar la línea de pedido. Hicimos un esquema similar para Dodo IS. Decidimos que si se pone realmente mal, activaremos el límite general y les diremos a los clientes, dicen, 5 minutos y tomaremos su pedido. Desarrollamos esta medida por si acaso, pero como resultado, nunca la usamos. Inútil. Y bonito.

Tratamiento


Para comenzar el tratamiento, es necesario hacer un diagnóstico, por lo que nos centramos en las pruebas de rendimiento. Parte del equipo fue a recopilar un perfil de carga real de la producción usando GoReplay, parte del equipo centrado en pruebas sintéticas en el escenario.

Las pruebas sintéticas no reflejaron el perfil de carga real, pero dieron algunas bases para mejoras, mostraron algunas debilidades en el sistema. Por ejemplo, poco antes de eso, estábamos moviendo el conector MySQL de Oracle a uno nuevo . En la versión del conector había un error con las sesiones de agrupación, lo que condujo al hecho de que los servidores simplemente fueron al techo de la CPU y dejaron de atender las solicitudes. Reproducimos esto con pruebas de Stage, concebido y silenciosamente en producción. Hubo una docena de tales casos.

A medida que diagnostican e identifican las causas de los problemas, se corrigen puntualmente. Además, entendimos que nuestra forma ideal es la recepción asíncrona de un pedido. Comenzamos a trabajar para introducirlo en una aplicación móvil.

Semanas del infierno: organización del proceso


Un equipo de 40 personas trabajó en un solo gran objetivo: la estabilización del sistema. Todos los equipos trabajaron juntos. ¿No se que hacer? Ayuda a otros equipos. Centrarse en objetivos específicos ayudó a no ser rociado y a no participar en tonterías innecesarias para nosotros.



Tres veces al día había sincronización, un stand-up común, como en un scrum clásico. Para 40 personas. Solo dos veces en tres semanas (durante casi 90 sincronizaciones) no cumplimos 30 minutos. La sincronización más larga duró 57 minutos. Aunque generalmente tomaban 20-30 minutos.

El objetivo de las sincronizaciones: comprender dónde se necesita ayuda y cuándo llevaremos estas o esas tareas a producción. Los chicos se unieron en equipos de proyecto, si necesitaban la ayuda de la infraestructura, una persona vino allí, todos los problemas se resolvieron rápidamente, menos discusión era más importante.

Por las noches, para apoyar a los muchachos, nuestro laboratorio de I + D preparó comida para los desarrolladores durante la noche. Recetas de pizza locas, alitas de pollo, papas! ¡Eso fue increíblemente genial! Tal apoyo motivó a los muchachos tanto como fue posible.



Trabajar en un modo tan continuo era muy difícil. El miércoles 25 de abril, a eso de las 5 de la tarde, Oleg Blokhin, uno de nuestros desarrolladores, se acercó a CTO, que había estado pensando el sábado sin parar. Había fatiga inhumana en sus ojos: "Me fui a casa, no puedo soportarlo más". Dormió bien y al día siguiente fue abundante. Entonces puedes describir la condición general de muchos chicos.

El próximo sábado 28 de abril (fue un sábado de trabajo para todos en Rusia) fue más tranquilo. No pudimos cambiar nada, vimos el sistema, los chicos descansaron un poco del ritmo. Todo fue en silencio. La carga no era tan grande, pero lo era. Sobrevivieron sin problemas, y esto les dio la confianza de que íbamos por el camino correcto.

La segunda y tercera semana después de la caída ya estaban en un modo más tranquilo, el ritmo infernal desapareció hasta altas horas de la noche, pero el proceso general de la ley marcial se mantuvo.

Próximo día X: prueba de resistencia


¡Al día siguiente X fue el 9 de mayo! Alguien estaba sentado en casa y monitoreando el estado del sistema. Aquellos de nosotros que salimos a caminar llevamos computadoras portátiles con nosotros para estar completamente armados si algo salía mal. Sasha Andronov, nuestra estación de servicio, se acercó al pico de la tarde a una de las pizzerías, para que, en caso de problemas, vea todo con sus propios ojos.

Ese día recibimos 91500 pedidos en Rusia (en ese momento, el segundo resultado en la historia del Dodo). Ni siquiera había el menor indicio de un problema. ¡El 9 de mayo confirmó que estamos en el camino correcto! Centrarse en la estabilidad, el rendimiento, la calidad. El proceso de reestructuración nos esperaba aún más, pero esta es una historia completamente diferente.

Gran caída retro y 6 prácticas


En situaciones críticas, se desarrollan buenas prácticas que pueden y deben transferirse a un momento de silencio. Enfoque, ayuda entre equipos, despliegue rápido a producción sin esperar una regresión completa. Comenzamos con retro y luego desarrollamos el marco del proceso.



Los primeros dos días pasaron en una discusión de prácticas. No nos propusimos el objetivo de "poner una retrospectiva a las 2 en punto". Después de tal situación, estábamos listos para tomar el tiempo para desarrollar nuestras ideas y nuestro nuevo proceso en detalle. Todos participaron. Todos los que participaron en el trabajo de restauración de una forma u otra.



Como resultado, hubo 6 prácticas importantes de las que me gustaría hablar con más detalle.

  1. Top N . , . Product Owners , , , . . , . , , , . , . N – Lead Time .
  2. . . -, , . , , , . .
  3. . , « » . , . , , . , - . Dodo IS. .
  4. Pull Request. , Pull Request, - . . , , , , - . , . , . 15 .
  5. Performance- — . performance- . , . Performance- . baseline , PR . , .
  6. Performance . — . , , -, , , . . , .



1.

21.04.2018 – Dodo IS. ?


(Site Reliability Engineering): . , .

(Site Reliability Engineering, Product Owner Dodo IS): . , , .

auth’, . . , .

, () :



. , .

. , . . -. , , . - , , . , -, , .

. redis, . . - , . .

Dodo IS . . , . , , , , . , — .

. « ». « , » .

- ?


:

– . . . , . . .

:

. , . ( ), - . .

. :

  1. .
  2. .
  3. , .

?



:

, , , .

:

, , . , .

? ?



: , – .

:

  1. — . - - .

    , . 2018 , PerformanceLab, .
  2. , . Less-.
  3. . 2018 -, . , . - 2018 .
  4. async . , 21.04.2018 . , . async.
  5. . , SaveOrder async-await. , . : , LF, 20 . , . , . !

    , , , .

    , , . — -. .
  6. . , (, ). , . «» . nginx , - , .

    : innodb_lock_wait_timeout = 5; innodb_rollback_on_timeout = ON. . , , , , .

, ?


:

  1. , , , . , .
  2. , .
  3. , , , . – .

:

  1. .
  2. . , , -. .
  3. . , - , .

, ?


:

«» , «». , , . .

:

, . , , . .

2. , (Dodo IS Architect)
— , . , — .

, , . , (, , ) .

IT-. Dodo IS, . …

X , . . Dodo IS , , , . , , , . . 146%, . , Dodo IS ?

, . , , . , . , !

, . « »: 11- , , 2 . «» . 3-4 , . , . .

, , . . Dodo IS , « ». ! ( ).

, Dodo IS , . Dodo IS . « », , . ( ), loadtest, , .

All Articles