Überwachung von virtuellem FC Client Verkehr

Mit dem LPAR-Tool lassen sich jederzeit Statistiken für alle virtuellen FC Clients mit dem Kommando „vios fcstat“ anzeigen. Damit lässt sich jederzeit feststellen welche Client LPARs gerade welchen I/O-Durchsatz haben (bei Verwendung von NPIV).

Welche NPIV fähigen FC-Adapter es auf einem Virtual-I/O-Server gibt, lässt sich leicht mit „vios lsnports“ herausfinden:

$ vios lsnports ms15-vio1
NAME  PHYSLOC                     FABRIC  TPORTS  APORTS  SWWPNS  AWWPNS
fcs0  U78CB.001.XXXXXXX-P1-C5-T1  1       64      62      2032    2012
fcs1  U78CB.001.XXXXXXX-P1-C5-T2  1       64      62      2032    2012
fcs2  U78CB.001.XXXXXXX-P1-C5-T3  1       64      61      2032    1979
fcs3  U78CB.001.XXXXXXX-P1-C5-T4  1       64      61      2032    1979
fcs4  U78CB.001.XXXXXXX-P1-C3-T1  1       64      50      3088    3000
fcs5  U78CB.001.XXXXXXX-P1-C3-T2  1       64      63      3088    3077
$

Wir lassen uns die FC Client Statistiken mit dem Kommando „vios fcstat“ anzeigen, dabei werden per Default alle 10 Sekunden die Daten für alle virtuellen FC Clients des angegebenen Virtual-I/O-Servers, ausgegeben:

$ vios fcstat ms15-vio1
HOSTNAME   PHYSDEV  WWPN                DEV    INREQS    INBYTES      OUTREQS    OUTBYTES     CTRLREQS
ms15-vio1  fcs1     0x210000XXXXX56EC5  fcs1   774.75/s  129.51 MB/s  1332.71/s   92.96 MB/s  20
aixtsmp1   fcs2     0xC050760XXXXX0058  fcs6   318.10/s   83.39 MB/s  481.34/s   126.18 MB/s  0
ms15-vio1  fcs2     0x210000XXXXX56EC6  fcs2   318.10/s   83.39 MB/s  480.78/s   126.03 MB/s  0
aixtsmp1   fcs5     0xC050760XXXXX003E  fcs0   583.98/s   60.35 MB/s  1835.17/s  124.86 MB/s  0
ms15-vio1  fcs5     0x10000090XXXXX12D  fcs5   583.70/s   60.27 MB/s  1836.21/s  124.92 MB/s  0
ms15-vio1  fcs0     0x21000024XXXXXEC4  fcs0   923.19/s  165.08 MB/s  1032.81/s   17.25 MB/s  46
aixtsmp3   fcs1     0xC050760XXXXX00E4  fcs0   775.12/s  129.48 MB/s  1047.32/s   17.15 MB/s  20
aixtsmp3   fcs0     0xC050760XXXXX00DE  fcs1   775.78/s  128.99 MB/s  1037.99/s   17.39 MB/s  20
aixtsmp1   fcs1     0xC050760XXXXX0056  fcs5     0.00/s    0.00 B/s   290.39/s    76.12 MB/s  0
aixtsmp1   fcs0     0xC050760XXXXX0052  fcs4   142.89/s   36.12 MB/s    0.00/s     0.00 B/s   26
ms15-vio1  fcs4     0x10000090XXXXX12C  fcs4   234.97/s    4.58 MB/s  621.78/s    11.12 MB/s  40
cus1dbp01  fcs4     0xC050760XXXXX0047  fcs0   243.55/s    5.05 MB/s  432.33/s     9.95 MB/s  0
cus1dbi01  fcs4     0xC050760XXXXX0044  fcs1     0.94/s   10.42 KB/s   87.28/s   459.26 KB/s  0
...
HOSTNAME   PHYSDEV  WWPN                DEV    INREQS     INBYTES      OUTREQS    OUTBYTES     CTRLREQS
aixtsmp1   fcs5     0xC050760XXXXX003E  fcs0   1772.84/s  162.24 MB/s  1309.30/s   70.60 MB/s  68
ms15-vio1  fcs5     0x10000090XXXXX12D  fcs5   1769.13/s  161.95 MB/s  1305.60/s   70.54 MB/s  68
ms15-vio1  fcs1     0x21000024XXXXXEC5  fcs1   883.55/s   118.97 MB/s  1551.97/s  108.78 MB/s  43
ms15-vio1  fcs2     0x21000024XXXXXEC6  fcs2   201.09/s    52.72 MB/s  497.26/s   130.35 MB/s  0
aixtsmp1   fcs2     0xC050760XXXXX0058  fcs6   201.09/s    52.72 MB/s  495.40/s   129.87 MB/s  0
ms15-vio1  fcs0     0x21000024XXXXXEC4  fcs0   923.54/s   128.89 MB/s  1234.98/s   23.31 MB/s  65
aixtsmp3   fcs0     0xC050760XXXXX00DE  fcs1   876.93/s   118.93 MB/s  1234.98/s   23.32 MB/s  44
aixtsmp3   fcs1     0xC050760XXXXX00E4  fcs0   884.17/s   119.07 MB/s  1223.50/s   23.00 MB/s  43
aixtsmp1   fcs1     0xC050760XXXXX0056  fcs5     0.00/s     0.00 B/s   325.83/s    85.41 MB/s  0
...
^C
$

