Top fakapov cyan

Top fakapov cyan

Tout bien! 

Je m'appelle Nikita, je suis le chef d'équipe de l'équipe d'ingénierie Cian. L’une de mes responsabilités au sein de l’entreprise est de réduire à zéro le nombre d’incidents liés aux infrastructures en production.
Ce qui sera discuté ci-dessous nous a apporté beaucoup de douleur, et le but de cet article est d'empêcher d'autres personnes de répéter nos erreurs ou du moins de minimiser leur impact. 

Préambule

Il y a longtemps, lorsque Cian était constitué de monolithes et qu'il n'y avait encore aucune trace de microservices, nous mesurions la disponibilité d'une ressource en vérifiant 3 à 5 pages. 

Ils répondent - tout va bien, s'ils ne répondent pas pendant longtemps - alerte. La durée pendant laquelle ils devaient s'absenter du travail pour que cela soit considéré comme un incident était décidée par les personnes lors des réunions. Une équipe d'ingénieurs a toujours été impliquée dans l'enquête sur l'incident. Une fois l'enquête terminée, ils ont rédigé une autopsie - une sorte de rapport par courrier électronique au format : ce qui s'est passé, combien de temps cela a duré, ce que nous avons fait sur le moment, ce que nous ferons dans le futur. 

Les pages principales du site ou comment nous comprenons que nous avons touché le fond

 
Afin de comprendre d'une manière ou d'une autre la priorité de l'erreur, nous avons identifié les pages du site les plus critiques pour les fonctionnalités commerciales. En les utilisant, nous comptons le nombre de requêtes réussies/infructueuses et les délais d'attente. C'est ainsi que nous mesurons la disponibilité. 

Disons que nous avons découvert qu'il existe un certain nombre de sections très importantes du site qui sont responsables du service principal : la recherche et la soumission de publicités. Si le nombre de requêtes qui échouent dépasse 1 %, il s’agit d’un incident critique. Si, dans les 15 minutes aux heures de grande écoute, le taux d'erreur dépasse 0,1 %, cela est également considéré comme un incident critique. Ces critères couvrent la plupart des incidents ; le reste dépasse le cadre de cet article.

Top fakapov cyan

Top meilleurs incidents Cian

Nous avons donc définitivement appris à déterminer le fait qu'un incident s'est produit. 

Désormais, chaque incident est décrit en détail et reflété dans l'épopée Jira. À propos : pour cela, nous avons lancé un projet distinct, appelé FAIL - seules des épopées peuvent y être créées. 

Si l’on rassemble tous les échecs des dernières années, les leaders sont : 

  • incidents liés à MSSQL ;
  • incidents causés par des facteurs externes ;
  • erreurs d'administration.

Examinons plus en détail les erreurs des administrateurs, ainsi que quelques autres échecs intéressants.

Cinquième place - « Mettre de l'ordre dans le DNS »

C'était un mardi orageux. Nous avons décidé de remettre de l'ordre dans le cluster DNS. 

Je voulais transférer les serveurs DNS internes de bind vers powerdns, en allouant pour cela des serveurs complètement séparés, où il n'y a rien d'autre que DNS. 

Nous avons placé un serveur DNS dans chaque emplacement de nos DC, et le moment est venu de déplacer les zones de bind vers powerdns et de basculer l'infrastructure vers de nouveaux serveurs. 

Au milieu du déménagement, parmi tous les serveurs spécifiés dans les liaisons de mise en cache locale sur tous les serveurs, il n'en restait qu'un, qui se trouvait dans le centre de données de Saint-Pétersbourg. Ce DC a été initialement déclaré non critique pour nous, mais est soudainement devenu un point de défaillance unique.
C’est durant cette période de délocalisation que le canal entre Moscou et Saint-Pétersbourg s’effondre. En fait, nous sommes restés sans DNS pendant cinq minutes et nous nous sommes relevés lorsque l'hébergeur a résolu le problème. 

Conclusions:

Si auparavant nous négligeions les facteurs externes lors de la préparation au travail, ils sont désormais également inclus dans la liste de ce à quoi nous nous préparons. Et maintenant nous nous efforçons de faire en sorte que tous les composants soient réservés n-2, et pendant les travaux nous pouvons abaisser ce niveau à n-1.

  • Lors de l'élaboration d'un plan d'action, marquez les points où le service pourrait échouer et réfléchissez à l'avance à un scénario où tout allait « de mal en pis ».
  • Distribuez les serveurs DNS internes sur différents géolocalisations/centres de données/racks/commutateurs/entrées.
  • Sur chaque serveur, installez un serveur DNS de mise en cache local, qui redirige les requêtes vers les serveurs DNS principaux, et s'il n'est pas disponible, il répondra depuis le cache. 

Quatrième place - «Mettre les choses en ordre dans Nginx»

Un beau jour, notre équipe a décidé que « nous en avions assez de ça » et le processus de refactorisation des configurations nginx a commencé. L'objectif principal est d'amener les configurations à une structure intuitive. Auparavant, tout était « historiquement établi » et ne comportait aucune logique. Désormais, chaque nom de serveur a été déplacé vers un fichier du même nom et toutes les configurations ont été distribuées dans des dossiers. À propos, la configuration contient 253949 7836520 lignes ou 7 XNUMX caractères et occupe près de XNUMX mégaoctets. Niveau supérieur de structure : 

Structure 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

