Come controllare i dischi con fio per prestazioni sufficienti per etcd

Nota. trad.: Questo articolo è il risultato di una mini-ricerca condotta dagli ingegneri di IBM Cloud alla ricerca di una soluzione ad un problema reale legato al funzionamento del database etcd. Un compito simile era rilevante per noi, tuttavia, il corso di riflessioni e azioni degli autori potrebbe essere interessante in un contesto più ampio.

Come controllare i dischi con fio per prestazioni sufficienti per etcd

Breve riassunto dell'intero articolo: fio e etcd

Le prestazioni di un cluster etcd dipendono fortemente dalla velocità dello storage sottostante. etcd esporta varie metriche Prometheus per monitorare le prestazioni. Uno di essi è wal_fsync_duration_seconds. Nella documentazione per etcd diceche l'archiviazione può essere considerata abbastanza veloce se il 99° percentile di questa metrica non supera i 10 ms...

Se stai pensando di configurare un cluster etcd su macchine Linux e vuoi verificare se le unità (come gli SSD) sono abbastanza veloci, ti consigliamo di utilizzare il popolare tester I/O chiamato filo. È sufficiente eseguire il seguente comando (directory test-data deve trovarsi nella partizione montata dell'unità testata):

fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytest

Resta solo da guardare l'output e verificare se il 99esimo percentile si adatta fdatasync tra 10 ms. In tal caso, l'unità funziona abbastanza velocemente. Ecco un esempio di output:

fsync/fdatasync/sync_file_range:
  sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70
  sync percentiles (usec):
   | 1.00th=[ 553], 5.00th=[ 578], 10.00th=[ 594], 20.00th=[ 627],
   | 30.00th=[ 709], 40.00th=[ 750], 50.00th=[ 783], 60.00th=[ 1549],
   | 70.00th=[ 1729], 80.00th=[ 1991], 90.00th=[ 2180], 95.00th=[ 2278],
   | 99.00th=[ 2376], 99.50th=[ 9634], 99.90th=[15795], 99.95th=[15795],
   | 99.99th=[15795]

Alcune note:

  1. Nell'esempio precedente, abbiamo regolato i parametri --size и --bs per un caso specifico. Per ottenere un risultato significativo da fio, specifica i valori appropriati per il tuo caso d'uso. Come sceglierli sarà discusso di seguito.
  2. Solo durante i test fio carica il sottosistema del disco. Nella vita reale, è probabile che altri processi scrivano su disco (oltre a quelli relativi a wal_fsync_duration_seconds). Questo carico aggiuntivo può aumentare wal_fsync_duration_seconds. In altre parole, se il 99° percentile del test con fio, solo poco meno di 10 ms, ci sono buone probabilità che le prestazioni di archiviazione non siano sufficienti.
  3. Per il test avrai bisogno della versione fio non inferiore a 3.5, perché le versioni precedenti non aggregano i risultati fdatasync sotto forma di percentili.
  4. La conclusione di cui sopra è solo un piccolo estratto dalla conclusione generale fio.

Maggiori informazioni su fio e etcd

Qualche parola sui WAL, ecc

In genere, i database utilizzano registrazione proattiva (registrazione write-ahead, WAL). etcd è anche influenzato. Una discussione su WAL va oltre lo scopo di questo articolo, ma per i nostri scopi, quello che devi sapere è che ogni membro del cluster etcd archivia WAL in una memoria persistente. etcd scrive alcune operazioni di archiviazione di valori-chiave (come gli aggiornamenti) in WAL prima di eseguirle. Se un nodo si arresta in modo anomalo e si riavvia tra gli snapshot, etcd può ripristinare le transazioni dall'istantanea precedente in base al contenuto del WAL.

Pertanto, ogni volta che un client aggiunge una chiave all'archivio KV o aggiorna il valore di una chiave esistente, etcd aggiunge la descrizione dell'operazione al WAL, che è un normale file nell'archivio persistente. etcd DEVE essere sicuro al 100% che la voce WAL sia stata effettivamente salvata prima di procedere. Per ottenere ciò su Linux, non è sufficiente utilizzare la chiamata di sistema write, poiché l'operazione di scrittura stessa sul supporto fisico potrebbe essere ritardata. Ad esempio, Linux può conservare per un po' di tempo una voce WAL in una cache del kernel in memoria (ad esempio, nella cache della pagina). Per garantire che i dati vengano scritti sul supporto, è necessario richiamare una chiamata di sistema dopo la scrittura fdatasync - questo è esattamente ciò che fa etcd (come puoi vedere nel seguente output strace; Qui 8 - Descrittore file WAL):

21:23:09.894875 lseek(8, 0, SEEK_CUR)   = 12808 <0.000012>
21:23:09.894911 write(8, ".20210220361223255266632$1020103026"34"rn3fo"..., 2296) = 2296 <0.000130>
21:23:09.895041 fdatasync(8)            = 0 <0.008314>

Sfortunatamente, la scrittura su una memoria persistente richiede del tempo. L'esecuzione prolungata delle chiamate fdatasync può influire sulle prestazioni di etcd. Nella documentazione del repository è indicato, che per prestazioni sufficienti è necessario che il 99esimo percentile della durata di tutte le chiamate fdatasync durante la scrittura su un file WAL era inferiore a 10 ms. Esistono altre metriche relative all'archiviazione, ma questo articolo si concentrerà su quella.

Valorizzare lo stoccaggio con fio

È possibile valutare se un determinato spazio di archiviazione è adatto per l'uso con etcd utilizzando l'utilità filo — un popolare tester I/O. Tieni presente che l'I/O su disco può avvenire in molti modi diversi: sync/async, molte classi di chiamate di sistema diverse e così via. L'altra faccia della medaglia è quella fio estremamente difficile da usare. L'utilità ha molti parametri e diverse combinazioni dei loro valori portano a risultati completamente diversi. Per ottenere una stima ragionevole per etcd, è necessario assicurarsi che il carico di scrittura generato da fio sia il più vicino possibile al carico di scrittura del file WAL di etcd:

  • Ciò significa che il file generato fio il caricamento dovrebbe essere almeno una serie di scritture consecutive sul file, in cui ogni scrittura consiste in una chiamata di sistema writeseguito da fdatasync.
  • Per abilitare la scrittura sequenziale è necessario specificare il flag --rw=write.
  • Che fio ha scritto usando le chiamate write (piuttosto che altre chiamate di sistema - per esempio, pwrite), usa la bandiera --ioengine=sync.
  • Infine la bandiera --fdatasync=1 assicura che ogni write deve essere fdatasync.
  • Gli altri due parametri nel nostro esempio sono: --size и --bs - può variare a seconda del caso d'uso specifico. La prossima sezione descriverà la loro configurazione.

Perché abbiamo scelto fio e come abbiamo imparato a configurarlo

Questa nota viene da un caso reale che abbiamo incontrato. Avevamo un cluster su Kubernetes v1.13 con monitoraggio su Prometheus. Gli SSD sono stati usati come storage per etcd v3.2.24. Le metriche Etcd hanno mostrato latenze troppo elevate fdatasync, anche quando il cluster era inattivo. A noi, queste metriche sembravano molto dubbie e non eravamo sicuri di cosa rappresentassero esattamente. Inoltre, il cluster era costituito da macchine virtuali, quindi non era possibile dire se il ritardo fosse dovuto alla virtualizzazione o se la colpa fosse dell'SSD.

Inoltre, abbiamo preso in considerazione vari cambiamenti nella configurazione hardware e software, quindi avevamo bisogno di un modo per valutarli. Naturalmente, sarebbe possibile eseguire etcd in ogni configurazione e guardare le metriche Prometheus corrispondenti, ma ciò richiederebbe uno sforzo significativo. Ciò di cui avevamo bisogno era un modo semplice per valutare una configurazione specifica. Volevamo testare la nostra comprensione delle metriche Prometheus provenienti da etcd.

Ciò ha richiesto la risoluzione di due problemi:

  • Innanzitutto, che aspetto ha il carico I/O generato da etcd durante la scrittura su file WAL? Quali chiamate di sistema vengono utilizzate? Qual è la dimensione dei blocchi di registrazione?
  • In secondo luogo, diciamo che abbiamo le risposte alle domande di cui sopra. Come riprodurre il carico corrispondente con fio? Dopotutto fio — utilità estremamente flessibile con un'abbondanza di parametri (questo è facile da verificare, ad esempio, qui - ca. trad.).

Abbiamo risolto entrambi i problemi con lo stesso approccio basato sui comandi lsof и strace:

  • Con lsof puoi visualizzare tutti i descrittori di file utilizzati dal processo, nonché i file a cui si riferiscono.
  • Con strace puoi analizzare un processo già in esecuzione o eseguire un processo e guardarlo. Il comando visualizza tutte le chiamate di sistema effettuate da questo processo e, se necessario, i suoi discendenti. Quest'ultimo è importante per i processi che si biforcano e etcd è uno di questi processi.

La prima cosa che abbiamo fatto è stata usare strace per esaminare il server etcd nel cluster Kubernetes mentre era inattivo.

Quindi è stato riscontrato che i blocchi di record WAL sono raggruppati in modo molto denso, la dimensione della maggior parte era nell'intervallo di 2200-2400 byte. Ecco perché il comando all'inizio di questo articolo utilizza il flag --bs=2300 (bs è la dimensione in byte di ciascun blocco di scrittura in fio).

Tieni presente che la dimensione dei blocchi di scrittura etcd può variare a seconda della versione, della distribuzione, dei valori dei parametri, ecc. - influisce sulla durata fdatasync. Se hai un caso d'uso simile, analizza con strace i tuoi processi etcd per ottenere valori aggiornati.

Quindi, per avere un'idea chiara ed esaustiva di come funziona etcd con il file system, lo abbiamo avviato da sotto strace con le bandiere -ffttT. Ciò ha reso possibile acquisire i processi figlio e scrivere l'output di ciascuno in un file separato. Inoltre, sono state ottenute informazioni dettagliate sull'ora di inizio e la durata di ciascuna chiamata di sistema.

Abbiamo anche usato il comando lsofper confermare la comprensione dell'output strace in termini di quale descrittore di file è stato utilizzato per quale scopo. Ho avuto la conclusione strace, simile a quello sopra. Le manipolazioni statistiche con i tempi di sincronizzazione hanno confermato che la metrica wal_fsync_duration_seconds da etcd corrisponde alle chiamate fdatasync con descrittori di file WAL.

Per generare con fio un carico di lavoro simile a quello di etcd, è stata studiata la documentazione dell'utilità e sono stati selezionati i parametri adatti al nostro compito. Abbiamo verificato che siano in corso le chiamate di sistema corrette e ne abbiamo confermato la durata eseguendo fio di strace (come è stato fatto in caso di etcd).

Particolare attenzione è stata posta nella determinazione del valore del parametro --size. Rappresenta il carico I/O totale generato dall'utility fio. Nel nostro caso, questo è il numero totale di byte scritti sul supporto. È direttamente proporzionale al numero di chiamate write (e fdatasync). Per uno specifico bs numero di chiamate fdatasync è size / bs.

Poiché eravamo interessati al percentile, volevamo che il numero di campioni fosse abbastanza grande da essere statisticamente significativo. E l'ho deciso 10^4 (che corrisponde a una dimensione di 22 MB) sarà sufficiente. Valori dei parametri più piccoli --size ha dato un rumore più pronunciato (ad esempio, chiamate fdatasync, che richiedono molto più tempo del solito e interessano il 99° percentile).

Tocca a voi

L'articolo mostra come usare fio si può giudicare se il supporto destinato all'uso con etcd è abbastanza veloce. Ora tocca a te! È possibile esplorare le macchine virtuali con l'archiviazione basata su SSD nel servizio IBM Cloud.

PS da traduttore

Con casi d'uso già pronti fio Per altri compiti, cfr documentazione o direttamente a repository di progetti (ce ne sono molti di più di quelli menzionati nella documentazione).

PPS dal traduttore

Leggi anche sul nostro blog:

Fonte: habr.com

Aggiungi un commento