Cum să verificați discurile cu fio pentru performanță suficientă pentru etcd

Notă. transl.: Acest articol este rezultatul unei mini-cercetări efectuate de inginerii IBM Cloud în căutarea unei soluții la o problemă reală legată de funcționarea bazei de date etcd. O sarcină similară a fost relevantă pentru noi, însă cursul reflecțiilor și acțiunilor autorilor poate fi interesant într-un context mai larg.

Cum să verificați discurile cu fio pentru performanță suficientă pentru etcd

Scurt rezumat al întregului articol: fio și etcd

Performanța unui cluster etcd depinde foarte mult de viteza stocării de bază. etcd exportă diverse valori Prometheus pentru a monitoriza performanța. Unul dintre ei este wal_fsync_duration_seconds. În documentația pentru etcd se spuneacea stocare poate fi considerată suficient de rapidă dacă percentila 99 a acestei valori nu depășește 10 ms...

Dacă vă gândiți să configurați un cluster etcd pe mașinile Linux și doriți să verificați dacă unitățile (cum ar fi SSD-urile) sunt suficient de rapide, vă recomandăm să utilizați popularul tester I/O numit fir. Este suficient să rulați următoarea comandă (director test-data trebuie să fie amplasat în partiția montată a unității testate):

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

Rămâne doar să privim rezultatul și să verificați dacă percentila 99 se potrivește fdatasync în 10 ms. Dacă da, atunci unitatea dumneavoastră funcționează suficient de repede. 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 note:

  1. În exemplul de mai sus, am ajustat parametrii --size и --bs pentru un caz anume. Pentru a obține un rezultat semnificativ din fio, specificați valori adecvate pentru cazul dvs. de utilizare. Cum să le alegeți va fi discutat mai jos.
  2. Numai în timpul testării fio încarcă subsistemul de disc. În viața reală, este probabil ca alte procese să scrie pe disc (în afară de cele legate de wal_fsync_duration_seconds). Această sarcină suplimentară poate crește wal_fsync_duration_seconds. Cu alte cuvinte, dacă percentila 99 de la testare cu fio, doar puțin mai puțin de 10 ms, există șanse mari ca performanța de stocare să nu fie suficientă.
  3. Pentru test veți avea nevoie de versiunea fio nu mai mic de 3.5, deoarece versiunile mai vechi nu cumulează rezultatele fdatasync sub formă de percentile.
  4. Concluzia de mai sus este doar un mic fragment din concluzia generală fio.

Mai multe despre fio și etcd

Câteva cuvinte despre WAL etcd

În general, bazele de date folosesc înregistrare proactivă (înregistrare scriere anticipată, WAL). etcd este de asemenea afectat. O discuție despre WAL depășește scopul acestui articol, dar în scopurile noastre, ceea ce trebuie să știți este că fiecare membru al clusterului etcd stochează WAL în stocare persistentă. etcd scrie unele operațiuni de stocare cheie-valoare (cum ar fi actualizări) în WAL înainte de a le executa. Dacă un nod se blochează și repornește între instantanee, etcd poate recupera tranzacțiile de la instantaneul anterior pe baza conținutului WAL.

