Come verificare le prestazioni dei dischi con fio per etcd

Nota del traduttore.: questo articolo riassume uno studio condotto dagli ingegneri di IBM Cloud alla ricerca di una soluzione a un reale problema nell'utilizzo del database etcd. La nostra situazione era simile, ma il ragionamento e le azioni degli autori potrebbero essere interessanti anche in un contesto più ampio.

Come verificare le prestazioni dei dischi con fio per etcd

Sintesi dell'intero articolo: fio e etcd

Le prestazioni del cluster etcd dipendono fortemente dalla velocità dello storage sottostante. Per monitorare le prestazioni, etcd esporta varie metriche di Prometheus. Una di queste è wal_fsync_duration_seconds. Nella documentazione di etcd si afferma, che uno storage può essere considerato sufficientemente veloce se il 99° percentile di questa metrica non supera i 10 ms…

Se stai considerando di organizzare un cluster etcd su macchine con Linux e vuoi verificare se gli storage (ad esempio, SSD) siano sufficientemente veloci, ti consigliamo di utilizzare un popolare strumento di test I/O chiamato fio. Basta eseguire il seguente comando (la directory test-data deve trovarsi nella partizione montata dello storage testato):

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

Rimane solo da esaminare l'output e verificare se rientra nel 99° percentile fdatasync in 10 ms. Se è così, significa che il tuo dispositivo di archiviazione 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 percentili (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]

Alcuni commenti:

  1. Nell'esempio sopra, abbiamo adattato i parametri --size e --bs per un caso specifico. Per ottenere un risultato significativo da fio, specifica valori adatti al tuo scenario d'uso. Di seguito ti spiegheremo come sceglierli.
  2. Durante il test, solo fio carica il sottosistema disco. Nella vita reale, è probabile che altri processi scrivano sul disco (oltre a quelli relativi a wal_fsync_duration_seconds). Tale carico aggiuntivo potrebbe portare a un aumento di wal_fsync_duration_seconds. In altre parole, se il 99° percentile ottenuto al termine del test con fio, è solo leggermente inferiore a 10 ms, è probabile che le prestazioni di archiviazione siano insufficienti.
  3. Per il test avrete bisogno di una versione fio non inferiore alla 3.5, poiché le versioni precedenti non aggregano i risultati fdatasync sotto forma di percentili.
  4. L'output sopra riportato rappresenta solo un piccolo estratto dell'output complessivo fio.

Approfondimenti su fio ed etcd

Alcune parole sui WAL di etcd

In generale, i database utilizzano la registrazione anticipata (write-ahead logging, WAL). Anche etcd riguarda questo. La discussione sui WAL va oltre lo scopo di questo articolo, tuttavia, per i nostri scopi, è importante sapere che: ogni membro del cluster etcd conserva il WAL in uno storage permanente. etcd registra alcune operazioni sul key-value store (ad esempio, aggiornamenti) nel WAL, prima di eseguirle. Se un nodo si arresta e si riavvia nel periodo tra gli snapshot, etcd sarà in grado di ripristinare le transazioni effettuate dall'ultimo snapshot, facendo riferimento al contenuto del WAL.

Pertanto, ogni volta che un cliente aggiunge una chiave allo store KV o aggiorna il valore di una chiave esistente, etcd registra la descrizione dell'operazione nel WAL, che è un file normale nello storage permanente. Prima di continuare a lavorare, etcd DEVE essere al 100% certo che la registrazione nel WAL sia realmente salvata. Per ottenere questo in Linux, non basta utilizzare una chiamata di sistema write, poiché l'operazione di scrittura su supporto fisico può essere ritardata. Ad esempio, Linux può mantenere la registrazione WAL nella cache del kernel in memoria (ad esempio, nella cache delle pagine) per un certo periodo. Per garantire che i dati siano scritti sul supporto, dopo la scrittura è necessario attivare una chiamata di sistema fdatasync — ed è proprio così che agisce etcd (come si vede nel seguente output strace; qui 8 — il descrittore del file WAL):

21:23:09.894875 lseek(8, 0, SEEK_CUR)   = 12808 
21:23:09.894911 write(8, ".      20210220361223255266632$10 20103026"34"rn3fo"..., 2296) = 2296 
21:23:09.895041 fdatasync(8)            = 0

Sfortunatamente, la registrazione nello storage permanente richiede del tempo. Un'esecuzione prolungata della chiamata fdatasync può influire sulle prestazioni di etcd. Nella documentazione dello storage che si indica, è necessario che il 99° percentile della durata di tutte le chiamate sia sufficiente per garantire prestazioni adeguate. fdatasync Quando si scrive nel file WAL deve essere inferiore a 10 ms. Ci sono altre metriche relative allo storage, ma in questo articolo parleremo specificamente di questa.

Valutiamo lo storage usando fio.

Per valutare se un certo storage è adatto per l'uso con etcd, è possibile utilizzare l'utilità fio — un popolare tester I/O. Tieni presente che l'input/output su disco può avvenire in modi diversi: sync/async, molteplici classi di chiamate di sistema, ecc. Il rovescio della medaglia è che fio è estremamente complesso da usare. L'utilità ha molte opzioni e diverse combinazioni dei loro valori portano a risultati completamente diversi. Per ottenere una valutazione significativa nel caso di etcd, è necessario assicurarsi che il carico di scrittura generato da fio assomigli il più possibile al carico di etcd durante la scrittura nei file WAL:

  • Questo significa che il carico generato fio deve rappresentare almeno una serie di scritture sequenziali nel file, dove ogni operazione di scrittura consiste in una chiamata di sistema write, seguita da fdatasync.
  • Per attivare la scrittura sequenziale, è necessario specificare il flag --rw=write.
  • Per creare un file di esportazione del database di gestione sul server di origine: fio ha scritto utilizzando le chiamate write (e non altre chiamate di sistema — ad esempio, pwrite), utilizzare il flag --ioengine=sync.
  • Infine, il flag --fdatasync=1 garantisce che ogni write è necessario fdatasync.
  • Altri due parametri nel nostro esempio: --size e --bs — possono variare a seconda dello specifico scenario d'uso. Nella prossima sezione sarà descritta la loro configurazione.

Perché abbiamo scelto fio e come abbiamo imparato a configurarlo

Questa nota è emersa da un caso reale con cui ci siamo trovati. Avevamo un cluster su Kubernetes v1.13 con monitoraggio su Prometheus. Come archivio per etcd v3.2.24 abbiamo utilizzato SSD. Le metriche di etcd mostravano latenze troppo elevate fdatasync, anche quando il cluster era inattivo. Queste metriche ci sembravano piuttosto sospette e non eravamo sicuri di cosa rappresentassero esattamente. Inoltre, il cluster era composto da macchine virtuali, quindi non riuscivamo a capire se la latenza fosse dovuta alla virtualizzazione o se fosse colpa degli SSD.

Inoltre, abbiamo esaminato diverse modifiche alla configurazione dell'hardware e del software, quindi era necessario un modo per valutarle. Naturalmente, si potrebbe eseguire etcd in ogni configurazione e osservare le metriche corrispondenti di Prometheus, ma ciò richiederebbe uno sforzo significativo. Avevamo bisogno di un modo semplice per valutare una configurazione specifica. Volevamo verificare la nostra comprensione delle metriche di Prometheus provenienti da etcd.

Per questo, era necessario risolvere due problemi:

  • Innanzitutto, quale carico di I/O viene generato da etcd durante la scrittura nei file WAL? Quali chiamate di sistema vengono utilizzate? Qual è la dimensione dei blocchi di scrittura?
  • In secondo luogo, supponiamo di avere le risposte alle domande sopra menzionate. Come riprodurre il carico corrispondente con fio? Ведь fio — un'utilità straordinariamente flessibile con una miriade di parametri (è facile verificarlo, ad esempio, qui — nota del traduttore).

