Top Fakapov Cyan



Bueno para todos! 

Mi nombre es Nikita, soy líder del equipo de ingenieros cian. Una de mis responsabilidades en la empresa es reducir a cero la cantidad de incidentes relacionados con la infraestructura en el producto.
Lo que se discutirá más adelante nos ha traído mucho dolor, y el propósito de este artículo es evitar que otras personas repitan nuestros errores o al menos minimizar su impacto. 

Preámbulo


Érase una vez, cuando Cyan consistía en monolitos, y aún no había indicios de microservicios, medimos la disponibilidad del recurso verificando 3-5 páginas. 

Respuesta: todo está bien, no responda durante mucho tiempo, alerta. Las personas decidieron en las reuniones cuánto tiempo no deberían trabajar para que esto se considere un incidente. Un equipo de ingenieros siempre ha estado involucrado en la investigación del incidente. Cuando se completó la investigación, escribieron una autopsia, una especie de informe a la oficina de correos en el formato: qué fue, cuánto tiempo, qué se hizo en el momento, qué se hará en el futuro. 

Las páginas principales del sitio, o tal como lo entendemos, han roto el fondo

 
Para comprender de alguna manera la prioridad del error, resaltamos las páginas más críticas del sitio para la funcionalidad del negocio. Según ellos, consideramos el número de solicitudes y tiempos de espera exitosos / no exitosos. Entonces medimos el tiempo de actividad. 

Supongamos que descubrimos que hay varias secciones súper importantes del sitio responsables del servicio principal: búsqueda y envío de anuncios. Si el número de solicitudes que fallaron es mayor al 1%, este es un incidente crítico. Si dentro de los 15 minutos en horario estelar el porcentaje de errores supera el 0.1%, entonces esto también se considera un incidente crítico. Estos criterios cubren la mayoría de los incidentes, el resto está más allá del alcance de este artículo.



Los mejores incidentes cian


Entonces, precisamente aprendimos a determinar el hecho de que ocurrió el incidente. 

Ahora cada incidente en nuestro país se describe en detalle y se refleja en la epopeya de Jira. Por cierto: para esto comenzamos un proyecto separado, llamado FALLO, solo se pueden crear épicas en él. 

Si acumula todos los fracasos en los últimos años, entonces los líderes son: 

  • incidentes relacionados con mssql;
  • incidentes causados ​​por factores externos;
  • errores de administrador

Detengámonos con más detalle en los errores de los administradores, así como en algunos otros errores interesantes.

Quinto lugar - "Poner orden en el DNS"


Era un martes lluvioso. Decidimos limpiar el clúster de DNS. 

Quería transferir los servidores dns internos de bind a powerdns, destacando servidores completamente separados para él, donde no hay nada más que dns. 

Colocamos un servidor dns en cada ubicación de nuestros DC, y llegó el momento de mover las zonas de bind a powerdns y cambiar la infraestructura a nuevos servidores. 

En el momento álgido del movimiento, de todos los servidores que se indicaron en el enlace de almacenamiento en caché local en todos los servidores, solo había uno que estaba en el centro de datos en San Petersburgo. Este DC fue inicialmente declarado como no crítico para nosotros, pero de repente se convirtió en un único punto de falla.
Justo durante ese período de reubicación, el canal entre Moscú y San Petersburgo cayó. De hecho, nos quedamos sin DNS durante cinco minutos y nos levantamos cuando el proveedor solucionó los problemas. 

Conclusiones:

si antes descuidamos los factores externos durante la preparación para el trabajo, ahora también se incluyen en la lista de lo que nos estamos preparando. Y ahora nos esforzamos por asegurarnos de que todos los componentes estén reservados n-2, y durante la duración del trabajo podemos reducir este nivel a n-1.

  • Al elaborar un plan de acción, marque de antemano los puntos donde puede caer el servicio y piense en el escenario en el que todo fue "peor que en ninguna parte".
  • Distribuya servidores DNS internos por diferentes geolocalizaciones / centros de datos / bastidores / interruptores / entradas.
  • En cada servidor, coloque un servidor dns de almacenamiento en caché local, que redirige las solicitudes a los servidores dns principales y, si no está disponible, responderá desde la memoria caché. 

Cuarto lugar: "Limpiar Nginx"


Un buen día, nuestro equipo decidió que "era suficiente para soportarlo", y comenzó el proceso de refactorización de las configuraciones de nginx. El objetivo principal es llevar las configuraciones a una estructura intuitiva. Anteriormente, todo estaba "históricamente establecido" y no había lógica en sí misma. Ahora cada nombre_servidor se ha extraído del archivo con el mismo nombre y se han distribuido todas las configuraciones en carpetas. Por cierto, la configuración contiene 253949 líneas o 7836520 caracteres y ocupa casi 7 megabytes. Estructura de nivel superior: 

Estructura Nginx
├── access
│   ├── allow.list
...
│   └── whitelist.conf
├── geobase
│   ├── exclude.conf
...
│   └── geo_ip_to_region_id.conf
├── geodb
│   ├── GeoIP.dat
│   ├── GeoIP2-Country.mmdb
│   └── GeoLiteCity.dat
├── inc
│   ├── error.inc
...
│   └── proxy.inc
├── lists.d
│   ├── bot.conf
...
│   ├── dynamic
│   └── geo.conf
├── lua
│   ├── cookie.lua
│   ├── log
│   │   └── log.lua
│   ├── logics
│   │   ├── include.lua
│   │   ├── ...
│   │   └── utils.lua
│   └── prom
│       ├── stats.lua
│       └── stats_prometheus.lua
├── map.d
│   ├── access.conf
│   ├── .. 
│   └── zones.conf
├── nginx.conf
├── robots.txt
├── server.d
│   ├── cian.ru
│   │   ├── cian.ru.conf
│   │   ├── ...
│   │   └── my.cian.ru.conf
├── service.d
│   ├── ...
│   └── status.conf
└── upstream.d
    ├── cian-mcs.conf
    ├── ...
    └── wafserver.conf


