Toppmissar pÄ Cian

Toppmissar pÄ Cian

Alla gott! 

Jag heter Nikita och Àr teamledare för ingenjörerna pÄ Cian. En av mina uppgifter i företaget Àr att minska antalet incidenter relaterade till infrastrukturen i produktion till noll.
Det som kommer att diskuteras hÀr har orsakat oss mycket smÀrta, och mÄlet med denna artikel Àr att förhindra andra frÄn att upprepa vÄra misstag eller Ätminstone minimera deras pÄverkan. 

Inledning

LĂ€nge sedan, nĂ€r Cian bestod av monoliter och det inte fanns nĂ„gra indikationer pĂ„ mikrotjĂ€nster, mĂ€tte vi tillgĂ€ngligheten av resurser genom att kontrollera 3–5 sidor. 

Svarar de — allt Ă€r bra, svarar de inte under en lĂ€ngre tid — alarm. Hur lĂ€nge de ska vara nere för att det ska rĂ€knas som en incident avgjordes av folk pĂ„ möten. Ingenjörsteamet deltog alltid i utredningen av incidenten. NĂ€r utredningen var klar skrev vi en postmortem — en slags rapport som skickades via e-post i formatet: vad som hĂ€nde, hur lĂ€nge det varade, vad man gjorde i stunden, vad vi kommer att göra i framtiden. 

Huvudsidorna pÄ webbplatsen eller hur vi vet att vi har nÄtt botten

 
För att kunna förstÄ prioriteten av fel har vi identifierat de mest kritiska sidorna för affÀrsfunktionaliteten pÄ webbplatsen. Genom dem rÀknar vi antalet lyckade/olyckade förfrÄgningar och tidsöverskridanden. PÄ sÄ sÀtt mÀter vi uptime. 

Anta att vi har kommit fram till att det finns ett antal superviktiga delar av webbplatsen som ansvarar för huvudservicen — sökning och publicering av annonser. Om antalet förfrĂ„gningar som avslutades med ett fel överstiger 1% — Ă€r det en kritisk incident. Om felprocenten under 15 minuter i primetime överstiger 0,1% — dĂ„ rĂ€knas det ocksĂ„ som en kritisk incident. Dessa kriterier tĂ€cker merparten av incidenterna, medan andra ligger utanför ramen för denna artikel.

Toppmissar pÄ Cian

Topp bÀsta incidenterna pÄ Cian

SÄ vi har definitivt lÀrt oss att identifiera nÀr en incident har intrÀffat. 

Nu Ă€r varje incident detaljerat beskriven och Ă„terspeglas i en epic i Jira. För övrigt: för detta har vi skapat ett separat projekt, som vi kallade FAIL — dĂ€r man endast kan skapa epics. 

Om man samlar alla misslyckanden frÄn de senaste Ären, sÄ ligger följande i topp: 

  • incidenter relaterade till mssql;
  • incidenter orsakade av externa faktorer;
  • adminfel.

Vi kommer att stanna vid adminfelen mer i detalj, samt nÄgra andra intressanta misslyckanden.

Femte plats — "Vi ordnar upp i DNS"

Det var en ruggig tisdag. Vi bestÀmde oss för att organisera DNS-klustret. 

Vi ville migrera interna DNS-servrar frÄn bind till powerdns, och avsatte helt separata servrar för detta, dÀr det endast fanns DNS. 

Vi placerade en DNS-server i varje plats i vÄra datacenter, och nu kom stunden att flytta zonerna frÄn bind till powerdns och byta infrastrukturen till de nya servrarna. 

I den mest intensiva fasen av flytten, servrar, som som angivits i lokala cachande bind-servrar pÄ alla servrar, Äterstod bara en, som lÄg i datacentret i Sankt Petersburg. Detta datacenter hade frÄn början deklarerats som icke-kritiskt för oss, men blev plötsligt en single point of failure.
Just under denna flytt kraschade kanalen mellan Moskva och Sankt Petersburg. Vi befann oss faktiskt utan DNS i fem minuter och ÄterhÀmtade oss nÀr hostingleverantören problemen ÄtgÀrdades. 