Abbiamo affrontato entrambi i problemi con lo stesso approccio, basato sui comandi lsof e strace:

  • Con lsof è possibile visualizzare tutte le descrittive dei file utilizzati dal processo, così come i file a cui si riferiscono.
  • Con strace è possibile analizzare un processo già in esecuzione o avviare un processo e osservarlo. Il comando mostra tutte le chiamate di sistema effettuate da questo processo e, se necessario, dai suoi processi figli. Quest'ultimo aspetto è importante per i processi che si biforcano, e etcd è uno di questi processi.

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

È stato così rilevato che i blocchi di scrittura nel WAL sono molto densamente raggruppati, la dimensione della maggior parte era compresa tra 2200 e 2400 byte. Per questo motivo, nel comando all'inizio di questo articolo è stato utilizzato il flag --bs=2300 (bs — la dimensione in byte di ogni blocco di scrittura in fio).

Si noti che la dimensione dei blocchi di scrittura di etcd può variare a seconda della versione, del deployment, dei valori dei parametri, ecc. — questo influisce sulla durata fdatasync. Se hai un caso d'uso simile, analizza con strace i tuoi processi etcd per ottenere valori attuali.

Quindi, per avere una chiara e completa comprensione del funzionamento di etcd con il filesystem, lo abbiamo avviato da strace con i flag -ffttT. Questo ha permesso di coprire i processi figlio e registrare l'output di ognuno in un file separato. Inoltre, sono state ottenute informazioni dettagliate sul momento di avvio e sulla durata di ogni chiamata di sistema.

Abbiamo anche utilizzato il comando lsof, per confermare la nostra comprensione dell'output strace in termini di quale descrittore di file fosse utilizzato per quale scopo. L'output risultante è stato strace, simile a quello mostrato sopra. Le manipolazioni statistiche sui tempi di sincronizzazione hanno confermato che la metrica wal_fsync_duration_seconds di etcd corrisponde alle chiamate fdatasync con i descrittori di file WAL.

Per generare un carico di lavoro simile a quello di etcd, è stata esaminata la documentazione dello strumento e sono stati selezionati i parametri più adatti al nostro compito. Ci siamo assicurati che fossero coinvolte le giuste chiamate di sistema e abbiamo confermato la loro durata, eseguendo fio (come è stato fatto nel caso di etcd). fio di strace Particolare attenzione è stata data alla definizione del valore del parametro

. Esso rappresenta il carico totale I/O generato dallo strumento fio. Nel nostro caso, si tratta del numero totale di byte scritti sul dispositivo. È direttamente proporzionale al numero di chiamate --size). Per un dato write (e fdatasync). Для определенного bs numero di chiamate fdatasync è uguale a dimensione / bs.

Poiché eravamo interessati al percentile, ci siamo assicurati che il numero di campioni fosse sufficientemente grande per una significatività statistica. Abbiamo deciso che 10^4 (corrispondente a una dimensione di 22 MB) sarebbe stato sufficiente. Valori inferiori della parametrizzazione --size davano un rumore più pronunciato (ad esempio, chiamate fdatasync, che richiedono molto più tempo del solito e influiscono sul 99° percentile).

A voi la scelta

L'articolo mostra come fio è possibile valutare se un'unità di archiviazione destinata all'uso con etcd è sufficientemente veloce. Ora tocca a voi! Potete esplorare macchine virtuali con storage basato su SSD nel servizio IBM Cloud.

P.S. dal traduttore

Con esempi pratici fio per altre soluzioni sono disponibili in documentazione o direttamente in il repository del progetto (ce ne sono molti di più rispetto a quanti ne menziona la documentazione).

P.P.S. dal traduttore

Leggete anche nel nostro blog:

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster