Mit FIO die Leistung von Festplatten bewerten
FIO (Flexible I/O tester) ist ein Open Source Werkzeug mit dem die I/O Leistung von Festplatten (HDD) und SSDs mit unterschiedlichen Lastprofilen gemessen werden kann. Wenn ich Änderungen an meinen Servern vornehmen, kann ich mit FIO die Auswirkung auf die Schreib- und Leseperformance überprüfen. Es geht mir dabei weniger um die absolute Leistung, sondern um die relative Veränderung der Leistung beim Einsatz von virtuellen Maschinen oder die Leistung beim Zugriff auf Netzwerkspeicher (shared storage).
Die Kombination von IOPS-, Latenz- und Durchsatzmessungen (IOPS, latency and throughput) ergibt ein gutes Bild von der I/O Leistung (performance). Allerdings hängen diese Werte sehr stark von der Größe (blocksize, IO request size) des Schreib- und Lesenvorgangs, dem spezifischen Lastprofil (workload) und der Latenz (latency) ab. Ein Datenbankserver mit vielen kleinen Schreib- und Lesezugriffen hat ein anderes Lastprofil als ein Webserver oder ein Dateiserver, mit eher großen Schreib- und Lesezugriffe.
Der Durchsatz gibt an, wie viele Informationseinheiten in einem Zeitraum verarbeitet werden können und wird in Megabit pro Sekunde (MiB/s) gemessen. Input / Output operations per second (IOPS) gibt an, wieviele Schreib- / Lesevorgänge pro Sekunde durchgeführt werden können. Die Größe des I/O Vorgangs (IO request size) ist abhängig von der Art des Zugriffs von Betriebssystem oder der Anwendung auf die HDD/SSD und wird in bytes, kilobytes oder megabytes gemessen (z.B. 4 KB, 8 KB, 64 KB, 1MB, 4MB). In der realen Anwendung ergibt sich häufig eine Mischung verschiedener I/O Vorgänge. Vereinfacht hängen die Größen wie folgt zusammen
Datendurchsatz = IOPS x durchschnittliche Blockgröße
Die Latenz (latency) dagegen ist die mittlere Zeit, die ein I/O Vorgang braucht, um abgeschlossen zu werden und wird in Millisekunden gemessen. Die Latenz sollte so gering wie möglich sein, da eine schlechte Zeit für den Abschluss des I/O Vorgangs die Leistungsfähigkeit der HDD/SSD beeinflusst. Angaben zu IOPS ohne Angaben der Latenz sind kaum belastbar.
Zu den Abhängigkeiten zwischen Lastprofil (workload) und Leistung (performance) gibt es ein gutes Dokument von EMC2 (Understanding how I/O workload profiles relate to performance). Gerade der erste Teil ist einfach und unterhaltsam zu lesen und geht im Weiteren auch auf den Unterschied zwischen Megabit (MiB) und Megabyte (MB).
Datendurchsatz und IOPS mit FIO messen
Für den Test habe ich einen DELL Optiplex 9010 SFF Hosts meines Playlabs mit Debian 10 installiert. In diesem Host sind zwei SSDs verbaut: sda
ist eine HP gebrandete Intel SSD DC S3700 100GB und sdb
eine Samsung SSD 860 EVO 500GB. Der Optiplex 9010 SFF hat drei SATA Ports: SATA 0 (SATA III, blau/blue, sda ), SATA 1 (SATA III, schwarz/black, sdb) und SATA 2 (SATA II, weiß/white). SATA III (SATA Revision 3.x) hat eine Bandbreite von 6,0 Gbit/s. SATA II (SATA Revision 2.x) hat eine Bandbreite von 3,0 Gbit/s.
1. FIO installieren
sudo apt update sudo apt install fio
2. Festplatte / Verzeichnis für den Test festlegen
lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 93,2G 0 disk ├─sda1 8:1 0 92,2G 0 part / └─sda2 8:2 0 982M 0 part [SWAP] sdb 8:16 0 465,8G 0 disk └─sdb1 8:17 0 465,8G 0 part /var
Zunächst wird das Verzeichnis für den Test auf der Samsung EVO 860 (sdb) angelegt.
sudo mkdir /var/fio cd /var/fio
3. Sequentielle Schreibvorgänge mit 4M Blockgröße testen
sudo sync;fio --name=fiotest --ioengine=libaio --direct=1 --randrepeat=1 --group_reporting \ --fallocate=none --ramp_time=10 --iodepth=64 --loops=5 --size=10G --numjobs=1 \ --rw=write --bs=4M
4. Messergebnisse von FIO lesen
Die markierte Zeile fasst das Ergebnis zusammen: FIO hat 45.2 GiB in 89 Sekunden geschrieben. Das entspricht einer Bandbreite von 519 MiB/s (544MB/s) und 128 IOPS bei eine I/O Blockgröße von 4MiB. Das oben verlinkte Dokument von EMC2 erläutert den Unterschied zwischen MiB und MB; ich verwende im Weiteren MB.
fio: (g=0): rw=write, bs=(R) 4096KiB-4096KiB, (W) 4096KiB-4096KiB, (T) 4096KiB-4096KiB, ioengine=libaio, iodepth=64 fio-3.28 Starting 1 process fio: (groupid=0, jobs=1): err= 0: pid=11245: Sun Nov 28 17:08:25 2021 write: IOPS=128, BW=519MiB/s (544MB/s)(45.2GiB/89161msec); 0 zone resets slat (usec): min=184, max=121242, avg=7699.53, stdev=8377.88 clat (msec): min=113, max=603, avg=484.01, stdev=35.13 lat (msec): min=123, max=611, avg=491.71, stdev=34.51 clat percentiles (msec): | 1.00th=[ 296], 5.00th=[ 481], 10.00th=[ 481], 20.00th=[ 481], | 30.00th=[ 481], 40.00th=[ 481], 50.00th=[ 489], 60.00th=[ 498], | 70.00th=[ 498], 80.00th=[ 498], 90.00th=[ 498], 95.00th=[ 498], | 99.00th=[ 558], 99.50th=[ 584], 99.90th=[ 592], 99.95th=[ 600], | 99.99th=[ 600] bw ( KiB/s): min=98304, max=917504, per=99.63%, avg=529046.71, stdev=57391.43, samples=178 iops : min= 24, max= 224, avg=129.10, stdev=14.01, samples=178 lat (msec) : 250=0.75%, 500=97.02%, 750=2.78% cpu : usr=2.17%, sys=2.02%, ctx=5759, majf=0, minf=58 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.3%, 16=0.6%, 32=1.1%, >=64=97.8% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0% issued rwts: total=0,11495,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=64 Run status group 0 (all jobs): WRITE: bw=519MiB/s (544MB/s), 519MiB/s-519MiB/s (544MB/s-544MB/s), io=45.2GiB (48.5GB), run=89161-89161msec Disk stats (read/write): sdb: ios=0/51171, merge=0/21, ticks=0/5892259, in_queue=3119356, util=99.43%
Der gleiche Test mit --bs=4k
ergibt eine Bandbreite von 407 MiB/s und rund 99400 IOPS bei der I/O Blockgröße von 4k.
5. Bandbreite und IOPS in Abhängigkeit von Blockgröße
Mit einer I/O Blockgröße von 4k, 8k, 64k, 1M und 4M ergeben über 3 FIO Messungen mittlere Werte für die Bandbreite und die IOPS. Die Diagramme zeigen die Ergebnisse für sequentielle und zufällige I/O Schreibvorgänge in Abhängigkeit von der I/O Blockgröße.