Astfel, de fiecare dată când un client adaugă o cheie în magazinul KV sau actualizează valoarea unei chei existente, etcd adaugă descrierea operației la WAL, care este un fișier obișnuit în magazinul persistent. etcd TREBUIE să fie 100% sigur că intrarea WAL a fost de fapt salvată înainte de a continua. Pentru a realiza acest lucru pe Linux, nu este suficient să folosiți apelul de sistem write, deoarece operația de scriere în sine pe suportul fizic poate fi întârziată. De exemplu, Linux poate păstra o intrare WAL într-un cache al nucleului în memorie (de exemplu, în memoria cache a paginii) pentru ceva timp. Pentru a vă asigura că datele sunt scrise pe suport, trebuie invocat un apel de sistem după scriere fdatasync - asta este exact ceea ce face etcd (după cum puteți vedea în următoarea ieșire strace; Aici 8 - Descriptor de fișier 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>

Din păcate, scrierea în stocarea persistentă durează ceva timp. Execuția prelungită a apelurilor fdatasync poate afecta performanța etcd. În documentația depozitului indicat, că pentru o performanță suficientă este necesar ca percentila 99 din durata tuturor apelurilor fdatasync când scrierea într-un fișier WAL a fost mai mică de 10 ms. Există și alte valori legate de stocare, dar acest articol se va concentra pe acesta.

Evaluarea stocării cu fio

Puteți evalua dacă o anumită stocare este potrivită pentru utilizare cu etcd folosind utilitarul fir — un tester I/O popular. Rețineți că I/O pe disc se poate întâmpla în multe moduri diferite: sincronizare/async, multe clase diferite de apelare sistem și așa mai departe. Cealaltă parte a monedei este că fio extrem de greu de utilizat. Utilitarul are mulți parametri, iar combinațiile diferite ale valorilor acestora duc la rezultate complet diferite. Pentru a obține o estimare rezonabilă pentru etcd, trebuie să vă asigurați că sarcina de scriere generată de fio este cât mai aproape posibil de încărcarea de scriere a fișierului WAL al etcd:

  • Aceasta înseamnă că generat fio încărcarea ar trebui să fie cel puțin o serie de scrieri consecutive în fișier, unde fiecare scriere constă dintr-un apel de sistem writeurmată de fdatasync.
  • Pentru a activa scrierea secvențială, trebuie să specificați steag-ul --rw=write.
  • fio scris folosind apeluri write (mai degrabă decât alte apeluri de sistem - de exemplu, pwrite), folosiți steagul --ioengine=sync.
  • În sfârșit, steagul --fdatasync=1 asigură că fiecare writefdatasync.
  • Ceilalți doi parametri din exemplul nostru sunt: --size и --bs - poate varia în funcție de cazul specific de utilizare. Următoarea secțiune va descrie configurația lor.

De ce am ales fio și cum am învățat cum să-l configuram

Această notă provine dintr-un caz real pe care l-am întâlnit. Aveam un cluster pe Kubernetes v1.13 cu monitorizare pe Prometheus. SSD-urile au fost folosite ca stocare pentru etcd v3.2.24. Valorile Etcd au arătat latențe prea mari fdatasync, chiar și atunci când clusterul era inactiv. Pentru noi, aceste valori ni s-au părut foarte dubioase și nu eram siguri ce reprezintă exact. În plus, clusterul era format din mașini virtuale, așa că nu se putea spune dacă întârzierea se datora virtualizării sau SSD-ul era de vină.

În plus, am luat în considerare diverse modificări ale configurației hardware și software, așa că aveam nevoie de o modalitate de a le evalua. Desigur, ar fi posibil să rulați etcd în fiecare configurație și să vă uitați la valorile Prometheus corespunzătoare, dar asta ar necesita un efort semnificativ. Ceea ce aveam nevoie era o modalitate simplă de a evalua o anumită configurație. Am vrut să ne testăm înțelegerea valorilor Prometheus care provin de la etcd.

Aceasta a necesitat rezolvarea a două probleme:

  • În primul rând, cum arată încărcarea I/O generată de etcd când scrieți în fișiere WAL? Ce apeluri de sistem sunt folosite? Care este dimensiunea blocurilor de înregistrare?
  • În al doilea rând, să presupunem că avem răspunsuri la întrebările de mai sus. Cum se reproduce sarcina corespunzătoare cu fio? Dupa toate acestea fio — utilitate extrem de flexibilă, cu o mulțime de parametri (acest lucru este ușor de verificat, de exemplu, aici - aprox. traducere).

Am rezolvat ambele probleme cu aceeași abordare bazată pe comandă lsof и strace:

  • Cu lsof puteți vizualiza toți descriptorii de fișier utilizați de proces, precum și fișierele la care se referă.
  • Cu strace puteți analiza un proces care rulează deja sau puteți rula un proces și vizionați-l. Comanda afișează toate apelurile de sistem efectuate de acest proces și, dacă este necesar, descendenții acestuia. Acesta din urmă este important pentru procesele care se bifurcă, iar etcd este un astfel de proces.

Primul lucru pe care l-am făcut a fost să folosim strace pentru a examina serverul etcd din clusterul Kubernetes în timp ce acesta era inactiv.

Așa că s-a constatat că blocurile de înregistrări WAL sunt foarte dens grupate, dimensiunea majorității era în intervalul 2200-2400 de octeți. De aceea, comanda de la începutul acestui articol folosește steag --bs=2300 (bs este dimensiunea în octeți a fiecărui bloc de scriere în fio).

Vă rugăm să rețineți că dimensiunea blocurilor de scriere etcd poate varia în funcție de versiune, implementare, valorile parametrilor etc. - afectează durata fdatasync. Dacă aveți un caz de utilizare similar, analizați cu strace procesele dvs. etcd pentru a obține valori actualizate.

Apoi, pentru a ne face o idee clară și cuprinzătoare despre cum funcționează etcd cu sistemul de fișiere, am început-o de sub strace cu steaguri -ffttT. Acest lucru a făcut posibilă capturarea proceselor copil și scrierea ieșirii fiecăruia într-un fișier separat. În plus, au fost obținute informații detaliate despre ora de începere și durata fiecărui apel de sistem.

Am folosit și comanda lsofpentru a vă confirma înțelegerea rezultatului strace în ceea ce privește ce descriptor de fișier a fost utilizat în ce scop. Am ajuns la concluzia strace, similar cu cel de mai sus. Manipulările statistice cu timpii de sincronizare au confirmat că metrica wal_fsync_duration_seconds din apeluri de meciuri etcd fdatasync cu descriptori de fișiere WAL.

A genera cu fio un volum de lucru similar cu cel de la etcd, s-a studiat documentația utilitarului și s-au selectat parametrii potriviți sarcinii noastre. Am verificat că apelurile de sistem corecte sunt în curs și am confirmat durata lor prin rulare fio de strace (cum s-a făcut în cazul etcd).

O atenție deosebită a fost acordată determinării valorii parametrului --size. Reprezintă sarcina totală I/O generată de utilitarul fio. În cazul nostru, acesta este numărul total de octeți scriși pe media. Este direct proporțional cu numărul de apeluri write (și fdatasync). Pentru un anume bs numărul de apeluri fdatasync este size / bs.

Deoarece eram interesați de percentilă, am dorit ca numărul de eșantioane să fie suficient de mare pentru a fi semnificativ statistic. Și a decis că 10^4 (care corespunde unei dimensiuni de 22 MB) va fi suficient. Valori mai mici ale parametrilor --size a dat un zgomot mai pronunțat (de exemplu, apeluri fdatasync, care durează mult mai mult decât de obicei și afectează percentila 99).

Depinde de tine

Articolul arată cum se utilizează fio se poate judeca dacă media destinată utilizării cu etcd este suficient de rapidă. Acum depinde de tine! Puteți explora mașini virtuale cu stocare bazată pe SSD în serviciu IBM Cloud.

PS de la traducator

Cu cazuri de utilizare gata făcute fio Pentru alte sarcini, vezi documentație sau direct către depozite de proiecte (sunt mult mai multe decât cele menționate în documentație).

PPS de la traducător

Citește și pe blogul nostru:

Sursa: www.habr.com

Adauga un comentariu