Top des erreurs de Tsiang

Top des erreurs de Tsiang

Bonjour à tous ! 

Je m'appelle Nikita, je suis le chef d'équipe des ingénieurs chez Cian. L'une de mes responsabilités dans l'entreprise est de réduire le nombre d'incidents liés à l'infrastructure en production à zéro.
Ce dont nous allons parler par la suite nous a causé beaucoup de douleurs, et l'objectif de cet article est d'éviter à d'autres de répéter nos erreurs ou tout au moins de minimiser leur impact. 

Préambule

Il était une fois, quand Cian n'était constitué que de monolithes, et qu'il n'y avait aucun indice sur les microservices, nous mesurions la disponibilité des ressources en vérifiant 3 à 5 pages. 

S'ils rĂ©pondent — tout va bien, s'ils ne rĂ©pondent pas pendant un long moment — alerte. Combien de temps ils doivent ĂȘtre hors service pour que cela soit considĂ©rĂ© comme un incident, cela Ă©tait dĂ©cidĂ© par des personnes lors de rĂ©unions. L'Ă©quipe d'ingĂ©nieurs participait toujours Ă  l'enquĂȘte sur l'incident. Lorsque l'enquĂȘte Ă©tait terminĂ©e, un post-mortem Ă©tait rĂ©digĂ© — un rapport adressĂ© par email sous la forme : ce qui s'est passĂ©, combien de temps cela a durĂ©, ce que nous avons fait sur le moment, ce que nous ferons Ă  l'avenir. 

Les pages principales du site ou comment nous savons que nous avons atteint un point critique

 
Pour pouvoir comprendre la prioritĂ© des erreurs, nous avons identifiĂ© les pages du site les plus critiques pour la fonctionnalitĂ© commerciale. Nous comptons le nombre de requĂȘtes rĂ©ussies/Ă©chouĂ©es et de timeouts sur ces pages. Ainsi, nous mesurons le temps de disponibilitĂ©. 

Supposons que nous avons dĂ©terminĂ© qu'il y a plusieurs sections super importantes du site qui sont responsables du service principal — la recherche et la soumission d'annonces. Si le nombre de requĂȘtes qui se terminent par une erreur dĂ©passe 1 %, c'est un incident critique. Si pendant 15 minutes durant les heures de pointe, le pourcentage d'erreurs dĂ©passe 0,1 %, cela est Ă©galement considĂ©rĂ© comme un incident critique. Ces critĂšres couvrent la plus grande partie des incidents, les autres dĂ©passent le cadre de cet article.

Top des erreurs de Tsiang

Top des incidents les plus marquants de Cian

Donc, nous avons certainement appris à définir le fait qu'un incident s'est produit. 

Maintenant, chaque incident est dĂ©taillĂ© et reflĂ©tĂ© dans une Ă©popĂ©e Jira. À propos : pour cela, nous avons créé un projet sĂ©parĂ©, que nous avons appelĂ© FAIL — oĂč l'on peut uniquement crĂ©er des Ă©popĂ©es. 

Si nous rassemblons tous les échecs des derniÚres années, nous constatons que les principaux sont : 

  • incidents liĂ©s Ă  mssql ;
  • incidents causĂ©s par des facteurs externes ;
  • erreurs d'administration.

Concentrons-nous plus en détail sur les erreurs des administrateurs, ainsi que sur quelques autres échecs intéressants.

CinquiĂšme place — « Mettre de l'ordre dans le DNS »

C'était un mardi pluvieux. Nous avons décidé de faire le ménage dans le cluster DNS. 

Nous avons voulu migrer nos serveurs DNS de BIND vers PowerDNS, en allouant des serveurs entiĂšrement dĂ©diĂ©s Ă  cela, oĂč il n'y a rien d'autre que des DNS. 

Nous avons installé un serveur DNS dans chaque emplacement de nos centres de données, et le moment est venu de migrer les zones de BIND vers PowerDNS et de passer notre infrastructure vers les nouveaux serveurs. 

Au beau milieu de la migration, tous serveurs, qui étaient indiqués dans les caches locaux de BIND sur tous les serveurs, il ne restait qu'un seul serveur, situé dans le centre de données de Saint-Pétersbourg. Ce DC avait initialement été déclaré non critique pour nous, mais il est soudainement devenu un point de défaillance unique.
Juste à ce moment-là, le lien entre Moscou et Saint-Pétersbourg est tombé. Nous avons été sans DNS pendant cinq minutes, et nous avons récupéré quand l'hébergeur les problÚmes ont été résolus. 

