Top fakapov cian

Top fakapov cian

Todo bien 

Mi nombre es Nikita, soy la líder del equipo de ingeniería de Cian. Una de mis responsabilidades en la empresa es reducir a cero el número de incidencias relacionadas con la infraestructura en producción.
Lo que se discutirá a continuación nos trajo 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

Hace mucho tiempo, cuando Cian estaba formado por monolitos y aún no había indicios de microservicios, medimos la disponibilidad de un recurso comprobando entre 3 y 5 páginas. 

Responden: todo está bien, si no responden durante mucho tiempo, alerta. El tiempo que tenían que estar de baja para que se considerara un incidente lo decidían las personas en las reuniones. Un equipo de ingenieros siempre estuvo involucrado en la investigación del incidente. Cuando terminó la investigación, escribieron una autopsia, una especie de informe por correo electrónico en el formato: qué pasó, cuánto duró, qué hicimos en ese momento, qué haremos en el futuro. 

Las páginas principales del sitio o cómo entendemos que hemos tocado fondo

 
Para comprender de alguna manera la prioridad del error, hemos identificado las páginas del sitio más críticas para la funcionalidad empresarial. Utilizándolos, contamos el número de solicitudes y tiempos de espera exitosos/fallidos. Así es como medimos el tiempo de actividad. 

Digamos que descubrimos que hay una serie de secciones muy importantes en el sitio que son responsables del servicio principal: buscar y enviar anuncios. Si el número de solicitudes que fallan supera el 1%, se trata de un incidente crítico. Si en 15 minutos durante el horario de máxima audiencia la tasa de error supera el 0,1%, esto también se considera un incidente crítico. Estos criterios cubren la mayoría de los incidentes; el resto está fuera del alcance de este artículo.

Top fakapov cian

Top mejores incidentes Cian

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

Ahora cada incidente se describe en detalle y se refleja en la epopeya de Jira. Por cierto: para esto comenzamos un proyecto separado, llamado FAIL; en él solo se pueden crear epopeyas. 

Si se recogen todos los fracasos de los últimos años, los líderes son: 

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

Consideremos con más detalle los errores de los administradores, así como algunos otros fallos interesantes.

Quinto lugar: "Poner las cosas en orden en el DNS"

Era un martes tormentoso. Decidimos restablecer el orden en el clúster DNS. 

Quería transferir los servidores DNS internos de bind a powerdns, asignando para esto servidores completamente separados, 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 zonas de bind a powerdns y cambiar la infraestructura a nuevos servidores. 

En medio de la mudanza, de todos los servidores que estaban especificados en enlaces de caché local en todos los servidores, solo quedaba uno, que estaba en el centro de datos en San Petersburgo. Inicialmente, este DC fue declarado no crítico para nosotros, pero de repente se convirtió en un punto único de falla.
Fue durante este período de reubicación cuando se cayó el canal entre Moscú y San Petersburgo. De hecho, nos quedamos sin DNS durante cinco minutos y volvimos a funcionar cuando el proveedor de alojamiento solucionó el problema. 

Conclusiones:

Si antes descuidábamos los factores externos durante la preparación para el trabajo, ahora también están incluidos en la lista de para qué nos estamos preparando. Y ahora nos esforzamos por garantizar que todos los componentes estén reservados n-2, y durante el trabajo podemos bajar este nivel a n-1.

  • Al elaborar un plan de acción, marque los puntos donde el servicio puede fallar y piense de antemano en un escenario en el que todo fue "de mal en peor".
  • Distribuya servidores DNS internos en diferentes geolocalizaciones/centros de datos/racks/switches/entradas.
  • En cada servidor, instale un servidor DNS de almacenamiento en caché local, que redirige las solicitudes a los servidores DNS principales y, si no está disponible, responderá desde el caché. 

Cuarto lugar: "Poner las cosas en orden en Nginx"

Un buen día, nuestro equipo decidió que "ya hemos tenido suficiente de esto" 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 tenía ninguna lógica. Ahora cada nombre_servidor se ha movido a un archivo con el mismo nombre y todas las configuraciones se han distribuido en carpetas. Por cierto, la configuración contiene 253949 líneas o 7836520 caracteres y ocupa casi 7 megabytes. Nivel superior de estructura: 

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 cambiar el nombre y distribuir las configuraciones, algunas de ellas tenían la extensión incorrecta y no estaban incluidas en la directiva include *.conf. Como resultado, algunos hosts dejaron de estar disponibles y devolvieron el 301 a la página principal. Debido a que el código de respuesta no era 5xx/4xx, esto no se detectó inmediatamente, sino sólo por la mañana. Después de eso, comenzamos a escribir pruebas para verificar los componentes de la infraestructura.

