Top fakapov ciano

Top fakapov ciano

Tutto bene! 

Mi chiamo Nikita, sono il team leader del team di ingegneri Cian. Una delle mie responsabilità in azienda è ridurre a zero il numero di incidenti legati alle infrastrutture di produzione.
Ciò che verrà discusso di seguito ci ha causato molto dolore e lo scopo di questo articolo è impedire ad altre persone di ripetere i nostri errori o almeno minimizzarne l'impatto. 

preambolo

Molto tempo fa, quando Cian era costituito da monoliti e non c'erano ancora accenni di microservizi, misuravamo la disponibilità di una risorsa controllando 3-5 pagine. 

Rispondono: va tutto bene, se non rispondono per molto tempo, avvisa. Quanto tempo dovevano assentarsi dal lavoro perché fosse considerato un incidente veniva deciso dalle persone durante le riunioni. Una squadra di ingegneri è stata sempre coinvolta nelle indagini sull'incidente. Una volta completata l'indagine, hanno scritto un'autopsia, una sorta di rapporto via e-mail nel formato: cosa è successo, quanto è durato, cosa abbiamo fatto in questo momento, cosa faremo in futuro. 

Le pagine principali del sito o come capiamo di aver toccato il fondo

 
Per poter comprendere in qualche modo la priorità dell'errore, abbiamo individuato le pagine del sito più critiche per la funzionalità aziendale. Usandoli, contiamo il numero di richieste e timeout riusciti/non riusciti. Ecco come misuriamo il tempo di attività. 

Diciamo che abbiamo scoperto che ci sono una serie di sezioni estremamente importanti del sito che sono responsabili del servizio principale: la ricerca e l'invio di annunci pubblicitari. Se il numero di richieste non riuscite supera l'1%, si tratta di un incidente critico. Se entro 15 minuti durante la prima serata il tasso di errore supera lo 0,1%, anche questo è considerato un incidente critico. Questi criteri coprono la maggior parte degli incidenti; il resto va oltre lo scopo di questo articolo.

Top fakapov ciano

I migliori incidenti Cian

Quindi, abbiamo sicuramente imparato a determinare il fatto che si sia verificato un incidente. 

Ora ogni incidente è descritto in dettaglio e si riflette nell'epopea di Jira. A proposito: per questo abbiamo avviato un progetto separato, chiamato FAIL: al suo interno è possibile creare solo epiche. 

Se raccogli tutti i fallimenti degli ultimi anni, i leader sono: 

  • incidenti relativi a mssql;
  • incidenti causati da fattori esterni;
  • errori di amministrazione.

Diamo un'occhiata più in dettaglio agli errori degli amministratori, così come ad altri fallimenti interessanti.

Quinto posto - “Mettere ordine nei DNS”

Era un martedì tempestoso. Abbiamo deciso di ripristinare l'ordine nel cluster DNS. 

Volevo trasferire i server DNS interni da bind a powerdns, assegnando per questo server completamente separati, dove non c'è altro che DNS. 

Abbiamo posizionato un server DNS in ciascuna posizione dei nostri controller di dominio ed è arrivato il momento di spostare le zone da bind a powerdns e trasferire l'infrastruttura su nuovi server. 

Durante il trasloco, di tutti i server specificati nel caching locale, ne è rimasto solo uno, che si trovava nel data center di San Pietroburgo. Questo DC è stato inizialmente dichiarato non critico per noi, ma improvvisamente è diventato un singolo punto di errore.
Fu durante questo periodo di trasferimento che crollò il canale tra Mosca e San Pietroburgo. In realtà siamo rimasti senza DNS per cinque minuti e ci siamo rialzati quando l'hoster ha risolto il problema. 

Conclusioni:

Se prima trascuravamo i fattori esterni durante la preparazione al lavoro, ora sono inclusi anche nell'elenco di ciò per cui ci stiamo preparando. E ora ci sforziamo di garantire che tutti i componenti siano riservati n-2 e durante il lavoro possiamo abbassare questo livello a n-1.

  • Quando elabori un piano d'azione, segna i punti in cui il servizio potrebbe fallire e pensa in anticipo a uno scenario in cui tutto è andato “di male in peggio”.
  • Distribuisci server DNS interni su diverse geolocalizzazione/data center/rack/switch/input.
  • Su ciascun server, installa un server DNS di memorizzazione nella cache locale, che reindirizza le richieste ai server DNS principali e, se non è disponibile, risponderà dalla cache. 

Quarto posto - “Mettere ordine in Nginx”

Un bel giorno, il nostro team ha deciso che “ne abbiamo abbastanza” ed è iniziato il processo di refactoring delle configurazioni nginx. L'obiettivo principale è portare le configurazioni in una struttura intuitiva. In precedenza, tutto era “storicamente stabilito” e non aveva alcuna logica. Ora ciascun nome_server è stato spostato in un file con lo stesso nome e tutte le configurazioni sono state distribuite in cartelle. A proposito, la configurazione contiene 253949 righe o 7836520 caratteri e occupa quasi 7 megabyte. Livello superiore della struttura: 

Struttura 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

È migliorato molto, ma nel processo di ridenominazione e distribuzione delle configurazioni, alcune di esse avevano l'estensione sbagliata e non erano incluse nella direttiva include *.conf. Di conseguenza, alcuni host sono diventati non disponibili e hanno restituito il codice 301 alla pagina principale. Dato che il codice di risposta non era 5xx/4xx, questo non è stato notato immediatamente, ma solo al mattino. Successivamente, abbiamo iniziato a scrivere test per verificare i componenti dell'infrastruttura.

Conclusioni: 

  • Struttura correttamente le tue configurazioni (non solo nginx) e pensa alla struttura nelle prime fasi del progetto. In questo modo li renderai più comprensibili al team, il che a sua volta ridurrà il TTM.
  • Scrivere test per alcuni componenti dell'infrastruttura. Ad esempio: verificare che tutte le chiavi server_name forniscano lo stato corretto + corpo della risposta. Basterà avere a portata di mano qualche script che controlli le funzioni base del componente, per non ricordarsi freneticamente alle 3 di notte cos'altro c'è da controllare. 

Terzo posto - "Improvvisamente ha esaurito lo spazio in Cassandra"

I dati crescevano costantemente e tutto andava bene fino al momento in cui la riparazione di grandi casespace nel cluster Cassandra cominciò a fallire, perché la compattazione non poteva funzionare su di essi. 

In un giorno di tempesta il grappolo si trasformò quasi in una zucca, e precisamente:

  • c'era circa il 20% dello spazio totale rimasto nel cluster;
  • È impossibile aggiungere completamente i nodi, poiché la pulizia non viene eseguita dopo l'aggiunta di un nodo a causa della mancanza di spazio sulle partizioni;
  • la produttività diminuisce gradualmente poiché la compattazione non funziona; 
  • Il cluster è in modalità di emergenza.

Top fakapov ciano

Esci: abbiamo aggiunto altri 5 nodi senza pulizia, dopodiché abbiamo iniziato a rimuoverli sistematicamente dal cluster e reinserirli, come nodi vuoti che avevano esaurito lo spazio. È stato impiegato molto più tempo di quanto vorremmo. Esisteva il rischio di indisponibilità parziale o totale del cluster. 

Conclusioni:

  • Su tutti i server Cassandra non deve essere occupato più del 60% dello spazio su ciascuna partizione. 
  • Dovrebbero essere caricati a non più del 50% della CPU.
  • Non dovresti dimenticare la pianificazione della capacità e pensare attentamente a ciascun componente, in base alle sue specifiche.
  • Maggiore è il numero di nodi nel cluster, meglio è. I server contenenti una piccola quantità di dati vengono sovraccaricati più velocemente e un cluster di questo tipo è più facile da ripristinare. 

Secondo posto: "I dati sono scomparsi dall'archiviazione dei valori-chiave della console"

Per l'individuazione dei servizi, noi, come molti, utilizziamo consul. Ma utilizziamo anche il suo valore-chiave per il layout blu-verde del monolite. Memorizza informazioni sugli upstream attivi e inattivi, che cambiano posizione durante la distribuzione. A questo scopo è stato scritto un servizio di distribuzione che interagiva con KV. Ad un certo punto, i dati di KV sono scomparsi. Ripristinato dalla memoria, ma con una serie di errori. Di conseguenza, durante il caricamento, il carico sugli upstream è stato distribuito in modo non uniforme e abbiamo ricevuto molti errori 502 a causa del sovraccarico dei backend sulla CPU. Di conseguenza, siamo passati dal console KV a Postgres, da dove non è più così facile rimuoverli.  

Conclusioni:

  • I servizi senza alcuna autorizzazione non dovrebbero contenere dati critici per il funzionamento del sito. Ad esempio, se non si dispone dell'autorizzazione in ES, sarebbe meglio negare l'accesso a livello di rete da qualsiasi luogo in cui non sia necessario, lasciare solo quelli necessari e impostare anche action.destructiva_requires_name: true.
  • Esercitati in anticipo con il tuo meccanismo di backup e ripristino. Ad esempio, crea in anticipo uno script (ad esempio in Python) che possa eseguire il backup e il ripristino.

Primo posto: “Capitano Unbvious” 

Ad un certo punto, abbiamo notato una distribuzione non uniforme del carico sugli upstream nginx nei casi in cui c'erano più di 10 server nel backend. Poiché il round robin inviava richieste dal primo all'ultimo upstream in ordine e ogni ricarica di nginx ricominciava, i primi upstream ricevevano sempre più richieste degli altri, di conseguenza lavoravano più lentamente e l'intero sito ne soffriva. Ciò è diventato sempre più evidente con l’aumento della quantità di traffico. Il semplice aggiornamento di nginx per abilitare la casualità non ha funzionato: dobbiamo rifare un sacco di codice lua che non è decollato nella versione 1 (in quel momento). Abbiamo dovuto patchare il nostro nginx 1.15, introducendovi il supporto casuale. Questo ha risolto il problema. Questo bug vince la categoria "Captain Non-Ovviousness".

Conclusioni:

È stato molto interessante ed emozionante esplorare questo bug). 

  • Organizza il tuo monitoraggio in modo che ti aiuti a trovare rapidamente tali fluttuazioni. Ad esempio, puoi utilizzare ELK per monitorare gli rps su ciascun backend di ciascun upstream, monitorare il loro tempo di risposta dal punto di vista di nginx. In questo caso, questo ci ha aiutato a identificare il problema. 

Di conseguenza, la maggior parte dei fallimenti avrebbero potuto essere evitati con un approccio più scrupoloso a ciò che stavi facendo. Dobbiamo sempre ricordare la legge di Murphy: Se qualcosa può andare male, lo farà, e costruire componenti basati su di esso. 

Fonte: habr.com

Aggiungi un commento