Inspeksjon disk IO ytelse med fio


Lagring ytelsen har ikke klart å holde tritt med det av andre viktige komponenter i datasystemer. Harddisker har fått større, men hastigheten har ikke holdt tritt med de relative hastighetsforbedringer i RAM og CPU-teknologi. Potensialet for harddisken for å være systemets ytelse flaskehals gjør å vite hvor fort dine disker og filsystemer er og få kvantitative målinger på eventuelle forbedringer du kan gjøre til disk subsystem viktig. En måte å gjøre disktilgang raskere er å bruke flere disker i kombinasjon, som i et RAID-5-konfigurasjon.



For å få en viss idé om hvor fort en fysisk disk kan nås fra Linux kan du bruke hdparm verktøy med -T og -t alternativer. Den -T alternativ utnyttet Linux disk cache og gir en indikasjon på hvor mye informasjon systemet kan lese fra en disk om disken var rask nok til å holde følge. Valget -t leser også disken gjennom cache, men uten noen precaching resultater. Dermed kan -t gi et inntrykk av hvor raskt en disk kan levere informasjon som er lagret sekvensielt på disk.

hdparm verktøyet er ikke den beste indikatoren på reell ytelse. Den opererer på et svært lavt nivå; når du plasserer et filsystem på en partisjon du kan få vesentlig forskjellige resultater. Du vil også se store forskjeller i hastighet mellom sekvensiell tilgang og random access. Det ville også være bra å kunne benchmark et filsystem som er lagret på en gruppe av diskene i et RAID-konfigurasjon.

fio ble opprettet for å tillate benchmarking bestemt disk IO arbeidsbelastninger. Det kan utstede sine IO forespørsler ved hjelp av en av mange synkrone og asynkrone IO APIer, og kan også bruke ulike programmeringsgrensesnitt som gjør at mange IO forespørsler om å få utstedt et enkelt API-kall. Du kan også stille inn hvor store filene FIO bruker er, hva forskyvninger i disse filene IO som skal skje på, hvor mye forsinkelse hvis noen er det mellom å utstede IO forespørsler, og hva om er utstedt noen filsystem sync samtaler mellom hver IO forespørsel. En sync samtalen forteller operativsystemet for å sørge for at all informasjon som er lagret i minnet har blitt lagret på disken og kan dermed innføre en betydelig forsinkelse. Alternativene til FIO tillate deg å utstede svært presist definerte IO mønstre og se hvor lang tid det tar disken delsystem for å fullføre disse oppgavene.

fio er pakket i standard oppbevaringssted for Fedora 8 og er tilgjengelig for opensuse gjennom opensuse Build Service. Brukere av Debian-baserte distribusjoner må kompilere fra kilden med make; sudo make install kombinasjon.