Se volvió mucho mejor, pero en el proceso de renombrar y distribuir configuraciones, algunos de ellos tenían la extensión incorrecta y no entraban en la directiva include * .conf. Como resultado, parte de los hosts dejó de estar disponible y devolvió 301 al principal. Debido al hecho de que el código de respuesta no era 5xx / 4xx, esto no se notó de inmediato, sino solo por la mañana. Después de eso, comenzamos a escribir pruebas para probar componentes de infraestructura.

Recomendaciones: 

  • Estructura correctamente las configuraciones (no solo nginx) y piensa en la estructura en una etapa temprana del proyecto. Por lo tanto, los hará más comprensibles para el equipo, lo que a su vez reducirá el TTM.
  • Para algunos componentes de infraestructura, escriba pruebas. Por ejemplo: comprobar que todas las claves server_names devuelven el estado correcto, + cuerpo de respuesta. Será suficiente tener a mano solo unos pocos scripts que verifican las funciones básicas del componente para que no recuerdes frenéticamente a las 3 a.m. qué más hay que verificar. 

Tercer lugar - "Lugar que terminó repentinamente en Cassandra"


Los datos crecían constantemente, y todo estaba bien hasta el momento en que la reparación de casos grandes comenzó a caer en el clúster Cassandra, porque la compactación no podía funcionar en ellos. 

En un día lluvioso, el racimo casi se convirtió en una calabaza, a saber:

  • los lugares permanecieron alrededor del 20% del grupo total;
  • es imposible agregar nodos por completo, porque la limpieza no funciona después de agregar un nodo debido a la falta de espacio en las particiones;
  • el rendimiento cae ligeramente, porque la compactación no funciona; 
  • El clúster está en modo de emergencia.



Salir: se agregaron otros 5 nodos sin limpieza, después de lo cual comenzaron a eliminarse sistemáticamente del clúster y volver a ingresarlos como nodos vacíos en los que terminaba el lugar. El tiempo pasó mucho más de lo que nos gustaría. Existía el riesgo de inaccesibilidad parcial o total del clúster. 

Recomendaciones:

  • Todos los servidores cassandra no deben ocupar más del 60% del espacio en cada partición. 
  • Deben cargarse no más del 50% de la CPU.
  • No obstruya la planificación de la capacidad y piense en ello para cada componente, en función de sus detalles.
  • Cuantos más nodos haya en el clúster, mejor. Los servidores que contienen una pequeña cantidad de datos se migran más rápido, y dicho clúster es más fácil de reanimar. 

Segundo lugar: "Los datos del almacenamiento de valores clave del cónsul han desaparecido"


Para el descubrimiento de servicios, nosotros, como muchos, usamos cónsul. Pero aquí, su valor clave también se usa para cálculos de monolitos azul-verdes. Almacena información sobre el flujo ascendente activo e inactivo, que cambia de lugar durante la implementación. Para esto, se escribió un servicio de implementación que interactuaba con KV. En algún momento, los datos de KV desaparecieron. Recuperado de la memoria, pero con una serie de errores. Como resultado, durante el cálculo, la carga en el flujo ascendente se distribuyó de manera desigual, y obtuvimos muchos errores 502 debido a la sobrecarga de los backends en la CPU. Como resultado, pasamos del cónsul KV a postgres, de donde no es tan fácil eliminarlos.  

Recomendaciones:

  • - . , ES — , , , action.destructive_requires_name: true.
  • . , ( ,  python), .

— « » 


En algún momento, notamos una distribución de carga desigual en el flujo ascendente nginx en los casos en que había más de 10 servidores en el back-end. Debido al hecho de que el round-robin envió solicitudes del 1 al último en sentido ascendente en orden, y cada recarga de nginx comenzó desde el principio, el primer flujo ascendente siempre tenía más solicitudes que el resto. Como resultado, trabajaron más lentamente y todo el sitio sufrió. Esto se hizo más notable a medida que aumentaba la cantidad de tráfico. Simplemente actualizar nginx para habilitar aleatorio no funcionó: debe rehacer un montón de código lua que no despegó en la versión 1.15 (en ese momento). Tuve que parchear nuestro nginx 1.14.2, introduciendo soporte aleatorio en él. Esto resolvió el problema. Este error gana la nominación de "capitán no obvio".

Conclusiones:

fue muy interesante y emocionante investigar este error). 

  • Configure el monitoreo de modo que ayude a encontrar tales fluctuaciones rápidamente. Por ejemplo, puede usar ELK para monitorear los rps en cada back-end de cada flujo ascendente, y monitorear su tiempo de respuesta desde el punto de vista de nginx. En este caso, nos ayudó a identificar el problema. 

Como resultado, la mayoría de las fallas podrían haberse evitado con un enfoque más escrupuloso de lo que está haciendo. Siempre debe recordar la Ley de Murphy:  cualquier cosa que pueda salir mal, saldrá mal, y construirá componentes basados ​​en ella. 

All Articles