C'est devenu bien meilleur, mais lors du processus de renommage et de distribution des configurations, certaines d'entre elles avaient la mauvaise extension et n'étaient pas incluses dans la directive include *.conf. En conséquence, certains hôtes sont devenus indisponibles et ont renvoyé 301 vers la page principale. Comme le code de réponse n'était pas 5xx/4xx, cela n'a pas été remarqué immédiatement, mais seulement le matin. Après cela, nous avons commencé à écrire des tests pour vérifier les composants de l'infrastructure.

Conclusions: 

  • Structurez correctement vos configurations (pas seulement nginx) et réfléchissez à la structure dès les premiers stades du projet. De cette façon, vous les rendrez plus compréhensibles pour l’équipe, ce qui réduira le TTM.
  • Écrivez des tests pour certains composants de l'infrastructure. Par exemple : vérifier que tous les noms de serveur clés donnent le bon statut + corps de réponse. Il suffira d'avoir juste quelques scripts sous la main qui vérifient les fonctions de base du composant, pour ne pas se rappeler frénétiquement à 3 heures du matin ce qui doit être vérifié d'autre. 

Troisième place - "J'ai soudainement manqué d'espace dans Cassandra"

Les données ont augmenté régulièrement et tout allait bien jusqu'au moment où la réparation de grands espaces de cas a commencé à échouer dans le cluster Cassandra, car le compactage ne pouvait pas fonctionner sur eux. 

Un jour d'orage, la grappe s'est presque transformée en citrouille, à savoir :

  • il restait environ 20 % de l'espace total dans le cluster ;
  • Il est impossible d'ajouter complètement des nœuds, car le nettoyage n'a pas lieu après l'ajout d'un nœud en raison du manque d'espace sur les partitions ;
  • la productivité diminue progressivement à mesure que le compactage ne fonctionne pas ; 
  • Le cluster est en mode urgence.

Top fakapov cyan

Quitter - nous avons ajouté 5 nœuds supplémentaires sans nettoyage, après quoi nous avons commencé à les supprimer systématiquement du cluster et à les réintégrer, comme des nœuds vides qui manquaient d'espace. Nous avons passé beaucoup plus de temps que nous le souhaiterions. Il existait un risque d'indisponibilité partielle ou totale du cluster. 

Conclusions:

  • Sur tous les serveurs Cassandra, pas plus de 60 % de l'espace sur chaque partition ne doit être occupé. 
  • Ils ne doivent pas être chargés à plus de 50 % du processeur.
  • Vous ne devez pas oublier la planification des capacités et y réfléchir pour chaque composant, en fonction de ses spécificités.
  • Plus il y a de nœuds dans le cluster, mieux c'est. Les serveurs contenant une petite quantité de données sont surchargés plus rapidement et un tel cluster est plus facile à relancer. 

Deuxième place - « Les données ont disparu du stockage clé-valeur du consul »

Pour la découverte de services, nous utilisons, comme beaucoup, consul. Mais nous utilisons également sa valeur-clé pour la disposition bleu-vert du monolithe. Il stocke des informations sur les amonts actifs et inactifs, qui changent de place pendant le déploiement. À cette fin, un service de déploiement a été écrit pour interagir avec KV. À un moment donné, les données de KV ont disparu. Restauré de mémoire, mais avec un certain nombre d'erreurs. En conséquence, lors du téléchargement, la charge sur les amonts a été inégalement répartie et nous avons reçu de nombreuses erreurs 502 en raison d'une surcharge des backends sur le CPU. En conséquence, nous sommes passés de consul KV à postgres, d'où il n'est plus si facile de les supprimer.  

Conclusions:

  • Les services sans aucune autorisation ne doivent pas contenir de données critiques au fonctionnement du site. Par exemple, si vous n'avez pas d'autorisation dans ES, il serait préférable de refuser l'accès au niveau du réseau partout où il n'est pas nécessaire, de ne laisser que ceux nécessaires et de définir également action.destructive_requires_name : true.
  • Pratiquez votre mécanisme de sauvegarde et de récupération à l’avance. Par exemple, créez à l'avance un script (par exemple, en python) capable de sauvegarder et de restaurer.

Première place - "Capitaine Unobvious" 

À un moment donné, nous avons remarqué une répartition inégale de la charge sur nginx en amont dans les cas où il y avait plus de 10 serveurs dans le backend. Étant donné que le round robin envoyait les requêtes du premier au dernier amont dans l'ordre et que chaque rechargement de nginx recommençait, les premiers amonts recevaient toujours plus de requêtes que les autres, ce qui les rendait plus lents et le site tout entier en souffrait. Cela est devenu de plus en plus visible à mesure que le volume de trafic augmentait. La simple mise à jour de nginx pour activer le mode aléatoire n'a pas fonctionné - nous devons refaire un tas de code Lua qui n'a pas décollé sur la version 1 (à ce moment-là). Nous avons dû patcher notre nginx 1.15, en y introduisant un support aléatoire. Cela a résolu le problème. Ce bug remporte la catégorie « Capitaine Non-Évidence ».

Conclusions:

C'était très intéressant et excitant d'explorer ce bug). 

  • Organisez votre surveillance de manière à ce qu'elle vous aide à détecter rapidement de telles fluctuations. Par exemple, vous pouvez utiliser ELK pour surveiller les rps sur chaque backend de chaque amont, surveiller leur temps de réponse du point de vue de nginx. Dans ce cas, cela nous a aidé à identifier le problème. 

En conséquence, la plupart des échecs auraient pu être évités avec une approche plus scrupuleuse de ce que vous faisiez. Il faut toujours se souvenir de la loi de Murphy : Tout ce qui peut mal tourner va mal tourner, et construire des composants basés sur celui-ci. 

Source: habr.com

Ajouter un commentaire