Ausgegeben werden der LPAR-Name, der physikalische FC-Port (PHYSDEV) auf dem Virtual-I/O-Server, die WWPN des Client Adapters, der virtuelle FC-Port (DEV), sowie die Anzahl Requests (INREQS und OUTREQS) und dabei transferierte Bytes (INBYTES und OUTBYTES). Die Transfer-Raten werden dabei jeweils in KB/s, MB/s oder GB/s ausgegeben. Auf größeren Systemen kann die Ausgabe sehr lang werden! Die Ausgabe wird ist nach Durchsatz sortiert, d.h. die aktivsten virtuellen Clients Adapter werden als erstes ausgegeben. Über die Option ‚-t‚ (Top) kann die Ausgabe auf eine gewünschte Zahl von Datensätzen eingeschränkt werden: z.B. werden mit ‚-t 10‚ nur die 10 Adapter mit dem höchsten Durchsatz ausgegeben. Zusätzlich kann über ein weiteres Argument auch die Intervall Länge (in Sekunden) angegeben werden, hier ein kurzes Beispiel:

$ vios fcstat -t 10 ms15-vio1 2
HOSTNAME   PHYSDEV  WWPN                DEV   INREQS     INBYTES      OUTREQS    OUTBYTES     CTRLREQS
ms15-vio1  fcs1     0x21000024XXXXXEC5  fcs1  1034.58/s   86.56 MB/s  2052.23/s  160.11 MB/s  20
ms15-vio1  fcs5     0x10000090XXXXX12D  fcs5  1532.63/s  115.60 MB/s  1235.72/s  118.32 MB/s  40
aixtsmp1   fcs5     0xC050760XXXXX003E  fcs0  1510.33/s  114.88 MB/s  1236.49/s  118.27 MB/s  40
aixtsmp3   fcs1     0xC050760XXXXX00E4  fcs0  1036.11/s   86.67 MB/s  1612.25/s   44.86 MB/s  20
aixtsmp3   fcs0     0xC050760XXXXX00DE  fcs1  1031.50/s   86.29 MB/s  1588.02/s   44.27 MB/s  20
ms15-vio1  fcs0     0x21000024XXXXXEC4  fcs0  1029.58/s   86.31 MB/s  1567.63/s   43.65 MB/s  20
aixtsmp1   fcs1     0xC050760XXXXX0056  fcs5    0.00/s     0.00 B/s   436.52/s   114.43 MB/s  0
ms15-vio1  fcs2     0x21000024XXXXXEC6  fcs2    0.00/s     0.00 B/s   435.75/s   114.23 MB/s  0
aixtsmp1   fcs2     0xC050760XXXXX0058  fcs6    0.00/s     0.00 B/s   432.68/s   113.42 MB/s  0
ms15-vio1  fcs4     0x10000090XXXXX12C  fcs4  144.99/s     0.78 MB/s  478.83/s     2.22 MB/s  46
HOSTNAME   PHYSDEV  WWPN                DEV   INREQS    INBYTES      OUTREQS    OUTBYTES     CTRLREQS
aixtsmp1   fcs5     0xC050760XXXXX003E  fcs0  758.14/s   35.55 MB/s  1822.99/s  112.60 MB/s  0
ms15-vio1  fcs5     0x10000090XXXXX12D  fcs5  757.38/s   35.52 MB/s  1821.46/s  112.59 MB/s  0
ms15-vio1  fcs0     0x21000024XXXXXEC4  fcs0  944.23/s   85.09 MB/s  1657.58/s   41.40 MB/s  2
aixtsmp3   fcs0     0xC050760XXXXX00DE  fcs1  943.47/s   85.15 MB/s  1636.90/s   40.68 MB/s  2
ms15-vio1  fcs1     0x21000024XXXXXEC5  fcs1  949.21/s   84.88 MB/s  1586.74/s   39.41 MB/s  2
aixtsmp3   fcs1     0xC050760XXXXX00E4  fcs0  946.53/s   84.64 MB/s  1584.83/s   39.40 MB/s  2
ms15-vio1  fcs4     0x10000090XXXXX12C  fcs4   39.44/s  449.92 KB/s  676.97/s     3.63 MB/s  10
cus1dbp01  fcs4     0xC050760XXXXX0047  fcs0   29.10/s  471.69 KB/s  310.92/s     1.28 MB/s  4
cus1mqp01  fcs4     0xC050760XXXXX002C  fcs0    1.91/s    4.71 KB/s  230.12/s     1.66 MB/s  0
cus2orap01 fcs4     0xC050760XXXXX000F  fcs0    0.77/s    4.31 KB/s   48.25/s   263.49 KB/s  0
^C
$

Über die Option ‚-s‚ (Select) können auch nur Datensätze eines bestimmten Clients (‚-s hostname=aixtsmp1‚) oder nur Datensätze eines bestimmten physikalischen Ports (‚-s physdev=fcs1‚) ausgewählt und ausgegeben werden:

$ vios fcstat -s hostname=aixtsmp1 ms15-vio1 2
HOSTNAME  PHYSDEV  WWPN                DEV   INREQS     INBYTES      OUTREQS    OUTBYTES     CTRLREQS
aixtsmp1  fcs5     0xC050760XXXXX003E  fcs0  1858.72/s   51.14 MB/s  1231.82/s  104.20 MB/s  0
aixtsmp1  fcs2     0xC050760XXXXX0058  fcs6    6.94/s     1.82 MB/s    6.94/s     1.82 MB/s  0
aixtsmp1  fcs4     0xC050760XXXXX0042  fcs2    0.39/s     1.19 KB/s    0.39/s   395.05 B/s   0
aixtsmp1  fcs1     0xC050760XXXXX0056  fcs5    0.39/s     7.72 B/s     0.00/s     0.00 B/s   1
aixtsmp1  fcs0     0xC050760XXXXX0052  fcs4    0.00/s     0.00 B/s     0.00/s     0.00 B/s   0
aixtsmp1  fcs3     0xC050760XXXXX005A  fcs7    0.00/s     0.00 B/s     0.00/s     0.00 B/s   0
HOSTNAME  PHYSDEV  WWPN                DEV   INREQS     INBYTES      OUTREQS    OUTBYTES     CTRLREQS
aixtsmp1  fcs5     0xC050760XXXXX003E  fcs0  1760.48/s  111.48 MB/s  1125.70/s   95.20 MB/s  0
aixtsmp1  fcs2     0xC050760XXXXX0058  fcs6    8.53/s     2.24 MB/s  484.61/s   127.04 MB/s  0
aixtsmp1  fcs1     0xC050760XXXXX0056  fcs5    0.00/s     0.00 B/s   469.04/s   122.96 MB/s  0
aixtsmp1  fcs4     0xC050760XXXXX0042  fcs2    0.37/s     1.14 KB/s    0.00/s     0.00 B/s   0
aixtsmp1  fcs0     0xC050760XXXXX0052  fcs4    0.00/s     0.00 B/s     0.00/s     0.00 B/s   0
aixtsmp1  fcs3     0xC050760XXXXX005A  fcs7    0.00/s     0.00 B/s     0.00/s     0.00 B/s   0
^C
$