Conclusions :

Alors qu'auparavant, nous ne tenions pas compte des facteurs externes lors de la préparation des travaux, nous avons désormais inclus ces éléments dans notre liste de préparation. Nous visons désormais à avoir tous les composants redondés en n-2, et pendant la durée des travaux, nous pouvons réduire ce niveau à n-1.

  • Lors de l'Ă©laboration du plan d'actions, notez les points oĂč le service pourrait tomber, et planifiez des scĂ©narios oĂč tout pourrait aller "de mal en pis", Ă  l'avance.
  • RĂ©partissez les serveurs DNS internes dans diffĂ©rentes gĂ©olocalisations / centres de donnĂ©es / racks / commutateurs / entrĂ©es.
  • Sur chaque serveur, installez un serveur DNS de cache local qui redirige les requĂȘtes vers les serveurs DNS principaux, et en cas d'indisponibilitĂ©, rĂ©pondra Ă  partir du cache. 

QuatriĂšme point — «Mise en ordre dans Nginx»

Un beau jour, notre Ă©quipe a dĂ©cidĂ© que "ça suffit" et le processus de refactoring des configurations Nginx a commencĂ©. L'objectif principal Ă©tait de rendre les configurations intuitivement comprĂ©hensibles. Auparavant, tout Ă©tait "historique" et n'avait aucune logique. Maintenant, chaque server_name a Ă©tĂ© dĂ©placĂ© dans un fichier homonyme et toutes les configurations ont Ă©tĂ© rĂ©parties dans des dossiers. À propos — la configuration contient 253949 lignes ou 7836520 caractĂšres et fait presque 7 mĂ©gaoctets. Le niveau supĂ©rieur de la structure: 

Structure Nginx

├── accùs
│   ├── 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
...
│   ├── dynamique
│   └── 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 beaucoup mieux, mais au cours du renommage et de la réorganisation des configurations, certaines d'entre elles avaient une mauvaise extension et n'étaient pas incluses dans la directive include *.conf. En conséquence, certaines hÎtes sont devenus inaccessibles et ont renvoyé 301 vers l'accueil. Comme le code de réponse n'était pas 5xx/4xx, cela n'a pas été remarqué immédiatement, seulement au matin. AprÚs cela, nous avons commencé à écrire des tests pour vérifier les composants d'infrastructure.

Conclusions : 

  • Structurez correctement les configurations (pas seulement nginx) et pensez Ă  la structure dĂšs le dĂ©but du projet. Cela les rendra plus comprĂ©hensibles pour l'Ă©quipe, ce qui Ă  son tour rĂ©duira le TTM.
  • Pour certains composants d'infrastructure, Ă©crivez des tests. Par exemple : vĂ©rifiez que tous les server_name clĂ©s renvoient le bon statut, + le corps de la rĂ©ponse. Avoir simplement quelques scripts sous la main qui vĂ©rifient les fonctions principales du composant suffira, afin de ne pas se rappeler frĂ©nĂ©tiquement Ă  3 heures du matin ce qu'il faut encore vĂ©rifier. 

TroisiĂšme place — «Soudain, plus d'espace dans Cassandra»

Les donnĂ©es ont progressivement augmentĂ©, et tout allait bien jusqu'au moment oĂč les rĂ©parations de grands keyspaces dans le cluster Cassandra ont commencĂ© Ă  Ă©chouer, car la compaction ne pouvait pas ĂȘtre effectuĂ©e. 

Un jour de tempĂȘte, le cluster s'est presque transformĂ© en citrouille, Ă  savoir :

  • il restait environ 20 % en total dans le cluster ;
  • il n'est pas possible d'ajouter des nƓuds pleinement, car le nettoyage ne se passe pas aprĂšs l'ajout d'un nƓud en raison du manque d'espace sur les partitions ;
  • la performance diminue lentement, car la compaction ne fonctionne pas ; 
  • le cluster fonctionne en mode d'urgence.

Top des erreurs de Tsiang

La sortie — nous avons ajoutĂ© cinq nƓuds sans nettoyage, puis nous avons commencĂ© Ă  les retirer progressivement du cluster et Ă  les rĂ©introduire en tant que nƓuds vides, sur lesquels l’espace Ă©tait Ă©puisĂ©. Le temps consacrĂ© a Ă©tĂ© beaucoup plus long que prĂ©vu. Il y avait un risque d'indisponibilitĂ© partielle ou complĂšte du cluster. 

Conclusions :

  • Sur tous les serveurs Cassandra, l'espace occupĂ© ne doit pas dĂ©passer 60 % sur chaque partition. 
  • Ils ne doivent pas ĂȘtre chargĂ©s Ă  plus de 50 % en CPU.
  • Ne nĂ©gligez pas la planification de capacitĂ© et rĂ©flĂ©chissez-y 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 un petit volume de donnĂ©es se redĂ©marrent plus rapidement, et un tel cluster est plus facile Ă  rĂ©animer. 

DeuxiĂšme place — «Des donnĂ©es ont disparu du stockage clĂ©-valeur de Consul»

Pour la dĂ©couverte de services, nous utilisons, comme beaucoup, Consul. Mais notre clĂ©-valeur est Ă©galement utilisĂ©e pour la mise en production continue de notre monolithe. Elle stocke des informations sur les upstreams actifs et inactifs, qui changent de place lors du dĂ©ploiement. Un service de dĂ©ploiement a Ă©tĂ© Ă©crit pour interagir avec le KV. À un moment donnĂ©, les donnĂ©es du KV ont disparu. Nous les avons rĂ©cupĂ©rĂ©es de mĂ©moire, mais avec quelques erreurs. En consĂ©quence, lors de la mise en production, la charge sur les upstreams s'est rĂ©partie de maniĂšre inĂ©gale, et nous avons rencontrĂ© de nombreuses erreurs 502 en raison de la surcharge des backends en CPU. Au final, nous avons migrĂ© de Consul KV vers Postgres, d'oĂč il n'est pas si facile de les supprimer.  

Conclusions :

  • Les services sans aucune autorisation ne doivent pas contenir de donnĂ©es critiques pour le fonctionnement du site. Par exemple, si vous n'avez pas d'autorisation dans ES, il serait prĂ©fĂ©rable d'interdire l'accĂšs au niveau rĂ©seau de partout oĂč il n'est pas nĂ©cessaire, de ne laisser que les accĂšs nĂ©cessaires, et de rendre action.destructive_requires_name: true.
  • Testez le mĂ©canisme de sauvegarde et de restauration Ă  l'avance. Par exemple, crĂ©ez Ă  l'avance un script (par exemple, en Python) qui peut Ă  la fois sauvegarder et restaurer.

PremiĂšre place — «Capitaine Évidence» 

À un moment donnĂ©, nous avons remarquĂ© une rĂ©partition inĂ©gale de la charge sur les upstreams nginx lorsque le backend comptait plus de 10 serveurs. Étant donnĂ© que le round-robin envoyait les demandes du premier au dernier upstream dans l'ordre, et que chaque rechargement de nginx recommençait, les premiers upstreams recevaient toujours plus de requĂȘtes que les autres. En consĂ©quence, ils fonctionnaient plus lentement et l'ensemble du site en souffrait. Cela devenait de plus en plus perceptible Ă  mesure que le trafic augmentait. Il n'a pas Ă©tĂ© suffisant de mettre Ă  jour nginx pour activer random — il a fallu réécrire une quantitĂ© consĂ©quente de code lua, qui ne fonctionnait pas sur la version 1.15 (Ă  ce moment-lĂ ). Nous avons dĂ» patcher notre nginx 1.14.2 pour y intĂ©grer le support du random. Cela a rĂ©solu le problĂšme. Ce bug mĂ©rite le prix du « capitaine de l'Ă©vident ».

Conclusions :

C'était trÚs intéressant et captivant d'explorer ce bug.) 

  • Mettez en place un suivi afin qu'il aide Ă  dĂ©tecter rapidement de telles fluctuations. Par exemple, vous pouvez utiliser ELK pour surveiller le RPS sur chaque backend de chaque upstream et suivre leur temps de rĂ©ponse du point de vue de nginx. Dans ce cas, cela nous a aidĂ©s Ă  identifier le problĂšme. 

Une grande partie des Ă©checs aurait pu ĂȘtre Ă©vitĂ©e avec une approche plus scrupuleuse de ce que vous faites. Il faut toujours garder Ă  l'esprit la loi de Murphy : Tout ce qui peut mal tourner, tournera mal, et construire des composants en s'en inspirant. 

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster