Topfakapov Cyaan

Topfakapov Cyaan

Allemaal goed! 

Mijn naam is Nikita, ik ben de teamleider van het Cian engineeringteam. Een van mijn verantwoordelijkheden bij het bedrijf is het terugbrengen van het aantal incidenten met betrekking tot de infrastructuur in de productie tot nul.
Wat hieronder zal worden besproken, heeft ons veel pijn gedaan, en het doel van dit artikel is om te voorkomen dat andere mensen onze fouten herhalen of op zijn minst de impact ervan minimaliseren. 

Преамбула

Lang geleden, toen Cian uit monolieten bestond en er nog geen aanwijzingen voor microservices waren, maten we de beschikbaarheid van een bron door 3-5 pagina's te controleren. 

Ze antwoorden - alles is in orde, als ze lange tijd niet antwoorden - alert. Hoe lang ze afwezig moesten zijn voordat er sprake was van een incident, werd tijdens vergaderingen bepaald. Bij het onderzoek naar het incident was altijd een team van ingenieurs betrokken. Toen het onderzoek was afgerond, schreven ze een postmortem - een soort rapport per e-mail in de vorm: wat er is gebeurd, hoe lang het heeft geduurd, wat we op dat moment hebben gedaan, wat we in de toekomst zullen doen. 

De hoofdpagina's van de site of hoe we dat begrijpen, we zijn op de bodem beland

 
Om op de een of andere manier de prioriteit van de fout te begrijpen, hebben we de meest kritische sitepagina's voor zakelijke functionaliteit geïdentificeerd. Hiermee tellen we het aantal succesvolle/niet-succesvolle verzoeken en time-outs. Dit is hoe we de uptime meten. 

Laten we zeggen dat we erachter zijn gekomen dat er een aantal superbelangrijke delen van de site zijn die verantwoordelijk zijn voor de hoofddienst: het zoeken en indienen van advertenties. Als het aantal mislukte aanvragen groter is dan 1%, is er sprake van een kritiek incident. Als binnen 15 minuten tijdens prime time het foutenpercentage hoger is dan 0,1%, wordt dit ook als een kritiek incident beschouwd. Deze criteria hebben betrekking op de meeste incidenten; de rest valt buiten het bestek van dit artikel.

Topfakapov Cyaan

Top beste incidenten Cian

We hebben dus zeker geleerd om vast te stellen dat er een incident heeft plaatsgevonden. 

Nu wordt elk incident gedetailleerd beschreven en weerspiegeld in het Jira-epos. Trouwens: hiervoor zijn we een apart project gestart, genaamd FAIL - er kunnen alleen heldendichten in worden gemaakt. 

Als je alle mislukkingen van de afgelopen jaren verzamelt, zijn de leiders: 

  • mssql-gerelateerde incidenten;
  • incidenten veroorzaakt door externe factoren;
  • beheerdersfouten.

Laten we meer in detail kijken naar de fouten van beheerders, evenals enkele andere interessante mislukkingen.

Vijfde plaats - “Orde op orde brengen in de DNS”

Het was een stormachtige dinsdag. We hebben besloten de orde in het DNS-cluster te herstellen. 

Ik wilde interne DNS-servers overzetten van binding naar powerdns, waarbij ik hiervoor volledig aparte servers toewijs, waar er niets anders is dan DNS. 

We hebben op elke locatie van onze DC's één DNS-server geplaatst en het moment kwam om zones van binding naar powerdns te verplaatsen en de infrastructuur over te zetten naar nieuwe servers. 

Midden in de verhuizing bleef er van alle servers die waren gespecificeerd in lokale caching-bindingen op alle servers, slechts één over, namelijk in het datacenter in St. Petersburg. Deze DC werd aanvankelijk als niet-kritisch voor ons bestempeld, maar werd plotseling een single point of Failure.
Het was tijdens deze periode van verplaatsing dat het kanaal tussen Moskou en Sint-Petersburg instortte. We zaten eigenlijk vijf minuten zonder DNS en stonden weer op toen de host het probleem oploste. 

Conclusies:

Als we eerder externe factoren verwaarloosden tijdens de voorbereiding op het werk, zijn ze nu ook opgenomen in de lijst van waar we ons op voorbereiden. En nu streven we ernaar ervoor te zorgen dat alle componenten n-2 gereserveerd zijn, en tijdens het werk kunnen we dit niveau verlagen naar n-1.

  • Markeer bij het opstellen van een actieplan de punten waarop de dienstverlening mogelijk faalt en bedenk vooraf een scenario waarin alles “van kwaad tot erger” gaat.
  • Verdeel interne DNS-servers over verschillende geolocaties/datacenters/racks/switches/ingangen.
  • Installeer op elke server een lokale DNS-caching-server, die verzoeken doorstuurt naar de belangrijkste DNS-servers, en als deze niet beschikbaar is, reageert deze vanuit de cache. 

Vierde plaats - “Dingen op orde brengen in Nginx”

Op een mooie dag besloot ons team dat “we hier genoeg van hadden”, en begon het proces van het refactoren van nginx-configuraties. Het belangrijkste doel is om de configuraties naar een intuïtieve structuur te brengen. Voorheen was alles ‘historisch vastgelegd’ en bevatte het geen enkele logica. Nu is elke servernaam verplaatst naar een bestand met dezelfde naam en zijn alle configuraties in mappen verdeeld. Trouwens, de configuratie bevat 253949 regels of 7836520 tekens en neemt bijna 7 megabytes in beslag. Structuur op het hoogste niveau: 

Nginx-structuur

├── 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

Het werd veel beter, maar tijdens het hernoemen en distribueren van configuraties hadden sommige ervan de verkeerde extensie en waren ze niet opgenomen in de include *.conf-richtlijn. Als gevolg hiervan waren sommige hosts niet meer beschikbaar en keerden ze terug naar de hoofdpagina. Doordat de responscode niet 301xx/5xx was, werd dit niet direct opgemerkt, maar pas in de ochtend. Daarna zijn we begonnen met het schrijven van tests om infrastructuurcomponenten te controleren.

Conclusies: 

  • Structureer uw configuraties correct (niet alleen nginx) en denk in een vroeg stadium van het project over de structuur na. Op deze manier maak je ze begrijpelijker voor het team, wat op zijn beurt de TTM zal verminderen.
  • Schrijf tests voor sommige infrastructuurcomponenten. Bijvoorbeeld: controleren of alle belangrijke servernamen de juiste status + antwoordtekst geven. Het is voldoende om slechts een paar scripts bij de hand te hebben die de basisfuncties van de component controleren, om niet om 3 uur 's nachts verwoed te bedenken wat er nog meer moet worden gecontroleerd. 

Derde plaats - “Er was plotseling geen ruimte meer in Cassandra”

De gegevens groeiden gestaag, en alles was in orde tot het moment waarop de reparatie van grote casespaces in het Cassandra-cluster begon te mislukken, omdat verdichting daarop niet kon werken. 

Op een stormachtige dag veranderde de cluster bijna in een pompoen, namelijk:

  • er was nog ongeveer 20% van de totale ruimte in het cluster over;
  • Het is onmogelijk om knooppunten volledig toe te voegen, omdat het opruimen niet doorgaat na het toevoegen van een knooppunt vanwege ruimtegebrek op de partities;
  • de productiviteit neemt geleidelijk af omdat verdichting niet werkt; 
  • Het cluster bevindt zich in de noodmodus.

Topfakapov Cyaan

Afsluiten - we hebben nog 5 knooppunten toegevoegd zonder op te ruimen, waarna we ze systematisch uit het cluster begonnen te verwijderen en ze opnieuw binnen te gaan, als lege knooppunten die geen ruimte meer hadden. Er is veel meer tijd aan besteed dan we zouden willen. Er bestond een risico op gedeeltelijke of volledige onbeschikbaarheid van het cluster. 

Conclusies:

  • Op alle cassandra-servers mag niet meer dan 60% van de ruimte op elke partitie bezet zijn. 
  • Ze mogen op niet meer dan 50% CPU worden geladen.
  • U mag de capaciteitsplanning niet vergeten en moet voor elk onderdeel goed nadenken, op basis van de specifieke kenmerken ervan.
  • Hoe meer knooppunten in het cluster, hoe beter. Servers met een kleine hoeveelheid data raken sneller overbelast en zo’n cluster is makkelijker weer tot leven te wekken. 

Tweede plaats - “Gegevens verdwenen uit de opslag van sleutelwaarden van consulenten”

Voor het ontdekken van diensten gebruiken wij, zoals velen, consul. Maar we gebruiken de sleutelwaarde ook voor de blauwgroene lay-out van de monoliet. Het slaat informatie op over actieve en inactieve upstreams, die tijdens de implementatie van plaats wisselen. Voor dit doel werd een implementatieservice geschreven die communiceerde met KV. Op een gegeven moment verdwenen de gegevens van KV. Hersteld vanuit het geheugen, maar met een aantal fouten. Als gevolg hiervan werd tijdens het uploaden de belasting van de upstreams ongelijk verdeeld en kregen we veel 502-fouten doordat de backends overbelast raakten op de CPU. Als gevolg hiervan zijn we verhuisd van consul KV naar postgres, vanwaar het niet langer zo eenvoudig is om ze te verwijderen.  

Conclusies:

  • Diensten zonder enige toestemming mogen geen gegevens bevatten die cruciaal zijn voor de werking van de site. Als u bijvoorbeeld geen autorisatie hebt in ES, is het beter om de toegang op netwerkniveau te weigeren overal waar deze niet nodig is, alleen de noodzakelijke te laten staan, en ook action.destructieve_requires_name: true in te stellen.
  • Oefen vooraf uw back-up- en herstelmechanisme. Maak bijvoorbeeld vooraf een script (bijvoorbeeld in Python) dat backups en herstel kan maken.

Eerste plaats - "Kapitein Unobvious" 

Op een gegeven moment merkten we een ongelijke verdeling van de belasting op nginx-upstreams in gevallen waarin er meer dan 10 servers in de backend waren. Vanwege het feit dat round-robin verzoeken van de eerste naar de laatste upstream op volgorde stuurde en elke herlaadbeurt van nginx opnieuw begon, ontvingen de eerste upstreams altijd meer verzoeken dan de rest, met als resultaat dat ze langzamer werkten en dat de hele site eronder leed. Dit werd steeds duidelijker naarmate de hoeveelheid verkeer toenam. Het simpelweg updaten van nginx om willekeurig in te schakelen werkte niet - we moeten een aantal lua-code opnieuw uitvoeren die niet van start ging in versie 1 (op dat moment). We moesten onze nginx 1.15 patchen en er willekeurige ondersteuning in introduceren. Dit loste het probleem op. Deze bug wint de categorie 'Captain Non-Obviousness'.

Conclusies:

Het was erg interessant en opwindend om deze bug te onderzoeken). 

  • Organiseer uw monitoring zo dat u dergelijke schommelingen snel kunt opsporen. U kunt ELK bijvoorbeeld gebruiken om rps op elke backend van elke upstream te monitoren, en hun responstijd te monitoren vanuit het oogpunt van nginx. In dit geval heeft dit ons geholpen het probleem te identificeren. 

Als gevolg daarvan hadden de meeste mislukkingen vermeden kunnen worden als je nauwgezeter had gehandeld. We moeten altijd de wet van Murphy onthouden: Alles wat fout kan gaan, zal fout gaan, en op basis daarvan componenten bouwen. 

Bron: www.habr.com

Voeg een reactie