Mit dem „vios fcstat“ Kommando lassen sich auf extrem einfache Weise jederzeit FC-Durchsatz von beliebigen LPARs, sozusagen auf Knopfdruck, ausgeben.

Bei kleineren Intervallen leidet die Genauigkeit der angezeigten Werte. Bei 2 Sekunden Intervallen beträgt die Ungenauigkeit ca 10%. Die Relationen zwischen den angezeigten Werten ist allerdings korrekt.

nmon_printer: schneller Blick in NMON-Dateien

Viele Administratoren setzen NMON zum Sammeln von Performance-Daten auf AIX-Systemen ein. Die gesammelten Daten können dann z.B. mit dem NMON-Analyzer graphisch visualisiert werden. Alternativ kann man natürlich auch njmon einsetzen. Manchmal möchte man einen schnellen Blick in eine NMON-Datei noch auf dem AIX-System werfen. Das geht natürlich mit grep, awk , und anderen Standard UNIX Utilities. Es muss aber immer erst die passende Kommandozeile überlegt und eingetippt werden und die Ausgabe ist dann auch nicht immer sehr übersichtlich.

Für einen solchen schnellen Blick in eine NMON-Datei haben wir in umserem Download Bereich das Skript nmon_printer zur Verfügung gestellt. Mit dem nmon_printer kann man zunächst einmal auflisten welche Daten grundsätzlich in der NMON-Datei gesammelt wurden:

$ nmon_printer -l aix01_200718.nmon
CPU_ALL -     CPU Total aix01
CPU01 -       CPU 1 aix01
CPU02 -       CPU 2 aix01
CPU03 -       CPU 3 aix01
CPU04 -       CPU 4 aix01
CPU05 -       CPU 5 aix01
CPU06 -       CPU 6 aix01
CPU07 -       CPU 7 aix01
CPU08 -       CPU 8 aix01
MEM -         Memory aix01
MEMNEW -      Memory New aix01
MEMUSE -      Memory Use aix01
PAGE -        Paging aix01
...
$

Zum Anzeigen der Datensätze gibt man neben dem NMON File noch den gewünschten darzustellenden Datensatz an, Groß- oder Klein-Schreibung spielt dabei keine Rolle. Hier eine Beispiel für CPU_ALL:

$ nmon_printer aix01_200718.nmon cpu_all
  CPU_ALL             Timestamp  User%  Sys%  Wait%  Idle%  Busy  PhysicalCPUs 
  CPU_ALL  00:05:15 17-JUL-2020    1.2   3.0    0.1   95.7   4.2              8
  CPU_ALL  00:10:15 17-JUL-2020    1.3   2.7    0.0   96.0   3.9              8
  CPU_ALL  00:15:15 17-JUL-2020    1.0   2.3    0.1   96.7   3.3              8
  CPU_ALL  00:20:16 17-JUL-2020    5.1   3.0    0.1   91.8   8.2              8
  CPU_ALL  00:25:16 17-JUL-2020    1.2   2.7    0.0   96.0   3.9              8
  CPU_ALL  00:30:16 17-JUL-2020    1.1  17.5    0.1   81.3  18.5              8
  CPU_ALL  00:35:16 17-JUL-2020    1.1   5.8    0.0   93.1   6.9              8
...
$

In manchen Fällen hat ein Datensatz soviel Felder, das die Zeilen umgebrochen werden und die Ausgabe dann etwas unübersichtlich wird. Der Datensatz LPAR hat z.B. 23 Felder! Für solche Fälle, oder falls man nur an bestimmten Feldern interessiert ist, kann man mit der Option ‚-f‚ die gewünschten Felder angeben. Dabei kann man entweder die gewünschten Felder durch Komma getrennt angeben:

$ nmon_printer -f 0,1,2,13,14,15 aix01_200718.nmon lpar
  LPAR             Timestamp  PhysicalCPU  EC_User%  EC_Sys%  EC_Wait%
  LPAR  00:05:15 17-JUL-2020        0.037      1.23     2.95      0.00
  LPAR  00:10:15 17-JUL-2020        0.034      1.28     2.66      0.00
  LPAR  00:15:15 17-JUL-2020        0.029      1.03     2.25      0.00
  LPAR  00:20:16 17-JUL-2020        0.064      5.14     3.01      0.00
  LPAR  00:25:16 17-JUL-2020        0.035      1.21     2.69      0.00
  LPAR  00:30:16 17-JUL-2020        0.150      1.08    17.46      0.02
  LPAR  00:35:16 17-JUL-2020        0.063      1.13     5.77      0.00
  LPAR  00:40:16 17-JUL-2020        0.030      1.13     2.24      0.00
  LPAR  00:45:16 17-JUL-2020        0.030      1.06     2.34      0.00
...
$

Oder man kann auch Bereiche angeben (z.B. 0-2 oder 13-15):

$ nmon_printer -f 1,5-7 aix01_200718.nmon ioadapt
             Timestamp  fcs1_read-KB/s  fcs1_write-KB/s  fcs1_xfer-tps
  00:05:15 17-JUL-2020             0.0             27.3            3.0
  00:10:15 17-JUL-2020             0.0              0.0            2.6
  00:15:15 17-JUL-2020             0.0             13.6            2.8
  00:20:16 17-JUL-2020             0.0             13.6            2.3
  00:25:16 17-JUL-2020             0.0             13.7            2.3
  00:30:16 17-JUL-2020            27.3           4982.5           89.4
  00:35:16 17-JUL-2020            13.7             27.3            4.1
  00:40:16 17-JUL-2020             0.0             13.6            2.6
  00:45:16 17-JUL-2020             0.0             13.6            2.6
...
$

Die Zählung der Felder beginnt jeweils bei 0.

ProbeVue in Action: Überwachen der „Queue Depth“ von Platten

Platten und Storage Systeme unterstützen Tagged Command Queueing, d.h. angeschlossene Server können mehrere I/O Aufträge an die Platte oder das Storage-System senden ohne zu Warten das ältere I/O-Aufträge fertig sind. Wieviele I/O-Aufträge man an eine Platte senden darf, bevor man warten muss das ältere I/O-Aufträge abgeschlossen wurden, kann über das hdisk Attribut queue_depth unter AIX konfiguriert werden. Für viele hdisk Typen ist der Wert 20 für die queue_depth der Default-Wert. In der Regel erlauben die meisten Storage-Systeme aber noch größere Werte für die Queue-Depth.

Mit Hilfe von ProbeVue lässt sich die Auslastung der Platten-Queue sehr leicht beobachten.

Ab AIX 7.1 TL4 bzw. AIX 7.2 TL0 unterstützt AIX den I/O Probe Manager. Damit lassen sich auf einfache Weise Ereignisse im I/O Stack von AIX tracen. Wird ein I/O vom Platten-Treiber gestartet, so geschieht dies über die Funktion iostart im Kernel, der Request wird an den Adapter-Treiber weitergegeben und geht dann über den Host-Bus-Adapter an das Storage-System. Das Bearbeiten der Antwort wird von der Funktion iodone im Kernel übernommen. Der I/O Probe-Manager unterstützt (unter anderem) Proben an diesen Stellen:

@@io:disk:iostart:read:<filter>
@@io::disk:iostart:write:<filter>
@@io:disk:iodone:read:<filter>
@@io::disk:iodone:write:<filter>

Als Filter kann z.B. ein Hdisk Name wie hdisk2 angegeben werden. Die Proben-Punkte lösen dann nur Ereignisse für die Platte hdisk2 aus. Damit lässt sich schon einmal eine Aktion durchführen wann immer ein I/O für eine Hdisk beginnt oder endet. Damit könnte man z.B. messen wie lange eine I/O Operation dauert oder auch einfach nur mitzählen wieviele I/Os ausgeführt werden. In unserem Beispiel waren wir aber an der Auslastung der Platten-Queue interessiert, d.h. der Anzahl I/Os die an die Platte gesendet aber noch nicht abgeschlossen wurden. Der I/O Probe-Manager besitzt für die I/O Ereignisse  iostart und iodone die Builtin-Variable __diskinfo mit den folgenden Feldern (https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.genprogc/probevue_man_io.htm):

name          char*     Name der Platte
…
queue_depth   int       Die Queue-Depth der Platte (Wert aus der ODM)
cmds_out      int       Anzahl der ausstehenden I/Os
…

Das Feld cmds_out gibt an wieviele I/Os an die Platte gesendet wurden, für die das I/O noch nicht abgeschlossen ist (Antwort ist noch nicht beim Server angekommen).

Mit dem folgenden Code-Abschnitt ermitteln wir die minimale, maximale und durchschnittliche Anzahl an Einträgen in der Platten-Queue:

@@io:disk:iostart:*:hdisk0     // Nur I/Os für hdisk0 berücksichtigen
{
   queue = __iopath->cmds_out; // Anzahl ausstehende I/Os in Variable queue festhalten
   ++numIO;                    // Anzahl I/Os in der Variablen numIO mitzählen (wegen Durchschnittsbildung)
   avg += queue;               // Variable avg um Anzahl ausstehende I/Os erhöhen
   if ( queue < min )
      min = queue;             // Überprüfen auf Minimum und gegebenenfalls setzen
   if ( queue > max )
      max = queue;             // Überprüfen auf Maximum und gegebenenfalls setzen
}

Die ermittelten Werte geben wir dann einmal pro Sekunde mit Hilfe des Intervall Probe-Managers aus:

@@interval:*:clock:1000
{
   if ( numIO == 0 )
      numIO = 1;    // Verhindert Division durch 0 bei der Durchschnittsbildung
   if ( min > max )
      min = max;
   printf( "%5d  %5d  %5d\n" , min , avg/numIO , max );
   min = 100000;   // Zurücksetzen der Variablen für das nächste Intervall
   avg = 0;
   max = 0;
   numIO = 0;
}

Das vollständige Skript ist auf unserer Webseite zum Download verfügbar: ioqueue.e.

Hier ein Beispiel-Lauf des Skriptes für die Platte hdisk13:

# ./ioqueue.e hdisk13
  min    avg    max
    1      1      2
    1      1      9
    1      1      2
    1      1      8
    1      1      2
    1      1      2
    1      1      8
    1      1     10
    1      1      2
    1      1      1
    1      1     10
    1      1      2
    1      1     11
...

Das Skript erwartet die Angabe einer hdisk als Argument und gibt dann einmal pro Sekunde die ermittelten Werte für die angegebene hdisk aus.

In der Beispiel-Ausgabe sieht man das die maximale Anzahl der Einträge in der Platten-Queue 11 ist. Eine Erhöhung des Attributes queue_depth macht daher aus Performance-Sicht keinen Sinn.

Hier ein anderes Beispiel:

# ./ioqueue.e hdisk21
  min    avg    max
    9     15     20
   11     17     20
   15     19     20
   13     19     20
   14     19     20
   17     18     20
   18     18     19
   16     19     20
   13     18     20
   18     19     19
   17     19     20
   18     19     20
   17     19     19
...

In diesem Fall wird der maximale Wert 20 (die hdisk21 hat eine queue_depth von 20) regelmäßig erreicht. Eine Erhöhung der queue_depth kann in diesem Fall zu einer Verbesserung des Durchsatzes führen.

Das Beispiel-Skript lässt sich natürlich noch beliebig erweitern, man könnte z.B. noch den Durchsatz erfassen, oder die Wartezeit von I/Os in der Wait-Queue oder auch die Position und Größe jedes I/Os auf der Platte. Das dargestellte Beispiel zeigt wie einfach man Informationen zu I/Os mit Hilfe von ProbeVue ermitteln kann.

Weitere Artikel zum Thema ProbeVue

ProbeVue: Praktische Einführung

ProveVue: Praktische Einführung II

ProbeVue in Action: Identifizieren eines Abstürzenden Prozesses

ProbeVue in Action: Überwachen der „Queue Depth“ von Platten