Den første testen du kanskje har lyst til å utføre er for tilfeldig lese IO ytelse. Dette er en av de styggeste IO belastninger som kan utstedes til en disk, fordi det fører til at disken hodet til å søke mye, og disken hodet søker er ekstremt trege operasjoner i forhold til andre harddisk operasjoner. Ett område hvor tilfeldig disk ønsker pass kan utstedes i reelle søknader er under påføring oppstart, når filer forespurt fra hele harddisken. Du angir Fio benchmarks bruker konfigurasjonsfiler med en ini-fil format. Du trenger bare et par parametere for å komme i gang. rw = randread forteller fio å bruke en tilfeldig lesing tilgang mønster, size = 128m presiserer at det skal overføre totalt 128 megabyte med data før du ringer testen ferdig, og katalogen parameter eksplisitt forteller fio hva filsystem som skal brukes for IO benchmark. På min test, er filsystemet under /tmp en ext3 filsystem er lagret på et RAID-5 utvalg bestående av tre 500GB Samsung SATA disker. Hvis du ikke angir katalogen, bruker fio gjeldende katalog at skallet er i, noe som kanskje ikke det du ønsker. Konfigurasjonsfilen og påkallelse er vist nedenfor

 
 $ cat random-les-test.fio.; tilfeldige lese av 128mb av data [random-read] rw = randreadsize = 128mdirectory = /tmp /fio-testing /data $ fio random-les-test.fiorandom-leser: (g = 0): rw = randread, bs = 4K -4K /4K-4K, ioengine = sync, iodepth = 1Starting en processrandom-leser: Legging ut IO-fil (er) (1 fil (er) /128MiB) Jobs: 1 (f = 1): [r] [100,0% Utført] [3588/0 kb /s] [eta 00m: 00s] tilfeldige-leser: (groupid = 0, jobber = 1): ERR = 0: pid = 30598 leser: io = 128MiB, bw = 864KiB /s, IOPS = 211, runt = 155282msec clat (usec): min = 139, max = 148K, avg = 4736,28, stdav = 6001,02 bw (KiB /s): min = 227, maks = 5275, per = 100,12%, avg = 865,00, stdav = 362,99 cpu: usr = 0,07%, sys = 1,27%, CTX = 32783, majf = 0, minf = 10 IO dypet: 1 = 100,0%, 2 = 0,0%, 4 = 0,0%, 8 = 0,0%, 16 = 0,0%, 32 = 0,0%, > = 64 = 0,0% utstedt r /w: total = 32768/0, kort = 0/0 lat (usec): 250 = 34,92%, 500 = 0,36%, 750 = 0,02 %, 1000 = 0,05% lat (msek): 2 = 0,41%, 4 = 12,80%, 10 = 44,96%, 20 = 5,16%, 50 = 0,94% lat (msek): 100 = 0,37%, 250 = 0,01% Run status gruppe 0 (alle jobber): LES: io = 128MiB, aggrb = 864KiB /s, minb = 864KiB /s, maxb = 864KiB /s, mynte = 155282msec, maxt = 155282msecDisk statistikk (lese /skrive): DM-6: ios = 32768/148, flette = 0/0, flått = 154728/12490, in_queue = 167218, util = 99,59% 


fio produserer mange tall i denne testen. Samlet sett økte verdier for båndbredde og lavere verdier for ventetid utgjøre bedre resultater.


BW Resultatet viser gjennomsnittlig båndbredde oppnås ved testen. De clat og BW linjene viser informasjon om ferdigstillelse latency og båndbredde hhv. Gjennomføringen ventetid er tiden mellom å sende inn en forespørsel, og det blir fullført. Den min, maks, gjennomsnitt og standardavvik for latency og båndbredde blir vist. I dette tilfellet, er standardavviket for både komplettering ventetid og båndbredde ganske stort i forhold til gjennomsnittsverdien, slik at noen IO forespørsler ble servert mye raskere enn andre. CPU linjen viser deg hvor mye innflytelse IO lasten hadde på CPU, slik at du kan fortelle om prosessoren i maskinen er for treg for IO du ønsker å utføre. IO dybder delen er mer interessant når du tester en IO arbeidsmengde der flere forespørsler om IO kan være utestående til enhver tid slik det gjøres i neste eksempel. På grunn av at ovennevnte test bare tillatt en enkelt IO forespørsel om å bli utstedt til enhver tid, IO dybder var på 1 til 100% av tiden. De latency tall innrykket under IO Snødybder avsnittet viser en oversikt over hvor lenge hver IO forespørsel tok å fullføre; for disse resultatene, nesten halvparten av forespørsler tok mellom 4 og 10 millisekunder mellom når IO forespørselen ble utstedt og når resultatet av at forespørselen ble rapportert. De ventetider er angitt som intervaller, så 4 = 12,80%, 10 = 44,96% delen rapporterer at 44,96% av forespørsler tok mer enn fire (tidligere rapportert verdi) og opp til 10 millisekunder å fullføre.


Den store LES linje tredje fra forrige viser gjennomsnittlig, min, og maks båndbredde for hver gjennomføring tråd eller prosess. fio lar deg definere mange tråder eller prosesser til alle sende inn arbeider på samme tid i løpet av en målestokk, slik at du kan ha mange tråder, hver bruker synkrone APIer for å utføre IO, og benchmark resultatet av alle disse trådene kjører samtidig. Dette lar deg teste IO arbeidsbelastning som er nærmere mange serverprogrammer, hvor en ny tråd eller prosessen er gytt å håndtere hver koble klient. I dette tilfellet har vi bare én tråd. Som LES linje nær bunnen av utgangen viser, har den eneste tråd en 864Kbps samlet båndbredde (aggrb) som forteller deg at enten disken er treg eller på hvilken måte IO er sendt til disken systemet ikke er vennlig, forårsaker disk hodet til å utføre mange dyre søker og dermed produsere en lavere samlet IO båndbredde. Hvis du sender inn IO til disken på en vennlig måte du bør få mye nærmere hastighetene som hdparm rapporter (typisk rundt 40-60Mbps).


Jeg utførte den samme testen på nytt , denne gangen ved hjelp av Linux asynkron IO subsystem i direkte IO-modus med mulighet, basert på iodepth parameter, åtte forespørsler om asynkron IO blir utstedt og ikke oppfylt fordi systemet måtte vente på disk IO på ethvert tidspunkt. Valget av å la opp til bare åtte IO forespørsler i køen var vilkårlig, men vanligvis en søknad vil begrense antall utestående forespørsler slik at systemet ikke blir overbelastes ned. I denne test rapportert i referanse nesten tre ganger båndbredden. De forkortede Resultatene er vist nedenfor. IO dypet viser hvor mange asynkrone IO forespørsler ble utstedt, men hadde ikke returnert data til søknaden i løpet av utførelsen. Tallene er rapportert for intervaller fra forrige figur; for eksempel, forteller 8 = 96,0% du at 96% av tiden det var fem, seks, sju eller åtte forespørsler i async IO køen, mens, basert på 4 = 4,0%, 4% av tiden var det bare tre eller fire forespørsler i køen


 
 $ cat random-les-test-aio.fio.; samme som random-les-test.fio; ... ioengine = libaioiodepth = 8direct = 1invalidate = 1 $ fio random-les-test-aio.fiorandom-leser: (groupid = 0, jobber = 1): err = 0: pid = 31318 lese: io = 128MiB, bw = 2,352KiB /s, IOPS = 574, runt = 57061msec slat (usec): min = 8, maks = 260, avg = 25,90, stdav = 23.23 clat (usec): min = 1, max = 124K, avg = 13901,91, stdav = 12193,87 bw (KiB /s): min = 0, maks = 5603, per = 97,59%, avg = 2295,43, stdav = 590,60 ... IO dypet: 1 = 0,1%, 2 = 0,1%, 4 = 4,0% , 8 = 96,0%, 16 = 0,0%, 32 = 0,0%, > = 64 = 0,0% ... Run status gruppe 0 (alle jobber): LES: io = 128MiB, aggrb = 2,352KiB /s, minb = 2,352KiB /s, maxb = 2,352KiB /s, mint = 57061msec, maxt = 57061msec 


Random leser alltid kommer til å være begrenset av søketid på disken hodet. Fordi async IO test kan gi så mange som åtte IO forespørsler før ventet på noen å fullføre, det var større sjanse for lyder på samme disk området skal være ferdig sammen, og dermed en samlet økning i IO båndbredde.


HOWTO fil fra fio distribusjon gir fullstendige opplysninger om de alternativene du kan bruke til å angi benchmark arbeidsoppgaver. En av de mer interessante parametere er rw, som kan angi sekvensiell eller tilfeldig leser og eller skriver i mange kombinasjoner. Den ioengine parameter kan velge hvordan IO forespørsler utstedes til kjernen. Den oppheve alternativet fører til at kjernen buffer og siden cache å være ugyldig etter en fil før du begynner referanseindeksen. Runtime fastsetter at en test skal kjøre for en gitt mengde tid og deretter betraktes som komplett. Den thinktime parameter setter inn en angitt forsinkelse mellom IO forespørsler, som er nyttig for å simulere en reell søknad som normalt ville utføre noe arbeid på data som leses fra disken. fsync = n
kan brukes til å utstede en sync samtalen etter hvert n
skriver utstedt. write_iolog og read_iolog årsaken fio å skrive eller lese en logg over alle IO forespørsler utstedt. Med disse kommandoene kan du ta en logg over de eksakte IO kommandoer utstedt, redigere som logg for å gi akkurat den IO arbeidsmengden du ønsker, og benchmark de eksakte IO forespørsler. De iolog alternativene er stor for å importere en IO tilgang mønster fra et eksisterende program for bruk med fio.


Simulerer servere


Du kan også angi flere tråder eller prosesser til alle sende IO arbeid på samme tid å benchmark server-lignende filsystem interaksjon. I følgende eksempel har jeg fire forskjellige fremgangsmåter, som hver utstedende sin egen IO belastninger på systemet, alle som kjører på samme tid. Jeg har basert eksempelet på å ha to minne-kartlagt spørre motorer, en bakgrunn oppdateringstråd, og en bakgrunn forfatter tråd. Forskjellen mellom de to skrive tråder er at forfatteren tråden er å simulere skrive en journal, mens bakgrunnen updater må lese og skrive (oppdatere) data. bgupdater har en thinktime på 40 mikrosekunder, slik at prosessen for å sove etter en liten stund etter hver fullførte IO


 
 $ cat fire-tråder-randio.fio.; Fire tråder, to spørre to writers.[global]rw=randreadsize=256mdirectory=/tmp/fio-testing/dataioengine=libaioiodepth=4invalidate=1direct=1[bgwriter]rw=randwriteiodepth=32[queryA]iodepth=1ioengine=mmapdirect=0thinktime=3[queryB]iodepth=1ioengine=mmapdirect=0thinktime=5[bgupdater]rw=randrwiodepth=16thinktime=40size=32m$ Fio fire-tråder-randio.fiobgwriter: (g = 0): rw = randwrite, bs = 4K-4K /4K-4K, ioengine = libaio, iodepth = 32queryA: (g = 0): rw = randread, bs = 4K -4K /4K-4K, ioengine = mmap, iodepth = 1queryB: (g = 0): rw = randread, bs = 4K-4K /4K-4K, ioengine = mmap, iodepth = 1bgupdater: (g = 0): rw = randrw, bs = 4K-4K /4K-4K, ioengine = libaio, iodepth = 16Starting 4 processesbgwriter: (groupid = 0, jobber = 1): err = 0: pid = 3241 write: io = 256MiB, bw = 7,480KiB /s, IOPS = 1826, runt = 35886msec slat (usec): min = 9, maks = 106K, avg = 35,29, stdav = 583,45 clat (usec): min = 117, max = 224k, avg = 17365,99, stdav = 24002,00 bw (KiB /s): min = 0, maks = 14 636, per = 72,30%, avg = 5746,62, stdav = 5225,44 cpu: usr = 0,40%, sys = 4,13%, CTX = 18254, majf = 0, minf = 9 IO dybder: 1 = 0,1%, 2 = 0,1%, 4 = 0,4%, 8 = 3,3%, 16 = 59,7%, 32 = 36,5%, > = 64 = 0,0% utstedt r /w: total = 0/65536 , kort = 0/0 lat (usec): 250 = 0,05%, 500 = 0,33%, 750 = 0,70%, 1000 = 1,11% lat (msek): 2 = 7,06%, 4 = 14,91%, 10 = 27,10%, 20 = 21,82%, 50 = 20,32% lat (msek): 100 = 4,74%, 250 = 1,86% queryA: (groupid = 0, jobber = 1): err = 0: pid = 3242 read: io = 256MiB, bw = 589MiB /s, IOPS = 147K, runt = 445msec clat (usec): min = 2, max = 165, avg = 3,48, stdav = 2.38 cpu: usr = 70,05%, sys = 30,41%, CTX = 91, majf = 0 , minf = 65545 IO dypet: 1 = 100,0%, 2 = 0,0%, 4 = 0,0%, 8 = 0,0%, 16 = 0,0%, 32 = 0,0%, > = 64 = 0,0% utstedt r /w: total = 65536/0, kort = 0/0 lat (usec): 4 = 76,20%, 10 = 22,51%, 20 = 1,17%, 50 = 0,05%, 100 = 0,05% lat (usec): 250 = 0,01% queryB: (groupid = 0, jobber = 1): err = 0: pid = 3243 read: io = 256MiB, BW = 455MiB /s, IOPS = 114K, runt = 576msec clat (usec): min = 2, max = 303, avg = 3,48, stdav = 2.31 bw (KiB /s): min = 464158, max = 464 158, per = 1383,48%, avg = 464158,00, stdav = 0.00 cpu: usr = 73,22%, sys = 26,43%, CTX = 69, majf = 0, minf = 65545 IO dypet: 1 = 100,0%, 2 = 0,0%, 4 = 0,0%, 8 = 0,0%, 16 = 0,0%, 32 = 0,0%, > = 64 = 0,0% utstedt r /w : total = 65536/0, kort = 0/0 lat (usec): 4 = 76,81%, 10 = 21,61%, 20 = 1,53%, 50 = 0,02%, 100 = 0,03% lat (usec): 250 = 0,01% 500 = 0,01% bgupdater: (groupid = 0, jobber = 1): err = 0: pid = 3244 read: io = 16,348KiB, bw = 1,014KiB /s, IOPS = 247, runt = 16501msec slat (usec): min = 7, max = 42 515, avg = 47,01, stdav = 665,19 clat (usec): min = 1, max = 137K, avg = 14215,23, stdav = 20611,53 bw (KiB /s): min = 0, maks = 1957 per = 2,37%, avg = 794,90, stdav = 495,94 write: io = 16,420KiB, bw = 1,018KiB /s, IOPS = 248, runt = 16501msec slat (usec): min = 9, max = 42 510, avg = 38.73, stdav = 663,37 clat (usec): min = 202, max = 229K, avg = 49803,02, stdav = 34393,32 bw (KiB /s): min = 0, maks = 1840 per = 10,89%, avg = 865,54, stdav = 411,66 CPU: usr = 0,53%, sys = 1,39%, CTX = 12089, majf = 0, minf = 9 IO dypet: 1 = 0,1%, 2 = 0,1%, 4 = 0,3%, 8 = 22,8%, 16 = 76,8% , 32 = 0,0%, > = 64 = 0,0% utstedt r /w: total = 4087/4105, kort = 0/0 lat (usec): 2 = 0,02%, 4 = 0,04%, 20 = 0,01%, 50 = 0,06%, 100 = 1,44% lat (usec): 250 = 8,81%, 500 = 4,24%, 750 = 2,56%, 1 000 = 1,17% lat (msek): 2 = 2,36%, 4 = 2,62%, 10 = 9,47 %, 20 = 13,57%, 50 = 29,82% lat (msek): 100 = 19,07%, 250 = 4,72% Run status gruppe 0 (alle jobber): LES: io = 528MiB, aggrb = 33,550KiB /s, minb = 1014 KiB /s, maxb = 589MiB /s, mint = 445msec, maxt = 16501msec SKRIV: io = 272MiB, aggrb = 7,948KiB /s, minb = 1,018KiB /s, maxb = 7,480KiB /s, mint = 16501msec, maxt = 35886msecDisk statistikk (lese /skrive): DM-6: iOS = 4087/69722, flette = 0/0, flått = 58049/1345695, in_queue = 1403777, util = 99,74% 


Som en ville forvente, båndbredden rekken oppnådd i søket og forfatter prosesser var vesentlig forskjellig. Spørringer er utført på ca 500Mbps mens skriving kommer inn på 1Mbps eller 7.5Mbps avhengig av om det er lese /skrive eller rent skriveytelse hhv. IO dypet viser antall ventende IO forespørsler som er i køen når en IO forespørsel utstedes. For eksempel, for bgupdater prosessen, nesten 1/4 av asynkron IO anmodninger blir oppfylt med åtte eller færre forespørsler i kø av en potensiell 16. I motsetning til dette har de bgwriter mer enn halvparten av forespørsler utføres med 16 eller mindre ventende forespørsler i køen.


Til kontrast med de tre-disk RAID-5-konfigurasjon, jeg reran den fire-tråder-randio.fio test på en enkelt Western Digital 750GB stasjonen. Den bgupdater prosessen oppnådd mindre enn halvparten av båndbredden, og hver av spørre prosesser kjørte på 1/3 av samlede båndbredden. For denne testen Western Digital stasjonen var på en annen datamaskin med forskjellige CPU og RAM spesifikasjoner i tillegg, så noen sammenligning bør tas med en klype salt


 
 bgwriter.: (groupid = 0, jobber = 1): err = 0: pid = 14963 skrive: io = 256MiB, bw = 6,545KiB /s, IOPS = 1597, runt = 41013msecqueryA: (groupid = 0, jobber = 1): err = 0: pid = 14964 lese: io = 256MiB, BW = 160MiB /s, IOPS = 39888, runt = 1643msecqueryB: (groupid = 0, jobber = 1): err = 0: pid = 14965 lese: io = 256MiB, bw = 163MiB /s, IOPS = 40680, runt = 1611msecbgupdater: (groupid = 0, jobber = 1): err = 0: pid = 14966 lese: io = 16,416KiB, bw = 422KiB /s, IOPS = 103, runt = 39788msec skrive : io = 16,352KiB, bw = 420KiB /s, IOPS = 102, runt = 39788msec LES: io = 528MiB, aggrb = 13,915KiB /s, minb = 422KiB /s, maxb = 163MiB /s, mint = 1611msec, maxt = 39788msec SKRIV: io = 272MiB, aggrb = 6,953KiB /s, minb = 420KiB /s, maxb = 6,545KiB /s, mint = 39788msec, maxt = 41013msec 


Det store utvalget av måter som Fio kan utstede sine IO forespørsler gir det til benchmarking IO mønstre og bruk av ulike APIer for å utføre denne IO. Du kan også kjøre identiske Fio konfigurasjoner på forskjellige filsystemer eller underliggende maskinvaren for å se hvilken forskjell endrer på dette nivået vil gjøre til ytelse.


Benchmarking forskjellige IO forespørsel systemer for en bestemt IO mønster kan være praktisk hvis du er i ferd med å skrive en IO-intensive program, men er ikke sikker på hvilken API og design vil fungere best på maskinvaren. For eksempel kan du holde disken systemet og RAM fast og se hvor godt en IO last ville bli betjent ved hjelp minnetilordnet IO eller Linux asyncio grensesnittet. Selvfølgelig dette krever at du har et svært innviklet kunnskap om typiske IO ber om at søknaden vil utstede. Hvis du allerede har et verktøy som bruker noe sånt minne-kartlagt filer, så kan du få IO mønstre for vanlig bruk fra eksisterende verktøy, mate dem inn fio ved hjelp av ulike IO motorer, og få en rimelig bilde av om det kan være verdt porting programmet til en annen IO API for bedre ytelse. Anmeldelser