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.

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 , 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 . 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=mytestRimane solo da esaminare l'output e verificare se rientra nel 99° percentile 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:
- Nell'esempio sopra, abbiamo adattato i parametri
--sizee--bsper un caso specifico. Per ottenere un risultato significativo dafio, specifica valori adatti al tuo scenario d'uso. Di seguito ti spiegheremo come sceglierli. - Durante il test, solo
fiocarica il sottosistema disco. Nella vita reale, è probabile che altri processi scrivano sul disco (oltre a quelli relativi awal_fsync_duration_seconds). Tale carico aggiuntivo potrebbe portare a un aumento diwal_fsync_duration_seconds. In altre parole, se il 99° percentile ottenuto al termine del test confio, è solo leggermente inferiore a 10 ms, è probabile che le prestazioni di archiviazione siano insufficienti. - Per il test avrete bisogno di una versione
fionon inferiore alla 3.5, poiché le versioni precedenti non aggregano i risultatifdatasyncsotto forma di percentili. - 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 (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 , 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 ; 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 , è 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à — 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
fiodeve rappresentare almeno una serie di scritture sequenziali nel file, dove ogni operazione di scrittura consiste in una chiamata di sistema , seguita dafdatasync. - 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:
fioha scritto utilizzando le chiamatewrite(e non altre chiamate di sistema — ad esempio, ), utilizzare il flag--ioengine=sync. - Infine, il flag
--fdatasync=1garantisce che ogniwriteè necessariofdatasync. - Altri due parametri nel nostro esempio:
--sizee--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, — nota del traduttore).
Abbiamo affrontato entrambi i problemi con lo stesso approccio, basato sui comandi e :
- 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 .
P.S. dal traduttore
Con esempi pratici fio per altre soluzioni sono disponibili in o direttamente in (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
