Nota traducătorului.: acest articol este concluzia unei mini-investigații realizate de inginerii IBM Cloud în căutarea unei soluții pentru o problemă reală legată de exploatarea bazei de date etcd. Am avut o problemă similară, dar modul de gândire și acțiunile autorilor ar putea fi interesante și într-un context mai larg.

Rezumatul întregului articol: fio și etcd
Performanța clusterului etcd depinde semnificativ de viteza stocării care îl susține. Pentru a monitoriza performanța, etcd exportă diverse metrici Prometheus. Una dintre acestea este wal_fsync_duration_seconds. În documentația pentru etcd , stocarea poate fi considerată suficient de rapidă dacă percentila de 99% a acestei metrici nu depășește 10 ms…
Dacă luați în considerare posibilitatea de a organiza un cluster etcd pe mașini ce rulează Linux și doriți să verificați dacă stocările sunt suficient de rapide (de exemplu, SSD), vă recomandăm să utilizați popularul tester I/O numit . Trebuie doar să rulați următoarea comandă (directorul test-data trebuie să fie situat în sistemul de fișiere montat al stocării supuse testării):
fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytestRămâne doar să verificați ieșirea și să vedeți dacă percentila de 99% a este în 10 ms. Dacă da, atunci stocarea dvs. funcționează suficient de rapid. Iată un exemplu de ieșire:
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]Câteva observații:
- În exemplul de mai sus am ajustat parametrii
--sizeși--bspentru un caz specific. Pentru a obține un rezultat semnificativ de lafio, specificați valori adecvate pentru scenariul dvs. de utilizare. Cum să le alegeți va fi explicat mai jos. - În timpul testării, doar
fiosubliniem subsistemul de stocare. În viața reală este foarte probabil ca pe disc să scrie și alte procese (în afară de cele legate dewal_fsync_duration_seconds). Această sarcină suplimentară poate duce la o creștere awal_fsync_duration_seconds. Cu alte cuvinte, dacă percentila de 99% obținută în urma testării cufio, doar puțin mai puțin de 10 ms, există o mare probabilitate ca performanța stocării să fie insuficientă. - Pentru test, veți avea nevoie de versiunea
fiode 3.5 sau mai recentă, deoarece versiunile mai vechi nu agregă rezultatelefdatasyncsub formă de percentili. - Iată ieșirea de mai sus care reprezintă doar un mic fragment din totalitatea ieșirii
fio.
Detalii despre fio și etcd
Câteva cuvinte despre WAL-urile etcd
În general, bazele de date utilizează (write-ahead logging, WAL). Acest lucru se aplică și pentru etcd. Discuția despre WAL depășește scopul acestui articol, dar pentru obiectivele noastre trebuie să știm următoarele: fiecare membru al clusterului etcd stochează WAL în stocarea permanentă. etcd înregistrează unele operațiuni cu stocarea key-value (de exemplu, actualizări) în WAL înainte de a le executa. Dacă un nod se prăbușește și se repornește între snapshot-uri, etcd poate restaura tranzacțiile efectuate de la ultimul snapshot, bazându-se pe conținutul WAL.
Astfel, de fiecare dată când un client adaugă o cheie în stocarea KV sau actualizează valoarea unei chei existente, etcd adaugă o descriere a operațiunii în WAL, care este un fișier obișnuit în stocarea permanentă. Înainte de a continua, etcd TREBUIE să fie 100% sigură că înregistrarea în WAL este efectiv salvată. Pentru a realiza acest lucru în Linux, nu este suficient să folosiți apelul de sistem , deoarece însăși operațiunea de scriere pe suportul fizic poate fi amânată. De exemplu, Linux poate menține înregistrarea WAL în cache-ul kernel-ului în memorie pentru o perioadă de timp (de exemplu, în cache-ul de pagini). Pentru a garanta că datele sunt scrise pe suport, după scriere trebuie să angajați apelul de sistem fdatasync — exact așa procedează etcd (așa cum se arată în următoarea ieșire ; aici 8 — descriptorul de fișier 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 Din păcate, scrierea în stocarea permanentă durează ceva timp. Întârzierea în executarea apelului fdatasync poate afecta performanța etcd. În documentația stocării , se menționează că pentru o performanță satisfăcătoare este necesar ca percentilul 99 al duratei tuturor apelurilor fdatasync scrierea în fișierul WAL a fost mai mică de 10 ms. Există și alte metrice legate de stocare, dar în acest articol ne vom concentra asupra acesteia.
Evaluăm stocarea folosind fio
Pentru a evalua dacă o anumită soluție de stocare este potrivită pentru utilizarea cu etcd, putem folosi utilitarul — un tester I/O popular. Rețineți că I/O-ul de disc poate funcționa în moduri diferite: sincron/asincron, numeroase clase diferite de apeluri system și așa mai departe. Partea mai puțin plăcută este că fio este extrem de complicat de utilizat. Utilitarul are multe opțiuni, iar combinațiile diferitelor valori ale acestora duc la rezultate complet diferite. Pentru a obține o evaluare decentă în cazul etcd, trebuie să vă asigurați că sarcina de scriere generată de fio se aseamănă cât mai mult cu sarcina etcd în timpul scrierii în fișierele WAL:
- Aceasta înseamnă că sarcina generată
fioar trebui, cel puțin, să fie o serie de scrieri secvențiale în fișier, unde fiecare operațiune de scriere constă dintr-un apel de sistem , urmat defdatasync. - Pentru a activa scrierea secvențială, trebuie să specificați flagul
--rw=write. - Pentru a
fiocare scria folosind apeluriwrite(și nu alte apeluri de sistem — de exemplu, ), folosiți flagul--ioengine=sync. - În fine, flagul
--fdatasync=1garantează că după fiecarewriteurmăreștefdatasync. - Celelalte două opțiuni din exemplul nostru:
--sizeși--bs— pot varia în funcție de scenariul specific de utilizare. În secțiunea următoare, vom discuta despre configurarea acestora.
De ce am ales fio și de unde am învățat cum să-l configurăm
Această notă a apărut dintr-un caz real cu care ne-am confruntat. Am avut un cluster pe Kubernetes v1.13 cu monitorizare pe Prometheus. Ca soluție de stocare pentru etcd v3.2.24 am folosit SSD-uri. Metricele etcd arătau întârzieri prea mari fdatasync, chiar și atunci când clusterul era inactiv. Ni s-au părut foarte dubioase aceste metrice și nu am fost siguri ce exact reprezentau. În plus, clusterul era format din mașini virtuale, așa că nu puteam determina dacă întârzierile erau legate de virtualizare sau din cauza SSD-urilor.
În plus, am analizat diferite modificări ale configurației hardware și software, de aceea aveam nevoie de o modalitate de evaluare. Desigur, am fi putut rula etcd în fiecare configurație și să observăm metricile corespunzătoare din Prometheus, dar acest lucru ar fi necesitat eforturi considerabile. Aveam nevoie de o metodă simplă pentru a evalua o configurație specifică. Voiam să ne verificăm înțelegerea metricalor Prometheus venind de la etcd.
Pentru asta, a fost necesar să rezolvăm două probleme:
- În primul rând, cum arată încărcătura I/O generată de etcd atunci când scrie în fișierele WAL? Ce apeluri de sistem sunt folosite? Care este dimensiunea blocurilor de scriere?
- În al doilea rând, să presupunem că avem răspunsurile la întrebările de mai sus. Cum putem reproduce încărcătura corespunzătoare cu
fio? Ведьfio— un instrument extrem de flexibil, cu o mulțime de parametrii (este ușor de văzut, de exemplu, — nt. trad.).
Am rezolvat ambele probleme folosind aceeași abordare bazată pe comenzi și :
- Folosind
lsofputem vizualiza toate descriptorii de fișiere utilizați de proces, precum și fișierele la care se referă. - Folosind
straceputem analiza un proces care rulează deja sau putem porni un proces și să-l monitorizăm. Comanda afișează toate apelurile de sistem efectuate de acest proces și, dacă este necesar, de descendantii săi. Acest lucru este important pentru procesele care se fork-uiesc, iar etcd este unul dintre aceste procese.
Primul lucru pe care l-am făcut a fost să folosim strace pentru a explora serverul etcd din clusterul Kubernetes, în timp ce acesta era inactiv.
Astfel, s-a descoperit că blocurile de scriere în WAL sunt foarte strâns grupate, marea majoritate având dimensiuni în intervalul 2200-2400 de bytes. De aceea, în comanda menționată la începutul acestui articol, este folosită flaul --bs=2300 (bs — dimensiunea în bytes a fiecărui bloc de scriere în fio).
Rețineți că dimensiunea blocurilor de scriere etcd poate varia în funcție de versiune, desfășurare, valori ale parametrilor etc. — acest lucru afectează durata fdatasync. Dacă aveți un scenariu de utilizare similar, analizați cu ajutorul strace procesele dvs. etcd pentru a obține valori actualizate.
Apoi, pentru a obține o înțelegere clară și cuprinzătoare a modului în care etcd interacționează cu sistemul de fișiere, l-am rulat din strace cu flag-urile -ffttT. Acest lucru a permis acoperirea proceselor descendente și înregistrarea ieșirii fiecăreia într-un fișier separat. De asemenea, s-au obținut informații detaliate despre momentul de start și durata fiecărei apeluri de sistem.
Am folosit de asemenea comanda lsof, pentru a ne confirma înțelegerea ieșirii strace în ceea ce privește care descriptor de fișier a fost folosit pentru ce scop. A rezultat o ieșire strace, similară cu cea menționată mai sus. Manipulările statistice cu timpii de sincronizare au confirmat că metrica wal_fsync_duration_seconds de la etcd corespunde apelurilor fdatasync cu descriptorii de fișiere WAL.
Pentru a genera fio o sarcină de lucru similară celei de la etcd, a fost studiată documentația utilitarului și au fost selectate parametrii potriviți pentru sarcina noastră. Ne-am asigurat că apelurile de sistem necesare sunt utilizate și am confirmat durata acestora, executând fio din strace (așa cum s-a făcut în cazul etcd).
O atenție deosebită a fost acordată determinării valorii parametrului --size. Acesta reprezintă încărcătura totală I/O generată de utilitarul fio. În cazul nostru, este numărul total de octeți scriși pe suport. Acesta este direct proporțional cu numărul de apeluri write Volume Provisioning fdatasync). Pentru un anumit bs numărul de apeluri fdatasync este egal cu size / bs.
Deoarece ne interesa percentila, am dorit ca numărul de probe să fie suficient de mare pentru semnificație statistică. Am decis că 10^4 (ceea ce corespunde unei dimensiuni de 22 Mb) va fi suficient. Valorile mai mici ale parametrului --size au generat un zgomot mai pronunțat (de exemplu, apeluri fdatasync, care durează mult mai mult decât de obicei și influențează percentila de 99).
Acum depinde de tine
În acest articol se arată cum fio poate evalua dacă suportul destinat utilizării cu etcd este suficient de rapid. Acum depinde de tine! Poți explora mașinile virtuale cu stocare bazată pe SSD în serviciul .
P.S. de la traducător
Pentru exemple de utilizare fio pentru alte probleme, poți consulta sau direct în (acolo sunt prezentate mult mai multe decât sunt menționate în documentație).
P.P.S. de la traducător
Citiți și în blogul nostru:
- «»;
- «»;
- «».
Sursa: habr.com