Conclusiones: 

  • Estructura tus configuraciones correctamente (no solo nginx) y piensa en la estructura en una etapa temprana del proyecto. De esta manera los harás más comprensibles para el equipo, lo que a su vez reducirá el TTM.
  • Escribir pruebas para algunos componentes de la infraestructura. Por ejemplo: verificar que todos los nombres_servidor clave proporcionen el estado correcto + cuerpo de respuesta. Bastará con tener a mano algunos scripts que verifiquen las funciones básicas del componente, para no recordar frenéticamente a las 3 a.m. qué más hay que verificar. 

Tercer lugar: "De repente me quedé sin espacio en Cassandra"

Los datos crecieron constantemente y todo estuvo bien hasta el momento en que la reparación de grandes espacios de cajas en el clúster Cassandra comenzó a fallar, porque la compactación no podía funcionar en ellos. 

Un día de tormenta el racimo casi se convirtió en calabaza, a saber:

  • quedaba alrededor del 20% del espacio total en el grupo;
  • Es imposible agregar nodos por completo, porque la limpieza no se realiza después de agregar un nodo debido a la falta de espacio en las particiones;
  • la productividad cae gradualmente porque la compactación no funciona; 
  • El clúster está en modo de emergencia.

Top fakapov cian

Salir: agregamos 5 nodos más sin limpieza, después de lo cual comenzamos a eliminarlos sistemáticamente del clúster y a reingresarlos, como nodos vacíos que se habían quedado sin espacio. Se dedicó mucho más tiempo del que nos gustaría. Existía el riesgo de indisponibilidad parcial o total del clúster. 

Conclusiones:

  • En todos los servidores Cassandra, no se debe ocupar más del 60% del espacio en cada partición. 
  • Deben cargarse a no más del 50% de la CPU.
  • No debe olvidarse de la planificación de la capacidad y debe pensarla detenidamente para cada componente, en función de sus características específicas.
  • Cuantos más nodos haya en el clúster, mejor. Los servidores que contienen una pequeña cantidad de datos se sobrecargan más rápido y un clúster de este tipo es más fácil de reactivar. 

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

Para el descubrimiento de servicios, nosotros, como muchos, utilizamos cónsul. Pero también usamos su valor-clave para el diseño azul-verde del monolito. Almacena información sobre aguas arriba activas e inactivas, que cambian de lugar durante la implementación. Para ello, se escribió un servicio de implementación que interactuaba con KV. En algún momento, los datos de KV desaparecieron. Restaurado desde la memoria, pero con varios errores. Como resultado, durante la carga, la carga en las fuentes ascendentes se distribuyó de manera desigual y recibimos muchos errores 502 debido a que los backends estaban sobrecargados en la CPU. Como resultado, pasamos del cónsul KV a postgres, desde donde ya no es tan fácil eliminarlos.  

Conclusiones:

  • Los servicios sin ninguna autorización no deben contener datos críticos para el funcionamiento del sitio. Por ejemplo, si no tiene autorización en ES, sería mejor denegar el acceso a nivel de red desde cualquier lugar donde no sea necesario, dejar solo los necesarios y también configurar action.destructivo_requires_name: verdadero.
  • Practique su mecanismo de respaldo y recuperación con anticipación. Por ejemplo, cree un script con anticipación (por ejemplo, en Python) que pueda realizar copias de seguridad y restaurar.

Primer lugar: "Capitán Unobvious" 

En algún momento, notamos una distribución desigual de la carga en los flujos ascendentes de nginx en los casos en que había más de 10 servidores en el backend. Debido al hecho de que el round-robin enviaba solicitudes desde el 1.º al último upstream en orden, y cada recarga de nginx comenzaba de nuevo, los primeros upstreams siempre recibían más solicitudes que el resto. Como resultado, trabajaban más lento y todo el sitio sufría. Esto se hizo cada vez más notorio a medida que aumentaba la cantidad de tráfico. Simplemente actualizar nginx para habilitar el modo aleatorio no funcionó; necesitamos rehacer un montón de código lua que no despegó en la versión 1.15 (en ese momento). Tuvimos que parchear nuestro nginx 1.14.2, introduciéndole soporte aleatorio. Esto resolvió el problema. Este error gana la categoría "Capitán No Obviedad".

Conclusiones:

Fue muy interesante y emocionante explorar este error). 

  • Organice su seguimiento para que le ayude a encontrar dichas fluctuaciones rápidamente. Por ejemplo, puede usar ELK para monitorear rps en cada backend de cada flujo ascendente y monitorear su tiempo de respuesta desde el punto de vista de nginx. En este caso, esto nos ayudó a identificar el problema. 

Como resultado, la mayoría de los fracasos podrían haberse evitado si se hubiera aplicado un enfoque más escrupuloso a lo que se estaba haciendo. Siempre debemos recordar la ley de Murphy: Cualquier cosa que pueda ir mal, irá mal, y construir componentes basados ​​en él. 

Fuente: habr.com

Añadir un comentario