Slutsatser:

Tidigare har vi Äsidosatt externa faktorer nÀr vi förberett oss för arbetet, men nu har vi Àven inkluderat dem i listan över vad vi förbereder oss pÄ. Och nu strÀvar vi efter att alla komponenter Àr reservdelar n-2, och under arbetets gÄng kan vi sÀnka denna nivÄ till n-1.

  • Under upprĂ€ttandet av handlingsplanen, markera punkter dĂ€r tjĂ€nsten kan falla och tĂ€nk igenom scenarier dĂ€r allt gĂ„r "fruktansvĂ€rt fel" i förvĂ€g.
  • Distribuera interna DNS-servrar över olika geolokationer/datacenter/stĂ€ll/omkopplare/inmatningar.
  • Installera en lokal cachande DNS-server pĂ„ varje server, som omdirigerar förfrĂ„gningar till de primĂ€ra DNS-servrarna, och i hĂ€ndelse av att den inte Ă€r tillgĂ€nglig kommer den att svara frĂ„n cachen. 

FjĂ€rde plats — "Ordning i Nginx"

En vacker dag bestÀmde vÄrt team att "det Àr nog nu", och processen för refaktorering av nginx-konfigurationerna startade. HuvudmÄlet var att ge konfigurationerna en intuitivt begriplig struktur. Tidigare var allt "historiskt betingat" och bar ingen logik. Nu har vi flyttat varje server_name till en namngiven fil och sorterat alla konfigurationer i mappar. För övrigt innehÄller konfigurationen 253949 rader eller 7836520 tecken och Àr nÀstan 7 megabyte stor. Den övergripande strukturens nivÄ: 

Nginx-struktur

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

Det har blivit betydligt bÀttre, men under omdöpning och fördelning av konfigar fick en del av dem fel filÀndelse och kom inte med i direktivet include *.conf. Som en följd av detta blev vissa vÀrdar otillgÀngliga och Ätergav 301 till startsidan. Eftersom svarskoden inte var 5xx/4xx, mÀrkte vi det inte genast, utan först pÄ morgonen. Efter detta började vi skriva tester för att kontrollera infrastrukturkomponenter.

Slutsatser: 

  • Strukturera konfigurationerna korrekt (inte bara nginx) och tĂ€nk igenom strukturen i ett tidigt skede av projektet. PĂ„ sĂ„ sĂ€tt gör du dem mer begripliga för teamet, vilket i sin tur minskar TTM.
  • Skriv tester för vissa infrastrukturkomponenter. Till exempel: kontrollera att alla viktiga server_name ger rĂ€tt status, + svarstext. Det rĂ€cker att ha bara nĂ„gra skript till hands som kontrollerar de grundlĂ€ggande funktionerna i komponenten, sĂ„ att du inte panikartat ska försöka komma ihĂ„g vad mer som behöver kontrolleras mitt i natten. 

Tredje plats — "Plötsligt tog det slut pĂ„ utrymme i Cassandra"

Data vÀxte stadigt, och allt gick bra tills det ögonblick dÄ reparationen av stora keyspaces i Cassandra-klustret började misslyckas, eftersom de inte kan genomföra kompaktion. 

En blödig dag nÀstan förvandlades klustret till en pumpa, nÀmligen:

  • det Ă„terstod cirka 20% totalt i klustret;
  • det gĂ„r inte att helt lĂ€gga till noder, eftersom cleanup inte genomförs efter att noder lagts till pĂ„ grund av brist pĂ„ utrymme pĂ„ partitionerna;
  • prestandan faller försiktigt, eftersom kompaktionen inte fungerar; 
  • klustret arbetar i nödlĂ€ge.

Toppmissar pÄ Cian

UttrĂ€de – vi har lagt till ytterligare 5 noder utan rensning, efter vilket vi började systematiskt ta bort frĂ„n klustret och sedan Ă„terinföra, som tomma noder, dĂ€r det inte fanns nĂ„got utrymme kvar. Tiden som lagts ner har varit betydligt mer Ă€n vi hade önskat. Det fanns en risk för delvis eller fullstĂ€ndig otillgĂ€nglighet av klustret. 

