Storage benchmarken: IOPS, throughput en latency
Kort antwoord
Storage-prestaties zijn niet één getal, maar drie: IOPS (operaties per seconde, vooral belangrijk bij kleine, random reads en writes zoals databases), throughput (totale hoeveelheid data per seconde, vooral belangrijk bij grote sequentiële overdrachten zoals backups) en latency (hoe lang één operatie duurt, belangrijk overal waar responsiviteit telt). Slecht benchmarken, testen vanuit cache, het verkeerde toegangspatroon testen of te kort testen levert cijfers op die er goed uitzien, maar niets betekenen.
De drie metrics, en wanneer elk ervan telt
IOPS (input/output operations per second) telt hoeveel individuele read- of write-operaties storage per seconde kan afronden. Dit getal telt het zwaarst voor workloads die bestaan uit veel kleine, random operaties, bijvoorbeeld een database die veel kleine queries verwerkt tegen verspreide rijen, waarbij elke operatie klein is maar er een enorm aantal tegelijk plaatsvindt.
Throughput telt iets anders: de totale hoeveelheid data die per seconde wordt verplaatst, meestal in MB/s of GB/s. Dit getal telt bij grote, sequentiële overdrachten, zoals het kopiëren van een groot backupbestand, het streamen van media of het verplaatsen van een grote dataset, waarbij de operaties weinig en groot zijn in plaats van veel en klein.
Latency meet hoe lang één operatie duurt om af te ronden, ongeacht hoeveel er tegelijk plaatsvinden. Dit getal telt voor alles waarbij responsiviteit belangrijk is: een applicatie die traag aanvoelt terwijl het totale datavolume klein is, heeft meestal een latency-probleem, geen throughput-probleem.
Deze drie bewegen niet gelijk op. Storage die uitstekende throughput haalt bij grote sequentiële overdrachten kan alsnog matige IOPS hebben bij kleine random operaties, en andersom, omdat ze de storage op verschillende manieren belasten. Benchmarken op de verkeerde metric, of op maar één van de drie, vertelt je minder dan het lijkt.
| Metric | Wat het meet | Telt vooral voor |
|---|---|---|
| IOPS | Afgeronde operaties per seconde | Kleine, random reads/writes: databases, transactionele workloads |
| Throughput | Totale hoeveelheid verplaatste data per seconde | Grote, sequentiële overdrachten: backups, media, bulk-dataverplaatsing |
| Latency | Tijd om één operatie af te ronden | Workloads van elke omvang waarbij responsiviteit telt |
Veelgemaakte fouten die misleidende resultaten opleveren
Een paar gewoontes zorgen er telkens weer voor dat benchmarkcijfers beter lijken dan de prestaties in de praktijk.
Testen met een bestand dat klein genoeg is om gecachet te worden. Besturingssystemen en storage-controllers cachen recent gebruikte data in het geheugen. Als je testbestand klein genoeg is om volledig in die cache te passen, meet je geheugensnelheid en niet schijfsnelheid, en liggen de cijfers veel hoger dan wat de onderliggende storage werkelijk kan volhouden. Een zinvolle test heeft een working set nodig die groot genoeg is om voorbij elke cache te komen die voor de storage zit.
Het verkeerde toegangspatroon testen. Sequentiële en random toegang belasten storage volledig anders, en een apparaat dat uitblinkt in het één kan onopvallend zijn in het ander. Een sequential-read test draaien en dan aannemen dat die iets zegt over de random-write-prestaties van je database, of andersom, levert cijfers op die niet weerspiegelen hoe de storage zich werkelijk gedraagt onder je echte workload.
De test niet lang genoeg laten draaien. Een korte burst kan er uitstekend uitzien omdat die profiteert van een cache of een burst-capaciteitsbuffer die bij een langere, aanhoudende run uiteindelijk uitgeput raakt. Echte workloads draaien minuten of uren, niet seconden, dus een benchmark die maar een paar seconden duurt, vertelt je iets over de burst, niet over de aanhoudende prestaties die je uiteindelijk krijgt zodra die marge op is.
Waarmee je test
fio (Flexible I/O Tester) is het standaardgereedschap voor dit soort tests op Linux. Het genereert sequentiële of random toegangspatronen, met de blockgrootte en queue depth die je zelf kiest, en rapporteert IOPS, throughput en latency uit dezelfde run. Daardoor kun je precies het toegangspatroon testen dat je echte workload oplevert, in plaats van een generieke standaardinstelling. De concrete fio-commandosyntax en het interpreteren van resultaten zijn een apart onderwerp en blijven bewust buiten dit artikel. Het gaat hier om weten wat je moet meten en hoe je jezelf niet voor de gek houdt voordat je zover bent.