In questo articolo parlerò di una situazione che è recentemente accaduta a uno dei server del nostro cloud VPS, mettendomi in difficoltà per alcune ore. Da circa 15 anni mi occupo di configurazione e risoluzione dei problemi di server Linux, ma questo caso non rientra affatto nella mia esperienza: ho fatto alcune supposizioni errate e mi sono leggermente scoraggiato prima di riuscire a identificare correttamente la causa del problema e risolverlo.
Premessa
Operiamo un cloud di medie dimensioni che costruiamo su server standard con la seguente configurazione: 32 core, 256 GB di RAM e un'unità NVMe PCI-E Intel P4500 da 4 TB. Ci piace molto questa configurazione, poiché ci consente di non pensare a una mancanza di IO, garantendo un corretto limite a livello di tipo di istanze VM. Poiché NVMe Intel ha prestazioni impressionanti, possiamo fornire simultaneamente sia una fornitura completa di IOPS alle macchine sia il backup dello storage su un server di backup con zero IOWAIT.
Siamo tra quei tradizionalisti che non utilizzano SDN iperconvergenti e altre cose stilose, moderne e giovanili per la memorizzazione dei volumi VM, credendo che più è semplice il sistema, più è semplice risolvere i problemi in un contesto "il guru principale è andato in montagna". Di conseguenza, memorizziamo i volumi VM nel formato QCOW2 su XFS o EXT4, che è distribuito su LVM2.
L'uso di QCOW2 è ulteriormente richiesto dal prodotto che utilizziamo per l'orchestrazione: Apache CloudStack.
Per eseguire backup, eseguiamo un'immagine completa del volume, come uno snapshot di LVM2 (sì, sappiamo che gli snapshot di LVM2 sono lenti, ma l'Intel P4500 ci aiuta anche qui). Facciamo lvmcreate -s .. e con dd invio il backup su un server remoto con storage ZFS. Qui siamo comunque leggermente progressisti: ZFS sa mantenere i dati in forma compressa, e possiamo recuperarli rapidamente con DD o estrarre singoli volumi VM con mount -o loop ....
Certo, è possibile anche non eseguire un'immagine completa del volume LVM2, ma montare il file system in modalità
ROe copiare le immagini QCOW2 stesse, tuttavia, ci siamo trovati di fronte al fatto che XFS ne risentiva, non subito, ma in modo imprevedibile. Non amiamo affatto quando gli host-ipervisor si "bloccano" all'improvviso durante il fine settimana, di notte o durante le festività a causa di errori che non si sa quando si verificheranno. Pertanto, per XFS non utilizziamo il montaggio di snapshot in modalitàROper l'estrazione dei volumi, ma semplicemente copiamo l'intero volume LVM2.
La velocità di backup sul server di backup nel nostro caso è determinata dalle prestazioni del server di backup, che sono circa 600-800 MB/s per i dati non compressi, il successivo limite è la connessione 10Gbit/s, che collega il server di backup al cluster.
In questo contesto, un server di backup carica simultaneamente backup di 8 server ipervisori. Così, i sottosistemi disco e rete del server di backup, essendo più lenti, non permettono di sovraccaricare i sottosistemi disco degli host-ipervisori, poiché semplicemente non sono in grado di gestire, ad esempio, 8 GB/s, che gli host-ipervisori possono facilmente erogare.
Il processo di copia descritto sopra è molto importante per la narrazione successiva, comprese le dettagli — l'uso di un'unità veloce Intel P4500, l'uso di NFS e, probabilmente, l'uso di ZFS.
Storia del backup
Su ciascun nodo-ipervisor abbiamo una piccola partizione SWAP di dimensioni 8 GB, e noi "deployiamo" il nodo ipervisor utilizzando DD un'immagine di riferimento. Per il volume di sistema sui server utilizziamo 2xSATA SSD RAID1 o 2xSAS HDD RAID1 su un controller hardware LSI o HP. In generale, non ci interessa cosa ci sia dentro, poiché il volume di sistema funziona in modalità "quasi readonly", a parte lo SWAP. E poiché abbiamo molta RAM sul server e questa è libera al 30-40%, non pensiamo allo SWAP.
Il processo di creazione del backup. Questa attività appare circa così:
#!/bin/bash
mkdir -p /mnt/backups/volumes
DIR=/mnt/images-snap
VOL=images/volume
DATE=$(date "+%d")
HOSTNAME=$(hostname)
lvcreate -s -n $VOL-snap -l100%FREE $VOL
ionice -c3 dd iflag=direct if=/dev/$VOL-snap bs=1M of=/mnt/backups/volumes/$HOSTNAME-$DATE.raw
lvremove -f $VOL-snapPrestare attenzione a ionice -c3, di fatto questa cosa per i dispositivi NVMe è completamente inutile, poiché lo scheduler IO per loro è impostato come:
cat /sys/block/nvme0n1/queue/scheduler
[none] Tuttavia, abbiamo vari nodi legacy con normali RAID SSD, per loro questo è rilevante, ed ecco che si trasferisce AS IS. In generale, è solo un interessante pezzo di codice che spiega la futilità ionice in caso di tale configurazione.
Prestare attenzione al flag iflag=direct per DD. Utilizziamo direct IO bypassando la cache del buffer, per evitare sostituzioni superflue dei buffer IO durante la lettura. Tuttavia, oflag=direct non lo facciamo, poiché abbiamo riscontrato problemi di prestazioni con ZFS durante il suo utilizzo.
Questo schema è stato utilizzato con successo da diversi anni senza problemi.
E qui è iniziato tutto… Abbiamo scoperto che per uno dei nodi il backup non stava più funzionando, mentre il precedente era stato eseguito con un IOWAIT mostruoso vicino al 50%. Nel tentativo di capire perché il backup non si stesse eseguendo, ci siamo imbattuti nel fenomeno:
Volume group "images" not foundAbbiamo cominciato a pensare che "la fine è arrivata per Intel P4500", tuttavia, prima di spegnere il server per sostituire il disco, era comunque necessario eseguire il backup. Abbiamo riparato LVM2 recuperando i metadati da un backup di LVM2:
vgcfgrestore imagesAbbiamo avviato il backup e abbiamo visto questa scena:

Siamo di nuovo diventati molto tristi — era chiaro che non si poteva continuare così, poiché tutti i VPS avrebbero sofferto, e quindi anche noi. Non si capiva affatto cosa stesse succedendo — iostat mostrava miseri IOPS e un altissimo IOWAIT. Non c'erano idee, tranne "sostituiamo NVMe", ma poi è avvenuta un'illuminazione.
Analisi della situazione passo dopo passo
Registrazione storica. Alcuni giorni prima, su questo server era stato necessario creare un grande VPS con 128 GB di RAM. Sembrava che la memoria fosse sufficiente, ma per sicurezza abbiamo allocato ulteriori 32 GB per la partizione di swap. Il VPS è stato creato, ha svolto la sua funzione con successo e l'incidente è stato dimenticato, mentre la partizione di SWAP è rimasta.
Caratteristiche della configurazione. Per tutti i server del cloud, il parametro vm.swappiness era impostato sul valore predefinito 60. E lo SWAP era stato creato su SAS HDD RAID1.
Cosa stava succedendo (secondo la redazione). Durante il backup DD si generava un gran numero di dati da registrare, che venivano collocati nei buffer RAM prima della scrittura in NFS. Il kernel del sistema, seguendo la politica swappiness, trasferiva molte pagine di memoria del VPS nella zona di swap, che si trovava su un volume HDD RAID1 lento. Questo portava a un significativo aumento di IOWAIT, non a causa di IO NVMe, ma a causa di IO HDD RAID1.
Come è stato risolto il problema. È stata disattivata la partizione di swap da 32 GB. Ci sono volute 16 ore, su come e perché lo SWAP si disattiva così lentamente si può leggere separatamente. Sono stati modificati i parametri swappiness a un valore pari a 5 in tutto il cloud.
Come potrebbe non essere successoIn primo luogo, se SWAP fosse su un dispositivo SSD RAID o NVMe, in secondo luogo, se non ci fosse un dispositivo NVMe, ma ci fosse un dispositivo più lento che non emetteva un tale volume di dati — ironicamente, il problema è sorto perché il NVMe è troppo veloce.
Dopo di ciò, tutto ha ripreso a funzionare come prima — con IOWAIT pari a zero.
Fonte: habr.com