Slutsatser:

  • PĂ„ alla servrar med Cassandra bör högst 60% av utrymmet vara anvĂ€nt pĂ„ varje partition. 
  • De bör vara belastade till högst 50% av CPU.
  • Man bör inte bortse frĂ„n kapacitetsplanering och det mĂ„ste övervĂ€gas för varje komponent beroende pĂ„ dess specifika behov.
  • Ju fler noder i klustret, desto bĂ€ttre. Servrar som innehĂ„ller en liten mĂ€ngd data fĂ„r snabbare omstart, och ett sĂ„dant kluster Ă€r lĂ€ttare att Ă„terstĂ€lla. 

Andra plats – 'Data försvann frĂ„n consul key-value storage'

För tjÀnsteupptÀckten anvÀnder vi, precis som mÄnga andra, Consul. Men vi anvÀnder Àven dess key-value för blue-green deployment av monoliten. DÀr lagras information om aktiva och inaktiva upstreams, som byter plats under deployment. För detta har en deploymenttjÀnst skrivits som interagerade med KV. Vid nÄgot tillfÀlle försvann data frÄn KV. Vi ÄterstÀllde det frÄn minnet, men med vissa fel. Som en följd av detta blev belastningen pÄ upstreams ojÀmt fördelad under distributionen, och vi fick mÄnga 502-fel pÄ grund av överbelastning av backend-maskinerna pÄ CPU. I slutÀndan flyttade vi frÄn Consul KV till Postgres, dÀrifrÄn Àr det inte sÄ lÀtt att ta bort dem.  

Slutsatser:

  • TjĂ€nster utan nĂ„gon form av autentisering bör inte innehĂ„lla kritiska uppgifter för webbplatsens funktion. Till exempel, om du inte har autentisering i ES – skulle det vara bĂ€st att förbjuda Ă„tkomst pĂ„ nĂ€tverksnivĂ„ frĂ„n alla platser dĂ€r det inte behövs, lĂ€mna endast de nödvĂ€ndiga och dessutom göra action.destructive_requires_name: true.
  • Öva pĂ„ mekanismen för sĂ€kerhetskopiering och Ă„terstĂ€llning i förvĂ€g. Till exempel, skapa ett skript (till exempel pĂ„ Python) som kan bĂ„de sĂ€kerhetskopiera och Ă„terstĂ€lla.

Första plats – 'Kapten Otydlighet' 

Vid nĂ„got tillfĂ€lle mĂ€rkte vi en ojĂ€mn belastning pĂ„ nginx upstreams nĂ€r det fanns fler Ă€n 10 servrar i backend. Eftersom round-robin dirigerade förfrĂ„gningar frĂ„n den första till den sista upstream i ordning, och varje reload av nginx började frĂ„n början, fick de första upstreams alltid fler förfrĂ„gningar Ă€n de andra. Som ett resultat arbetade de lĂ„ngsammare och hela webbplatsen drabbades. Detta blev allt mer pĂ„tagligt i takt med att trafiken ökade. Att bara uppdatera nginx för att inkludera random fungerade inte — vi var tvungna att göra om en massa lua-kod som inte gick att anvĂ€nda i version 1.15 (vid den tidpunkten). Vi var tvungna att patcha vĂ„r nginx 1.14.2 och införa stöd för random. Detta löste problemet. Denna bugg vinner i kategorin 'kapten uppenbarhet'.

Slutsatser:

Det var mycket intressant och spÀnnande att undersöka denna bugg). 

  • Bygg en övervakning som hjĂ€lper till att snabbt upptĂ€cka liknande fluktuationer. Till exempel kan man anvĂ€nda ELK för att övervaka rps för varje backend av varje upstream, och följa deras svarstider ur nginx:s perspektiv. I det hĂ€r fallet hjĂ€lpte det oss att identifiera problemet. 

De flesta av felen kunde ha undvikits med en mer noggrann instÀllning till det man gör. Man mÄste alltid komma ihÄg Murphys lag: Anything that can go wrong will go wrong, och bygga komponenter med den i Ätanke. 

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster