Storage Benchmarking mit fio


Graphische Darstellung einer fio Testreihe

Neue Storage Systeme brauchen neue Benchmark-Tools. Unser Testaufbau bestand aus vier schnelldrehenden  Western Digital 1TB Platten, die eine Geschwindigkeit von 10.000 U/m erreichen. Diese sind zusammen mit zwei SSDs, die rein für das Cache benutzt werden, in einem Raid 10 Verbund. Dieser Testaufbau wurde übrigens später weiterentwickelt zu einem sehr schnellen Storage-System für unsere eigenen Hosting-Angebote, aber dazu mehr in einem weiteren Artikel.

Die ersten Versuche, entstanden mit dem Tool bonnie++ diese führten zu widersprüchlichen Ergebnissen. Nach längerem recherchieren, sind wir darauf gestoßen das bonnie++ nicht genügend Last erzeugen kann um Tests in dieser Größenordnung durchzuführen. Die Grenze der zu messenden IOs liegt hier bei 8000.

Nach dieser ernüchternden Erkenntnis, haben wir begonnen mit fio zu testen und bis auf die Ausgabe hat uns dieses Tool voll und ganz überzeugt.

Die Vor- und Nachteile von fio:

  • Erzeugt mehr Last durch das Angeben der Prozesse die  gestartet werden
  • Unterscheidet zwischen dem Modus, der Blöckgröße, der Testdateigröße sowie die Anzahl der Prozesse die gestartet werden
  • Auch für Stresstests und Hardware-Verifikation geeignet
  • Kann gut Automatisiert werden
  • Wenn ein stark unter Last stehendes System getestet wird, wird es mit fio nicht so stark belastet, da die Datenmenge mit der getestet wird geringer wird je stärker das System beansprucht ist, das Problem der Überlastung wird daher umgangen
  • Der Output ist sehr detailliert, um die Testergebnisse auszuwerten jedoch schlecht lesbar
  • Unter Ubuntu-Linux einfach zu installieren (apt-get install fio)

Dieser Programmcode ist unser automatisierter fio Test, mit der dazugehörigen Überschrift. Diese Daten werden anschließend an unser Perl Programm übergeben um die Ausgewerteten Daten lesbar zu machen.

#! /bin/bash

DEVICE=$1
SIZE=$2

ARGS1="--direct=1  --runtime=30 "
ARGS2="--filename=$DEVICE --size=$SIZE "

#  fio --filename=/dev/sdb1 --direct=1 --rw=read --bs=512 --size=4G 
#      --runtime=60 --name=job1 --name=job2 --name=job3 --name=job4 
#      --name=job5 --name=job6

(
echo "     DEVICE;  SIZE;     MODE; BLOCKSIZE; NUMJOBS;  READMB; WRITEMB; READIOS; WRITEIOS"
# for mode in rw read randrw randread; do
for mode in randread; do
   for blocksize in 4k 16M ; do
      ARGS3="--bs=$blocksize --rw=$mode "
      for jobs in 1 2 3 4 6 8 10 12 16 20; do
         ARGS4=""
         i=0
         while [ $i -lt $jobs ]; do
            let i=$i+1
            ARGS4="$ARGS4 --name=job$i"
         done
         #echo -n "$DEVICE;$SIZE;$mode;$blocksize;$jobs;"
         printf "%12s %6s %8s %10s %8s" "$DEVICE;" "$SIZE;" "$mode;" "$blocksize;" "$jobs;"
         fio $ARGS1 $ARGS2 $ARGS3 $ARGS4 | /usr/local/tools/fio_parser.pl
      done
   done
done
) | tee /tmp/fio-result-`/bin/date +%Y-%m-%d--%H-%M-%s`-`/bin/hostname`.csv


#! /usr/bin/perl

while ( $s =  ) {
# egrep "READ:|WRITE:|^  [a-z].*ios="
#   READ: io=4965MB, aggrb=84611KB/s, minb=13880KB/s, maxb=15064KB/s,
#         mint=60055msec, maxt=60088msec
#  WRITE: io=5015MB, aggrb=85463KB/s, minb=13999KB/s, maxb=15155KB/s,
#         mint=60055msec, maxt=60088msec
#  sdb: ios=9946/10014, merge=0/0, ticks=344830/329890,
#       in_queue=674820, util=99.93%

   chomp($s);
   if ( $s =~ / READ: /) {
      $ReadBandwidth = $s;
      $ReadBandwidth =~ s/^.*aggrb=//;
      $ReadBandwidth =~ s/B.*$//;
      $ReadUnit=chop($ReadBandwidth);
      if ($ReadUnit eq "M") {
         $ReadBandwidth=$ReadBandwidth*1024;
      } elsif ($ReadUnit eq "G") {
         $ReadBandwidth=$ReadBandwidth*1024*1024;
      }

      $Time = $s;
      $Time =~ s/^.*maxt=//;
      $Time =~ s/msec.*$//;
   } elsif ( $s =~ / WRITE: /) {
      $WriteBandwidth = $s;
      $WriteBandwidth =~ s/^.*aggrb=//;
      $WriteBandwidth =~ s/B.*$//;
      $WriteUnit=chop($ReadBandwidth);
      if ($WriteUnit eq "M") {
         $WriteBandwidth=$WriteBandwidth*1024;
      } elsif ($WriteUnit eq "G") {
         $WriteBandwidth=$WriteBandwidth*1024*1024;
      }

      if ($Time == undef ) {
         $Time = $s;
         $Time =~ s/^.*maxt=//;
         $Time =~ s/msec.*$//;
      }
   } elsif ( $s =~ /^  [a-z].*ios=/ ) {
      $ReadIOS = $s;
      $ReadIOS =~ s/^.*ios=//;
      $ReadIOS =~ s/\/.*$//;
      $WriteIOS = $s;
      $WriteIOS =~ s/^.*ios=[0-9]+\///;
      $WriteIOS =~ s/\,.*$//;
   }
}

printf( "%8s;", sprintf ("%.3f", $ReadBandwidth/1024) );
#print ";";
printf( "%8s;", sprintf ("%.3f", $WriteBandwidth/1024) );
#print ";";
printf ("%8i", int($ReadIOS*1000/$Time) );
print ";";
printf ("%9i", int($WriteIOS*1000/$Time) );
print "\n";


Und hier einmal eine Ausgabe.

DEVICE SIZE MODE BLOCKSIZE NUMJOBS READMB WRITEMB READIOS WRITEIOS
/dev/sdb1 49G randread 512 1 1624 0 3317 0
/dev/sdb1 49G randread 512 2 2926 0 5974 0
/dev/sdb1 49G randread 512 3 4363 0 8910 0
/dev/sdb1 49G randread 512 4 5572 0 11379 0
/dev/sdb1 49G randread 512 5 5918 0 12085 0
/dev/sdb1 49G randread 512 6 6396 0 13061 0
/dev/sdb1 49G randread 512 7 7076 0 14449 0
/dev/sdb1 49G randread 512 8 7647 0 15615 0
/dev/sdb1 49G randread 4k 1 12473 0 3193 0
/dev/sdb1 49G randread 4k 2 23147 0 5907 0
/dev/sdb1 49G randread 4k 3 33905 0 8656 0
/dev/sdb1 49G randread 4k 4 41183 0 10520 0
/dev/sdb1 49G randread 4k 5 43572 0 11122 0
/dev/sdb1 49G randread 4k 6 46203 0 11794 0
/dev/sdb1 49G randread 4k 7 48973 0 12501 0
/dev/sdb1 49G randread 4k 8 54445 0 13898 0
/dev/sdb1 49G randread 64k 1 106146 0 1693 0
/dev/sdb1 49G randread 64k 2 134256 0 2142 0
/dev/sdb1 49G randread 64k 3 184783 0 2949 0
/dev/sdb1 49G randread 64k 4 223165 0 3562 0
/dev/sdb1 49G randread 64k 5 250008 0 3991 0
/dev/sdb1 49G randread 64k 6 267242 0 4266 0
/dev/sdb1 49G randread 64k 7 282166 0 4504 0
/dev/sdb1 49G randread 64k 8 293171 0 4680 0
/dev/sdb1 49G randread 1M 1 267873 0 534 0
/dev/sdb1 49G randread 1M 2 314568 0 627 0
/dev/sdb1 49G randread 1M 3 290241 0 578 0
/dev/sdb1 49G randread 1M 4 297634 0 593 0
/dev/sdb1 49G randread 1M 5 247376 0 492 0
/dev/sdb1 49G randread 1M 6 263334 0 526 0
/dev/sdb1 49G randread 1M 7 269112 0 536 0
/dev/sdb1 49G randread 1M 8 269197 0 537 0

2 Gedanken zu „Storage Benchmarking mit fio

  1. Pingback: Deduplizierender Storage mit dem ZFS-Filesystem | Vernetzte Welt Cast

  2. Pingback: vSphere 5.5 Flash Read Cache: Performance und Praxis | Vernetzte Welt Cast

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s