Für sequentielle und zufällige I/O Lesevorgänge ergibt sich ein sehr vergleichbares Bild für Bandbreite, IOPS und Blockgröße.


6. Die Basiswerte (baseline)
Die gemessene sequentielle Schreib- und Leseleistung entspricht der Spezifikation der Samsung SSD 860 EVO 500GB sowie einer Leistungsmessung mit der Samsung SSD Verwaltungssoftware Samsung Magician unter Windows 10 (mit der auch ein Update der SSD Firmware möglich ist.)

Die mit FIO gemessene, mittlere Bandbreite für sequentielle Lesevorgänge liegt (ab einer Blockgröße von 64k) bei 560 MB/s und für sequentielle Schreibvorgang (ab eine Blockgröße von 64k) bei gut 530 MB/s.
Spezifikation und der Performance Benchmark von Samsung Magician für die Samsung SSD 860 EVO decken sich halbwegs mit den Ergebnissen von FIO. Damit sind die Leistungswerte dieses Hosts grundsätzlich nachvollziehbar.
In der Zukunft kann ich auf Basis dieser Basiswerte (baseline) den Einfluss von Betriebssystemen (operating system, OS), Virtualisierungssoftware (Hypervisor) und virtuellen Maschinen (VM) auf die Leistung des Speichers (Storage) besser einordnen.
DOM0 vs VM poor disk I/O on VM zeigt die Grundidee zur Bewertung der Leistung des Speichers (Storage) auf Basis von FIO. Dabei geht es mir weniger um die absoluten, sondern mehr um die relativen Ergebnisse.
7. Latenz
Bei der Bewertung der Leistung von Festplatten spielt die Latenz eine wesentliche Rolle (im 4M write Beispiel ca. 490 msec). Aber das schaue ich mir in einem zukünftigen Post an.
8. FIO selbst compilieren
Dies ist ein optionaler Schritt, falls man mit der aktuellsten Verion von FIO arbeiten möchte. Im Oktober 2021 wird über das Debian Repository die Version fio-3.12
installiert. Über das Git repository des Projektes ist die Version fio-3.28
verfügbar ist. Um mit der aktuellen Version zu arbeiten, muss man diese selbst compilieren / installieren.
Ist FIO bereits über das Debian Repository installiert worden, sollte das Paket deinstalliert werden, um Probleme zu vermeiden.
sudo apt purge fio sudo apt autoremove && sudo apt clean
Um FIO selbst compilieren zu können, muss eine Build- Umgebung installiert sein. Zudem muss die libaio
Bibliothek installiert werden, damit das Modul für asynchrone I/O Vorgänge (asynchronous IO accesses) genutzt werden kann.
sudo apt install build-essential libaio1 libaio-dev zlib1g-dev
FIO kann anschließend im /opt Verzeichnis installiert werden. Dazu wird die aktuelle Version von FIO heruntergeladen und entpackt (das Archiv kann gelöscht werden).
cd /opt sudo wget http://brick.kernel.dk/snaps/fio-git-latest.tar.gz sudo gunzip fio-git-latest.tar.gz sudo tar -xf fio-git-latest.tar sudo rm fio-git-latest.tar*
Anschließend kann FIO im Verzeichnis /opt/fio
compiliert und installiert werden.
cd /opt/fio sudo ./configure sudo make sudo make install
fio -v
zeigt nun die aktuelle verison an (im Oktober 2021 fio-3.28
)