Donnerstag Apr 14, 2016

Sockel, Core, Strand - Wo laufen meine Zonen?

Konsolidierung mit Solaris Zonen ist weit verbreitet.  Oft werden dabei, um die beste Auslastung zu erreichen, alle Zonen auf allen verfuegbaren CPUs betrieben.  In diesem Fall kuemmert sich Solaris darum, dass Programme auf der am besten geeigneten CPU ausgefuehrt werden und die vorhandenen Resourcen fair aufgeteilt werden.  Es gibt jedoch auch Faelle, in denen man einer oder mehreren Zonen einige CPUs fest zuweisen will, z.B. aus Lizenzgruenden oder um eine staerkere Trennung der Lasten zu erreichen.  Diese Trennung erreicht man entweder mit der Einstellung "dedicated-cpu" in der Zonen-Konfiguration, oder durch die Bindung an einen bestehenden Resource-Pool, der wiederum ein Prozessorset enthaelt.  Da im ersten Fall beim Start der Zone ein temporaerer Resource-Pool angelegt wird, ist die technische Umsetzung in beiden Faellen die gleiche.  Der Effekt eines solchen Prozessorsets ist, dass die darin enthaltenen CPUs exklusiv fuer die dem Set zugeordneten Zonen verfuegbar sind.  D.h. diese Zonen haben nicht mehr, aber auch nicht weniger CPUs zur Verfuegung, und alles andere (die Global Zone, alle anderen Zonen) koennen nicht mehr auf diesen CPUs ausgefuehrt werden.

Dieser Artikel widmet sich der Frage, welche CPUs man in ein solches Prozessorset legen sollte, und wie man feststellen kann, welche Zone derzeit auf welchen CPUs laeuft.

Vorab jedoch ein paar Definitionen, da auch hier wieder unterschiedliche Namen fuer verschiedene Konzepte ueblich sind:

  • Eine CPU ist ein Prozessor, bestehend aus ein oder mehreren Kernen, Cache sowie evtl. IO Controller und/oder Memory Controller
  • Ein Kern ist eine Recheneinheit auf einer CPU.
  • Ein Strand ist ein Einstiegspunkt in einen Kern, der die Rechenleistung des Kerns dem Betriebsystem verfuegbar macht.

Eine SPARC M7 CPU beispielsweise hat 32 Kerne, jeder Kern bietet 8 Strands, so dass eine M7 CPU dem Betriebsystem 32*8=256 Strands zur Verfuegung stellt.  Das Betriebsystem sieht jeden dieser Strands als vollwertige Ausfuehrungseinheit und zeigt deswegen 256 "CPUs" an.

Alle moderneren multi-core CPUs wenden bei den Caches verschiedene Lokalitaets-Ebenen an.  Waehrend der L3 Cache von allen Kernen gemeinsam benutzt wird, sind L2 und L1 Caches idR. pro Kern vorhanden. (Die M7 CPU wendet hier unterschiedliche Strategien an, aber auch hier nutzt jeder Kern einen exklusiven L1 Cache.)  Werden nun unterschiedliche Strands eines Kerns von der gleichen Anwendung genutzt, kann dies zu hoeheren Trefferraten in den entsprechenden Caches fuehren.  Werden diese Strands jedoch von unterschiedlichen Anwendungen genutzt, ist idR. das Gegenteil der Fall.  Die beiden Programme konkurieren dann um den Cache und verdraengen die Daten des jeweils anderen Programms regelmaessig aus den kleinen, lokalen Caches.  Man spricht hier von "Cache Thrashing".  Um dem entgegen zu wirken, wird allgemein empfohlen, verschiedene Zonen auf unterschiedliche Kerne zu binden, und zwar jeweils auf ganze Kerne.  Dies ist auch im Hinblick auf eventuelle Lizenzierung sinnvoll, die ja idR. ebenfalls kernweise erfolgt.

Wie kann man nun sicherstellen, dass die jeweiligen Zonen korrekt auf ganze, exklusive Kerne gebunden sind?

Solaris kennt die Zusammenhaenge zwischen Strand, Kern, CPU (und auch die Memory-Hierarchie, auf die ich hier jedoch nicht eingehen werde).  Diese kann man mit "kstat" abfragen.  Aus historischen Gruenden (aus der Zeit als es noch keine multi-core oder multi-strand CPUs gab) verwendet Solaris den Begriff "CPU" fuer einen Strand:

root@mars:~# kstat -m cpu_info -s core_id -i 150
module: cpu_info                        instance: 150   
name:   cpu_info150                     class:    misc
        core_id                         18

root@mars:~# kstat -m cpu_info -s chip_id -i 150
module: cpu_info                        instance: 150   
name:   cpu_info150                     class:    misc
        chip_id                         1

D.h die "CPU" mit der ID 150 ist ein Strand des Kerns 18 und der CPU 1.  Auf die gleiche Weise kann man natuerlich die gesamte vorhandene Infrastruktur erkunden.

Bei der Konfiguration von Prozessorsets fuer Resource Pools werden in der Regel einfach Minimum und Maximum der zu verwendenden Strandanzahl angegeben.  Alternativ kann man auch entweder CPU-IDs (also Strands) oder (seit Solaris 11.2) auch Core-IDs verwendet.  Die Kommandos hierfuer sind "pooladm" und "poolcfg".  (Es gibt auch das Kommando "psrset", das jedoch nur ein Prozessorset erzeugt, keinen Resource Pool, und deswegen nach jedem Reboot erneut ausgefuehrt werden muss.)  Die Verwendung dieser Kommandos habe ich bereits vor einiger Zeit beschrieben.  Um nun die Zuordnung von Strands, Kerne bzw. CPUs zu Zonen zu ermitteln, muss man die Strand-IDs des der Zone zugewiesenen Prozessorsets mittels kstat auf die Kerne und Prozessoren zurueckfuehren.  Das ist ein wenig muehsam, weswegen ich dafuer ein kleines Script geschrieben habe:

root@mars:~# ./zonecores -h
usage: zonecores [-Sscl] 
       -S report whole Socket use
       -s report shared use
       -c report whole core use
       -l list cpu overview

Dieses Script gibt mit "./zonecores -l" einen Ueberblick ueber die vorhandenen CPUs und die darauf laufenden Zonen aus.  Hier ein Beispiel von einem SPARC System mit 2 16-core CPUs:

root@mars:~# ./zonecores -l
#
# Socket, Core, Strand and Zone Overview
#
Socket Core Strands Zones
0      0    0,1,2,3,4,5,6,7 db2,
0      1    8,9,10,11,12,13,14,15 db2,
0      2    16,17,18,19,20,21,22,23 none
0      3    24,25,26,27,28,29,30,31 db2,
0      4    32,33,34,35,36,37,38,39 db2,
0      5    40,41,42,43,44,45,46,47 db2,
0      6    48,49,50,51,52,53,54,55 db2,
0      7    56,57,58,59,60,61,62,63 coreshare,db1,
0      8    64,65,66,67,68,69,70,71 db2,
0      9    72,73,74,75,76,77,78,79 none
0     10    80,81,82,83,84,85,86,87 none
0     11    88,89,90,91,92,93,94,95 none
0     12    96,97,98,99,100,101,102,103 none
0     13    104,105,106,107,108,109,110,111 none
0     14    112,113,114,115,116,117,118,119 none
0     15    120,121,122,123,124,125,126,127 none
1     16    128,129,130,131,132,133,134,135 none
1     17    136,137,138,139,140,141,142,143 none
1     18    144,145,146,147,148,149,150,151 none
1     19    152,153,154,155,156,157,158,159 none
1     20    160,161,162,163,164,165,166,167 none
1     21    168,169,170,171,172,173,174,175 none
1     22    176,177,178,179,180,181,182,183 none
1     23    184,185,186,187,188,189,190,191 none
1     24    192,193,194,195,196,197,198,199 none
1     25    200,201,202,203,204,205,206,207 none
1     26    208,209,210,211,212,213,214,215 none
1     27    216,217,218,219,220,221,222,223 none
1     28    224,225,226,227,228,229,230,231 none
1     29    232,233,234,235,236,237,238,239 none
1     30    240,241,242,243,244,245,246,247 db2,
1     31    248,249,250,251,252,253,254,255 none

Mit den Optionen -S, -s und -c wird geprueft, ob die Zonen ganze Sockel bzw. CPUs (-S) oder ganze Kerne (-c) verwenden.  Mit -s schliesslich wird geprueft, ob mehrere Zonen sich einen Kern teilen - was erwuenscht sein kann, oder auch nicht.  Hier ein Beispiel mit diversen Pools und Zonen auf dem selben System:

root@mars:~# ./zonecores -Ssc
#
# Checking Socket Affinity (16 cores per socket)
#
INFO - Zone db2 using 2 sockets for 8 cores.
OK - Zone db1 using 1 sockets for 1 cores.
OK - Zone capped7 using default pool.
OK - Zone coreshare using 1 sockets for 1 cores.
#
# Checking Core Resource Sharing
#
OK - Core 0 used by only one zone.
OK - Core 1 used by only one zone.
OK - Core 3 used by only one zone.
OK - Core 30 used by only one zone.
OK - Core 4 used by only one zone.
OK - Core 5 used by only one zone.
OK - Core 6 used by only one zone.
INFO - Core 7 used by 2 zones!
-> coreshare
-> db1
OK - Core 8 used by only one zone.
#
# Checking Whole Core Assignments
#
OK - Zone db2 using all 8 strands of core 0.
OK - Zone db2 using all 8 strands of core 1.
OK - Zone db2 using all 8 strands of core 3.
OK - Zone db2 using all 8 strands of core 30.
OK - Zone db2 using all 8 strands of core 4.
OK - Zone db2 using all 8 strands of core 5.
FAIL - only 7 strands of core 6 in use for zone db2.
FAIL - only 1 strands of core 8 in use for zone db2.
OK - Zone db1 using all 8 strands of core 7.
OK - Zone coreshare using all 8 strands of core 7.

Info: 1 instances of core sharing found.
Info: 1 instances of socket spanning found.
Warning: 2 issues found with whole core assignments.

Diese Ausgabe sollte recht selbsterklaerend sein, hier noch ein paar Worte dazu:

  • Die Zone db01 verwendet einen Resource Pool mit 8 Strands aus einem Kern.
  • Die Zone coreshare verwendet ebenfalls diesen Pool.
  • Die Zone db02 verwendet einen Resource Pool mit 64 Strands, die ueber Kerne aus zwei verschiedenen CPUs verteilt sind.  Einer der Kerne (Kern 6) wird nur mit 7 Strands verwendet, der letzte Strand liegt auf Kern 8.  Dies ist sicherlich so nicht gewuenscht.  Sinnvoller waere es, ganze Kerne sowie alle 8 Kerne aus der selben CPU zu verwenden.  Nicht nur muesste man so einen Kern wenige lizenzieren, Solaris wuerde dann beim Start der Zone auch versuchen, das zu den Prozessen gehoerende Memory so zu allokieren, dass moeglichst nur lokale Memory-Zugriffe notwendig werden - ein weiterer Grund, nach Moeglichkeit lokal zu bleiben.
  • Die Zone capped7 ist mit der Directive "capped-cpu: ncpus=7" konfiguriert.  Diese wird ueber den Fair Share Scheduler implementiert und bedient sich aus dem Default Pool.

Hier gibt es das Script zum Download: zonecores

Eine etwas ausfuehrlichere Besprechung mit Beispielen, wie man seine Poolkonfiguration veraendert, gibt es in MOS DocID 2116794.1

Weitere Links zum Thema:

ASM Scoped Security - Ein Realistisches Beispiel

Wenn man, z.B. auf SuperCluster, mehrere Instanzen der Grid Infrastruktur (gerne als RAC Cluster bezeichnet) betreibt, die die selben Exadata Storage Server (oder kurz Zellen) verwenden, ist es ratsam, ASM Scoped Security zu verwenden.  Selbst wenn es, wie z.B. bei mehreren Mandanten, keine Sicherheitsgruende dafuer gibt, kann man auf diese Weise immer verhindern, dass der Admin des einen Clusters versehentlich die Diskgruppe des anderen Clusters verwendet.  Als einfach umzusetzende Sicherheitsmassnahme ist das daher immer eine gute Idee.

Natuerlich gibt es fuer dieses Feature der Storage Zellen gute Dokumentation.  Allerdings steckt auch hier der Teufel im Detail, daher hier ein vollstaendiges Beispiel, wie man das macht:

  1. Den entsprechenden Cluster anhalten.  Kommando: "crsctl stop crs" auf allen Cluster Knoten.
  2. Einen Schluessel fuer den Cluster erzeugen
    Das macht, auf irgend einer Storage Zelle, das Kommando "cellcli -e create key".  Heraus kommt ein ASCII String, der als Schluessel zu verwenden ist.  Diesen Schluessel notiert man sich irgendow.  In diesem Beispiel verwende ich den Schluessel '9e9a606a461a1abc6af43626e85af3b7'.
  3. Nun denkt man sich einen eindeutigen Namen fuer den Cluster aus.  In diesem Beispiel verwende ich dafuer "marsc1" - der erste Cluster, der auf mars laeuft.
  4. Nun verknuepft man diesen Namen mit dem Schluessel.  Das muss auf jeder beteiligten Storage Zelle mit cellcli gemacht werden:
    CELLCLI> assign key for 'marsc1'='9e9a606a461a1abc6af43626e85af3b7'
  5. Hier kommt der komplizierteste Teil.  Der eindeutige Name muss nun jeder einzelnen Griddisk, die unser Cluster verwendet, zugewiesen werden.  Leider ist die Kommandozeile von CELLCLI hier nicht wirklich hilfreich.  Ich habe das so geloest:
    1. Auf jeder Zelle eine Liste aller Griddisks anlegen, die zu marsc1 gehoeren.  Mit CELLCLI:
      spool /tmp/disks
      list griddisk where asmdiskgroupname='DATAC1'
      list griddisk where asmdiskgroupname='RECOC1'
    2. Jetzt enthaelt /tmp/disks auf jeder Zelle eine Anzahl Zeilen aehnlich wie diese:
               DATAC1_CD_00_marsceladm04    active
               DATAC1_CD_01_marsceladm04    active
               DATAC1_CD_02_marsceladm04    active
               DATAC1_CD_03_marsceladm04    active
    3. Jetzt aendert man diese Datei in eine Kommando-Datei fuer CELLCLI.  Ich habe dafuer vi und awk verwendet, aber es geht sicher auch anders.  Das Ergebnis sah bei mir dann so aus:
      alter griddisk DATAC1_CD_00_marsceladm04 availableTo='marsc1'
      alter griddisk DATAC1_CD_01_marsceladm04 availableTo='marsc1'
      alter griddisk DATAC1_CD_02_marsceladm04 availableTo='marsc1'
      alter griddisk DATAC1_CD_03_marsceladm04 availableTo='marsc1'
    4. Jetzt laesst man dieses Script auf jeder Zelle laufen.  Natuerlich gibt es fuer jede Zelle ein eigenes Script!
      # cellcli < script
    5. Und jetzt noch nachsehen, ob es geklappt hat, wieder mit CELLCLI:
      list griddisk attributes name,availableTo
  6. Damit nun die Cluster-Knoten auf diese Griddisks zugreifen koennen, brauchen sie natuerlich das Name/Schluessel-Paerchen.  Das legt man unter Solaris auf jedem Knoten in der Datei /etc/oracle/cell/network-config/cellkey.ora ab.
    Meine sieht so aus:
    key=9e9a606a461a1abc6af43626e85af3b7
    asm=marsc1
  7. Nun noch die Cluster-Knoten neu starten:
    crsctl start crs

Das sollte alles sein.  Um zu pruefen, ob es geklappt hat, kann man in einem anderen Cluster mit dem Kommando "asmcmd lsdg --discovery" nachsehen, welche Griddisks verfuegbar sind.  Die eben geschuetzten sollten nicht mehr darunter sein.

Nun muss man das Ganze natuerlich fuer alle anderen Cluster wiederholen.  Am Ende hat man Cluster mit exklusivem Zugriff auf die eigenen Platten.  Ganz ohne die Gefahr von unabsichtlichem oder gar boesswilligem Zugriff unberechtigter.

Ein Tool, das ich zur Arbeit an den vielen Zellen sehr hilfreich finde, ist uebrigens "cssh", eine 1-N Kommandozeile die in neueren Versionen von Solaris enthalten ist.

Mittwoch Dez 23, 2015

OVM Templates fuer SPARC - Teil 3: Templates fuer SuperCluster

Wie auch bei den vorangegangenen Teilen dieser Mini-Serie ist dies die Blog-Version meines MOS-Artikels  2065199.1.  Allerdings weiche ich hier deutlicher vom "Original" ab.

Im zweiten Teil haben wir gesehen, wie man ein Template erzeugt und auf einem einzelnen System installiert.  Das war relativ einfach und wie gewohnt an der Kommandozeile zu machen.  Auf SuperCluster ist das anders.  Zuerst einmal kann man auf SuperCluster keine Templates erzeugen.  Das liegt daran, dass es nicht erlaubt ist, "von Hand" Domains anzulegen und alle Domains, die mit SuperCluster Tools angelegt werden keine Dateien als Backend fuer den rpool verwenden.  Dafuer ist die Installation mit dem "IO Domain Creation Tool" um so einfacher.

Dieses "IO Domain Creation Tool" verwaltet alle Aspekte des Lebenszyklus einer IO Domain.  Das ist ein neuer Typ von Domain die in der Version 2.0 der SuperCluster Software eingefuehrt wurde.  Mit dem Tool und den IO Domains werde ich mich hier nicht weiter beschaeftigen.  Interessierte finden die Details in der offiziellen Dokumentation.  IO Domains koennen jedoch auch mittels eines Templates installiert werden, und darum soll es hier gehen.

Auf einem einzelnen System ist man selbst fuer die Verwaltung der Templates verantwortlich.  Normalerweise wird man sie auf einem NFS-Share vorhalten.   Auf SuperCluster ist diese Sammlung in den Tools als Bibliothek implementiert, aus der man sich bei Bedarf ein Template zur Installation aussuchen kann.  Um eine Domain mit einem neuen Template zu installieren, muss dieses daher erst einmal in die Bibliothek importiert werden.  Damit das klappt, muss die Template-Datei irgendwo im Filesystem der Primary Domain des ersten Knotens des SuperClusters liegen.  In unserem Beispiel ist das /net/192.168.30.1/export/ssc/templates/pae/template-demo.ova.  Im IO Domain Creation Tool oeffnet man den "OVM Templates" Tab, gibt dort den vollen Pfadnamen der OVA-Datei ein und klickt auf "Add Template".  (Die Screenshots rechts werden lesbar, wenn man sie anklickt.)
Das Template wird jetzt in die Library importiert.  Das dauert eine Weile, weil die OVA-Datei ausgepackt und die Disk-Images dekomprimiert werden.  Leider gibt es keine Fortschrittsanzeige, aber man kann von Zeit zu Zeit den Inhalt der Bibliothek ueberpruefen.


Nach erfolgreichem Import findet man das Template im Inhaltsverzeichnis der Bibliothek.  Zu beachten ist, dass es derzeit nicht moeglich ist, ein Template hier wieder zu loeschen oder sonstwie zu veraendern.  Daran wird gerade gearbeitet...


Reservierung der Hardware und Auswahl des Templates

Auf  SuperCluster kann man nicht einfach mit ldm Kommandos eine neue Domain anlegen, wie man das von einzelnen Systemen gewohnt ist.  Alle Hardware, die fuer IO Domains zur Verfuegung steht, wird vom IO Domain Subsystem verwaltet.  Daher muss man neue Domains und dafuer benoetigte Hardware dort anfordern.  Dazu waehlt man den "IO Domains" Tab im IO Domain Creation Tool.  Hier wird eine Liste der bestehenden IO Domains angezeigt.  Um eine neue zu erzeugen, klickt man auf "Add IO Domain".  Im  nun folgenden Dialog waehlt man das gewuenschte Template als Domain Typ und die gewuenschte Groesse als "Domain Recipie".  Diese Hardware-Auswahl wird statt der im Template vorgegebenen Resourcen verwendet werden.  Weiter geht's mit "Next".


Nun wird man nach Angaben zu verschiedenen Eigenschaften der Domain gefragt.  Manche davon sind bspw. Hostnames fuer diverse Netzwerk-Adapter.  Diese sind SuperCluster spezifisch und werden unabhaengig von etwaigen Einstellungen im Template gesetzt.  Abhaengig vom Template gibt es evtl. weitere Eigenschaften, deren Werte hier angegeben werden koennen.  In unserem Beispiel werden die drei Eigenschaften abgefragt, die zuvor definiert wurden.   Wenn alles stimmt, kommt man mit "Allocate" wieder zurueck zur Domain-Uebersicht.  Die Hardware ist jetzt fuer die Domain reserviert.


Am oberen Ende der Anzeige werden einem einige Netzwerk-Details angezeigt.  Die IP-Adressen waehlt das Tool selbst aus einem Pool von Adressen, der vorab konfiguriert wurde.  Diese Adressen sollte man sich merken, um nach der Installation an die Domain zu kommen.

Installation der Domain

Der letzt Schritt ist sehr einfach.  Um die Installation anzustossen, einfach die Domain in der Liste auswaehlen und auf "Deploy" klicken.  Nach einer letzten Bestaetigung wird die Domain erzeugt und mit dem Template installiert.

Jetzt bleibt nur, auf das Ende der Installation zu warten.


Nach Abschluss der Installation kann man auch einige Details der Domain einsehen.


Und man kann nun natuerlich auch nachsehen, ob die Anwendung funktioniert.


Unterschiede zu Templates auf einzelnen Systemen

Wenn man Domains auf einzelnen Systemen installiert, werden sie anhand der Angaben im Template konfiguriert.  D.h. die Anzahl der CPUs, die Groesse des Hauptspeichers und die Anzahl der Netzwerk-Interfaces, der Typ und der Speicherort der Disk Images werden alle entweder dem Template entnommen oder durch den Administrator bei der Installation mit angegeben.  Auf SuperCluster wird all das durch das IO Domain Creation Tool kontrolliert:

  • Die Domain-Groesse (CPUs, RAM) wird anhand von vorher definierten "Domain Recipies" ausgewaehlt und gesetzt.
  • Die Netzwerk-Anschluesse werden entsprechend der SuperCluster Umgebung konfiguriert.  Jegliche Voreinstellungen im Template werden dabei ignoriert.
  • Disk Images werden grundsaetzlich als iSCIS LUNs vom zentralen ZFS Array geliefert.  Nur die Groesse wird dem Template entnommen.
  • /etc/hosts wird mit Eintraegen aus der SuperCluster Umgebung befuellt.
  • Der Solaris Publisher wird entsprechend der SuperCluster Umgebung gesetzt.  Dabei wird auch der zusaetzliche "exa-family" Publisher konfiguriert.  Eventuelle weitere Publisher bleiben erhalten.
  • ssctuner wird installiert und aktiviert.
  • Das Root-Passwort der Domain wird auf ein Default-Passwort gesetzt.

Unterm Strich haben diese Aenderungen zur Folge, dass die IO Domain, obwohl sie aus einem Template installiert wurde, eine normale SuperCluster IO Domain ist.  Sie hat volle Konnektivitaet in die SuperCluster Umgebung und ist voll supported, wie jede andere "Application Domain" auch.  Das bedeutet auch, dass alle Einschraenkungen, die etwa fuer Application IO Domains gelten sollten, auch fuer diese Domains gelten.

Weitere Links gab es bereits am Ende des ersten Teils dieser Mini-Serie.

Freitag Dez 04, 2015

OVM Templates fuer SPARC - Teil 2: Templates Erstellen

Der wesentliche Sinn eines Templates ist es, eine Anwendung mit einer Umgebung auszuliefern, in der alles vorhanden ist, was die Anwendung braucht, aber auch nicht mehr als noetig.  Ein Template wird mehrfach installiert werden - dazu muss jede Instanz konfiguriert werden um eine "Persoenlichkeit" zu bekommen und evtl. mit anderen Komponenten verknuepft zu werden.  Um ein solches Template zu erstellen, muss man daher die Anwendung sehr gut kennen.  Evtl. braucht man ein Script, um die Anwendung nach der Installation des Templates beim ersten Start der Instanz zu konfigurieren.  Alles, was nicht automatisch beim ersten Start konfiguriert wird, muss manuell nachgearbeitet werden, was ja gerade vermieden werden soll.  Wie man solche First-Boot-Scripts schreibt, werde ich hier nicht naeher betrachten.

(Dieser Artikel ist die Blog-Version des zweiten Teils von MOS DocID 2063739.1 die hier fuer einfachen Zugriff wiedergegeben wird.)

Dies sind die Schritte um ein Template zu erstellen:
  1. Eine neue Domain erzeugen und Solaris und die ovmtutils installieren.
  2. Die fuer die Anwendung notwendigen Parameter definieren.
  3. Die Anwendung installieren und so weit wie moeglich konfigurieren.
  4. Ein First-Boot Script oder SMF Service schreiben und testen um Werte fuer diese Parameter mittels der Ovmt Tools auszulesen und die Anwendung damit zu konfigurieren.
  5. Solaris dekonfigurieren, ungenutzte Dateien loeschen und die Domain anhalten.
  6. Das Template erzeugen. 
  7. Das Template testen.  Ggf. obiges wiederholen um Probleme zu loesen.

Bevor wir uns diese Schritte naeher ansehen, hier ein wenig Hintergrund zu den Parametern oder Eigenschaften eines Templates.

Parameter eines Templates

Die meisten Anwendungen brauchen ein wenige Konfiguration, bevor man sie nutzen kann.  Typische Parameter sind z.B. TCP Ports auf denen die Anwendung erreichbar ist, Admin Passwoerter fuer ein Web User Interface oder die IP-Adresse einer zentralen Instanz.  Diese Werte werden normalerweise bei der manuellen Installation der Anwendung gesetzt.  Aber genau das wollen wir bei Templates ja vermeiden.  Deswegen brauchen wir eine Moeglichkeit, der Anwendung in unserem Template diese Werte bei der Installation mit auf den Weg zu geben.  Hier kommen die Parameter ins Spiel.  Alles womit man die Anwendung konfiguiert, wird als Parameter des Templates definiert.  Dazu gibt es eine Datei, in der diese Parameter definiert werden.  Diese Datei wird ein Teil des Templates.  Wichtig ist hier, dass in dieser Datei nur die Parameter definiert werden, nicht jedoch die Werte, die diese Parameter einmal haben werden!  Diese Werte werden erst bei der Installation des Templates vergeben.  Wie das bemacht wird, wurde schon im ersten Teil kurz gezeigt, als wir Solaris-Parameter an das Template weitergaben.

Parameter werden in einer kleinen XML-Datei definiert.  Sie haben ihrerseits diverse Eigenschaften wie bspw. einen Namen, der entweder voll qualifiziert oder einfach sein kann.  Desweiteren gibt es verschiedene Datentypen - Text, Zahl, Auswahlliste etc.  Diese werden ausfuehrlich im "Template Authoring Guide" beschrieben, der derzeit noch in Arbeit ist.  In unserem einfachen Beispiel verwenden wir lediglich Text-Parameter.

Die Werte fuer diese Parameter werden dem Template waehrend der Installation mit dem Tool "ovmtconfig" mitgegeben.  Dafuer gibt es zwei verschiedene Methoden.  Die Kompliziertere mounted dazu das Dateisystem des fertig installierten Zielsystems in der Control Domain und ruft dann ein beliebiges Script auf.  Diese Script kann dann durch direktes Arbeiten auf dem Dateisystem das Zielsystem konfigurieren.  Auf diese Weise wird bspw. ein AI Profil generiert und an die Domain weitergegeben, damit Solaris beim ersten Starten korrekt konfiguriert wird.  Die zweite Methode verwendet VM Variablen, um Parameter-Werte an die Domain weiter zu geben.  Diese koennen dann nach dem ersten Booten mit "ovmtprop" ausgelesen werden.  Deswegen ist es hilfreich, die OVMT Utilities im Template zu installieren.  Wie man das macht, sehen wir gleich im Beispiel.

Eine Quell-Domain erstellen

Der erste Schritt in der Entwicklung eines Templates ist die Erstellung einer Quell-Domain.  Hier wird die Anwendung installiert, konfiguriert und getestet.  Insb. das First-Boot-Script welches die Anwendung anhand der Parameter des Templates konfiguriert sollte gut getestet werden.  Hier ein paar Empfehlungen fuer diese Domain:

  • Man sollte ein einzelnes SPARC sun4v system verwenden, um das Template zu entwickeln, keinesfalls jedoch die Control Domain eines SuperCluster.  Dies ist nicht supported und wird auch nicht funktionieren.
  • Die Domain sollte moeglichst einfach gehalten werden:
    • Nach Moeglichkeit nur ein Netzwerk-Interface verwenden.  Das macht es hinterher einfacher, das Template in unterschiedlichen Umgebungen einzusetzen.
    • Nur eine einzelnes Disk-Image fuer das Betriebsystem verwenden.  Dieses Image sollte nicht unnoetig gross sein, damit das Template einfach zu transportieren ist.  Auch die Installation wird dadurch einfacher.
    • Falls erforderlich, kann man ein oder mehrere weitere Disk Images fuer die Anwendung verwenden.  Eine Trennung vom Betriebsystem ist auch hier oft von Vorteil.
    • CPU und Memory sollten ebenfalls nur sparsam verwendet werden.  Bei Bedarf kann die installierte Ziel-Domain spaeter immer noch vergroessert werden.
    • Auch das Betriebsystem sollte moeglichst klein gehalten werden und nur die Pakete enthalten, die von der Anwendung gebraucht werden.  Am besten faengt man mit "solaris-minimal-server" an und fuegt das hinzu, was die Anwendung braucht.
  • Die Disk-Images muessen einfache "flat files" sein.  Eine spaetere Version der Tools wird auch andere Disk-Optionen unterstuetzen.
  • Die Namen aller Disk-Image Dateien muessen mit ".img" enden.  Das ist zwar nicht grundsaetzlich notwendig, aber eine zwingende Voraussetzung um das Template auch auf SuperCluster zu installieren.
    • Die Image-Namen sollten sinnvolle Namen haben, da diese Namen auch in den Meta-Daten des Templates verwendet werden.
  • Um die Testzyklen zu beschleunigen empfiehlt es sich, das Paket "pigz" zu installieren, eine parallele Implementierung von gzip.  Falls vorhanden, wird es von den Tools automatisch verwendet, um die Kompression und Dekompression der Disk Images zu beschleunigen.
  • Da man idR. ovmtprop verwenden wird, um Parameter fuer die Anwendung auszulesen, sollte man die "ovmtutilities" in der Quell-Domain installieren.
  • Die Anwendung sollte vollstaendig fertig konfiguriert sein.  Wenn das bedeutet, zusaetzliche Benutzer oder Dateisysteme hinzu zu fuegen oder die Systemkonfiguration anzupassen, dann nur zu.  Alle diese Aenderungen werden im Template erhalten bleiben.
  • System-Eigenschaften wie IP-Adressen, root Passworte oder Zeitzonen bleiben natuerlich nicht erhalten.  Diese werden aus dem Template entfernt und bei der Installation neu gesetzt.

Die Parameter Definieren

Welche Parameter man fuer das Template braucht, haengt natuerlich von der Anwendung ab.  Deswegen sollte man diese genau kennen und wissen, wie sie installiert und konfiguriert wird.  Hier ist ein Beispiel fuer eine sehr sehr einfache Anwendung:  Ein Apache Webserver der eine einfache Text-Seite zeigt, in der die drei Beispiel-Parameter mit ihren Werten angezeigt werden:  property1, property2 und property3.  Hier ist die XML-Datei, mit der diese Parameter definiert werden:

<ovf:ProductSection ovf:class="com.oracle.supercluster.client">
        <ovf:Product>Oracle SuperCluster</ovf:Product>
        <ovf:Category>OVM Templates</ovf:Category>
        <ovf:Version>1</ovf:Version>
        <ovf:Property ovf:key="property1" ovf:type="string" 
                      ovf:userConfigurable="true" ovf:value="Value1">
                <ovf:Description>Specifies property 1</ovf:Description>
        </ovf:Property>
        <ovf:Property ovf:key="property2" ovf:type="string"
                      ovf:userConfigurable="true" ovf:value="Value2">
                <ovf:Description>Specifies property 2</ovf:Description>
        </ovf:Property>
        <ovf:Property ovf:key="property3" ovf:type="string"
                      ovf:userConfigurable="true" ovf:value="Value3">
                <ovf:Description>Specifies property 3</ovf:Description>
        </ovf:Property>
</ovf:ProductSection> 

Diese Datei wird bei der Erzeugung ein Teil des Templates werden.  In dieser Definition stehen zwar Werte fuer die jeweiligen Parameter.  Diese werden jedoch bei der Installation nicht verwendet!  Eine ausfuehrliche Beschreibung aller Optionen fuer die Parameter wird es in dem bald erscheinenden "Template Authoring Guide" geben.

Installation und Konfiguration der Anwendung

Auch dieser Schritt haengt wieder stark von der jeweiligen Anwendung ab.  In unserem einfachen Beispiel ist nicht sehr viel zu tun.  Hier wird auch das einfachste aller First-Boot-Scripte gezeigt:

root@source:~# pkg install ovmtutils

root@source:~# pkg install apache22

root@source:~# svcadm enable apache22

root@source:~# more /etc/rc3.d/S99template-demo 

#!/bin/sh

# simplest of all first-boot scripts
# just for demo purposes

OUTFILE=/var/apache2/2.2/htdocs/index.html
OVMTPROP=/opt/ovmtutils/bin/ovmtprop
BASEKEY=com.oracle.supercluster.client.property

if [ ! -f $OUTFILE ]
then
   cat >>$OUTFILE << EOF
<html><body>
<h1>OVM Template Demo</h1>
EOF
   for i in 1 2 3
   do
      $OVMTPROP -q get-prop -k $BASEKEY$i >> $OUTFILE
      echo "</br>" >> $OUTFILE
   done
cat >>$OUTFILE << EOF
</body></html>
EOF
fi

Wenn alles perfekt laeuft und das First-Boot-Script zuverlaessig funktioniert muss als letzter Schritt Solaris de-konfiguriert werden.  Das macht man mit dem Kommando "sysconfig unconfigure --destructive --include-site-profile".  Damit wird die gesamte System-Identitaet, also Hostname, IP adressen, Zeitzonen und root Passwoerter entfernt.  Das ist notwendig, damit das System nach der Installation neu konfiguriert werden kann.  Auch Dateien wie bspw. SSH-Keys und temporaere Dateien in /var/tmp kann man jetzt noch loeschen.

Das Template Erzeugen

Nachdem nun endlich alle Vorbereitungen abgeschlossen sind, ist die eigentliche Erzeugung des Templates sehr einfach.  Das Kommando "ovmtcreate" sammelt all die Teile zusammen und baut daraus einen OVF Container.

root@mars:~# ovmtcreate -d source -o /templates/apache-template.ova \
             -s "OVM S11.2 SPARC Apache 2.2 Demo" \
             -P /development/apache-template.properties.xml

Dieses Kommando komprimiert alle Disk Images und fuegt sie gemeinsam mit den Parameter-Definitionen im OVF-Format zusammen.  Diese Datei kann dann verteilt und dorthin transportiert werden, wo das Template installiert werden soll.  Mit dem Parameter "-s" gibt man dem Ganzen eine sinnvolle Beschreibung, um das Template zu identifizieren.  Diese Beschreibung wird bspw. im SuperCluster verwendet, um die in der Template-Library vorhandenen Templates anzuzeigen.

Zum Schluss noch, wie man nun das Template mit passenden Werten fuer die Parameter versieht und installiert:

Installation

Die Werte fuer die Parameter des Templates werden fuer die Installation in eine kleine Text-Datei geschrieben:

root@mars:~# cat custom.values
com.oracle.supercluster.client.property1=Value1
com.oracle.supercluster.client.property2=Value2
com.oracle.supercluster.client.property3=Value3

Auch Solaris selbst muss man natuerlich mit Konfigurationsdaten versehen.  Wie das geht, habe ich bereits im ersten Teil dieser Mini-Serie gezeigt.  Diese Konfiguration verwenden wir hier einfach wieder.

Um die Ziel-Domain zu installieren und zu konfigurieren, braucht man jetzt nur zwei einfache Kommandos:

root@mars:~# ovmtdeploy -d target -o /domains \
    -s /templates/apache-template.ova
root@mars:~# ovmtconfig -d target  \
    -c /opt/ovmtutils/share/scripts/ovmt_s11_scprofile.sh \
    -P solaris_11.props.values,custom.values

Nachdem die Domain gebootet hat, sollte auf Port 80 der Apache die einfache HTML-Seite anzeigen, die durch das First-Boot-Script erzeugt wurde.

Noch einige Bemerkungen

  • Die Paramter fuer die Ziel-Domain sind in der Control Domain sichtbar.  Sie werden als normale VM Variablen an die Domain weiter gegeben.  Daher sind sie mit dem Kommando "ldm ls-variable <domain>" einzusehen.  Das bedeutet auch, dass sensitive Informationen die auf diese Weise an die Domain geleitet wird, fuer jedermann sichtbar sind, der die notwendigen Rechte fuer das Kommando "ldm ls" hat.  Die gleichen Informationen sind auch in der Zieldomain selbst jedem Benutzer ueber das Kommando ovmtprop zugaenglich.  So praktisch das fuer das Debuggen sein mag, sollte man daher keine sensitive Information wie z.B. Passworte, in solche Parameter stecken.  Besser sind verschluesselte Passwort-Strings, falls moeglich.  Falls das nicht moeglich ist, sollte man die Variablen nach erfolgreicher Installation des Templates mit dem Kommando "ldm rm-variable" loeschen.  Grundsaetzlich ist es auch eine gute Idee, den Benutzer der Anwendung (und der Domain) beim ersten einloggen zu einem Passwort-Wechsel aufzufordern.
  • Grundsaetzlich unterstuetzen OVMT Templates auch Solaris Zonenen.  Das bedeutet, man kann ein Template erzeugen, das eine oder mehrere Zonen enthaelt.  Allerdings muss man die Konfiguration dieser Zonen (IP Adressen, Hostname etc) selbst ueber das First-Boot-Script erledigen, das dies nicht Teil der normalen Solaris-Konfiguration ist.  Templates mit Zonen werden derzeit nicht auf SuperCluster unterstuetzt.

Weitere Links gab es bereits am Ende des ersten Teils dieser Mini-Serie.

Donnerstag Dez 03, 2015

OVM Templates fuer SPARC - Teil 1: Ein Template Installieren

OVM Templates gibt es schon laenger.  Dokumentation und verschiedene Templates sind auf OTN gut verfuegbar.  Allerdings dreht sich die Dokumentation meist um den OVM Manager und die Templates gibt es in der Regel fuer Linux auf x86.  Aber die Situation fuer SPARC und Solaris wird besser.  Ein Template fuer Weblogic 12.1.3 gibt es schon.

(Dieser Artikel ist die Blog-Version des ersten Teils von MOS DocID 2063739.1 die hier fuer einfachen Zugriff wiedergegeben wird.)

Die Tools zum Erzeugen, Ausrollen und Konfigurieren von Templates sind in Solaris 11.3 enthalten.  Es gibt sie jedoch auch als separaten Download in Form von Patch ID 21210110.  In dieser Mini-Serie werde ich beschreiben, wie man Templates installiert und selber baut.

Los geht's mit dem einfachsten Teil:  Die Installation eines existierenden Templates auf einem SPARC System.

Der erste Schritt ist hier natuerlich, sich ein Template zu besorgen.  Noch gibt es recht wenig Auswahl - es gibt ein Template mit Solaris 10, eines mit Solaris 11.  Aber mehr sind in Arbeit.  Verfuegbar sind sie auf Edelivery.oracle.com.  Hier ist ein kleiner Screenshot damit der Download klappt.  Meine Notizen sind in Rot...

Das Template fuer Weblogic 12.1.3 gibt es hier.

Nach erfolgreichem Download hat man eine Datei "sol-11_2-ovm-sparc.ova" oder aehnlich.  Dies ist das Template im Open Virtualization Format.   Da OVA und AVF auf tar aufbauen, kann man sich den Inhalt dieser Datei ganz einfach ansehen, falls einen die Neugier dazu draengt.

Im zweiten Schritt braucht man das OVM Template Tookit in der Control Domain des Servers.  Dazu kann man entweder auf Solaris 11.3 upgraden oder das Toolkit per Patch von MOS installieren.  Nach der Installation finden sich die Tools in /opt/ovmtutils.  Der Patch enthaelt auch README-Datien und manpages fuer die Tools.  Dort werden wissenswerte Details und Kommando-Optionen erklaert, die hier nicht behandelt werden.

root@mars:/tmp/ovmt# unzip /tmp/p21210110_11010_SOLARIS64.zip 
Archive:  /tmp/p21210110_11010_SOLARIS64.zip
  inflating: README.txt              
   creating: man1m/
  inflating: man1m/ovmtconfig.1m     
  inflating: man1m/ovmtprop.1m       
  inflating: man1m/ovmtlibrary.1m    
  inflating: man1m/ovmtcreate.1m     
  inflating: man1m/ovmtdeploy.1m     
  inflating: ovmt-utils1.1.0.1.p5p   

root@mars:/tmp/ovmt# pkg install -vg ./ovmt-utils1.1.0.1.p5p ovmtutils

[....]

root@mars:~# ls /opt/ovmtutils/bin
agent        dist         ovmtconfig   ovmtdeploy   ovmtprop
bin          lib          ovmtcreate   ovmtlibrary

Bevor wir nun das Template installieren, ein kurzer Blick auf das, was die Tools selbst ueber das Template sagen:

root@mars:~# ovmtdeploy -l ./sol-11_2-ovm-sparc.ova 
 
Oracle Virtual Machine for SPARC Deployment Utility
ovmtdeploy Version 1.1.0.1.4
Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.

STAGE 1 - EXAMINING SYSTEM AND ENVIRONMENT
------------------------------------------
Checking user privilege
Performing platform & prerequisite checks
Checking for required services
Named resourced available

STAGE 2 - ANALYZING ARCHIVE & RESOURCE REQUIREMENTS
---------------------------------------------------
Checking .ova format and contents
Validating archive configuration
Listing archive configuration

Assembly
------------------------
Assembly name: sol-11_2-ovm-sparc.ovf
Gloabl settings: 
References: zdisk-ovm-template-s11_2 -> zdisk-ovm-template-s11_2.gz
Disks: zdisk-ovm-template-s11_2 -> zdisk-ovm-template-s11_2
Networks: primary-vsw0

Virtual machine 1
------------------------
Name: sol-11_2-ovm-sparc
Description: Oracle VM for SPARC Template with 8 vCPUs, 4G memory, 1 disk image(s)
vcpu Quantity: 8
Memory Quantity: 4G
Disk image 1: ovf:/disk/zdisk-ovm-template-s11_2 -> zdisk-ovm-template-s11_2
Network adapter 1: Ethernet_adapter_0 -> primary-vsw0
Oracle VM for SPARC Template
        root-password
        network.hostname
        network.bootproto.0
        network.ipaddr.0
        network.netmask.0
        network.gateway.0
        network.dns-servers.0
        network.dns-search-domains.0

Man sieht, dass die Zieldomain

  • 8 vCPUs und 4GB RAM,
  • einen Ethernet Adapter an "primary-vsw0" und
  • ein Festplatten-Image

haben wird.

Darueber hinaus gibt es diverse Properties, die nach der Installation aber vor dem ersten Start der Domain konfiguriert werden koennen.  In diesem Fall sind das alles Solaris-Properties die man normalerweise bei der initialen Systemkonfiguration bestimmen wuerde - entweder an der Konsole oder mit einem AI Profile.  Wir werden spaeter sehen, wie man diese Properties mit den OVM Template Tools einfach setzen kann.

Vor der eigentlichen Installation sollte man kurz die Voraussetzungen pruefen:

  • Die Control Domain sollte mit Solaris 11.3 installiert sein.  Mindestens jedoch braucht man Solaris 11.2 und die OVM Template Tools.
  • Der Virtual Console Service muss konfiguriert und gestartet sein.  Wie das geht, steht hier.
  • Ein Virtual Disk Service muss ebenfalls vorhanden sein.

Nun, ohne weitere Details, eine einfache Installation:

root@mars:~# ovmtdeploy -d solarisguest -o /localstore/domains \
             /incoming/sol-11_2-ovm-sparc.ova

In diesem sehr einfachen Beispiel wird eine Domain "solarisguest" installiert.  Das Disk Image wird in /localstore/domains abgelegt und die Domain wird aus dem Template in /incoming/sol-11_2-ovm-sparc.ova installiert.

Auf einige Punkte moechte ich hier hinweisen:

  • ovmtdeploy wird die Domain mit den Resourcen erzeugen, die im Template definiert sind.
  • Es wird, falls notwendig, einen vSwitch erzeugen und mit Netzwerk-Ports verbinden.  Das sollte man ggf. nachpruefen.
  • Wenn nicht anders angegeben, wird ovmtdeploy einfache Dateien als Disk Images verwenden.
  • Alle diese Einstellungen koennen an der Kommandozeile geaendert werden.  Damit sind auch sehr fortgeschrittene Konfigurationen moeglich, die ich hier jedoch nicht weiter betrachten werde.
  • Die Domain wird sofort nach der Installation gestartet.  Da wir in diesem Beispiel die notwendigen Properties nicht mit Werten versehen haben, wird Solaris unkonfiguriert booten und an der Console die entsprechenden Werte abfragen.

Damit das einfacher wird, hier eine zweite Installation, diesmal mit Werten fuer diese Properties.  Damit ist es moeglich, die Domain ohne manuelle Intervention in konfiguriertem Zustand zu booten. Dafuer braucht man lediglich eine kleine Textdatei die die entsprechenden Werte enthaelt:

root@mars:~# more solaris_11.props.values 

# Default hostname
com.oracle.solaris.system.computer-name=solarisguest

# Root user account settings
com.oracle.solaris.root-password='password hash goes here'

# Administrator account settings 
com.oracle.solaris.user.name.0=admin
com.oracle.solaris.user.real-name.0="Administrator"
com.oracle.solaris.user.password.0='password hash goes here'

# Network settings for first network instance
# Domain network interface
com.oracle.solaris.system.ifname=net0

# IP Address
# if not set, use DHCP
com.oracle.solaris.network.ipaddr.0=192.168.1.2
com.oracle.solaris.network.netmask.0=24
com.oracle.solaris.network.gateway.0=192.168.1.1

# DNS settings
# (comma separated list of DNS servers)
com.oracle.solaris.network.dns-servers.0=192.168.1.1
# (comma separated list of domains)
com.oracle.solaris.network.dns-search-domains.0=example.com

# System default locale settings
com.oracle.solaris.system.time-zone=US/Pacific
Es sollte klar sein, wie man diese Datei an eigene Gegebenheiten anpasst.  Mit dieser Datei ist die Installation und Konfiguration eine Sache von zwei einfachen Schritten:

root@mars:~# ovmtdeploy -d solarisguest -o /localstore/domains \
             -s /incoming/sol-11_2-ovm-sparc.ova 

Dieses erste Kommando installiert die Domain, startet sie aber nicht.  Dafuer gibt es die Option "-s".

root@mars:~# ovmtconfig -d solarisguest \
    -c /opt/ovmtutils/share/scripts/ovmt_s11_scprofile.sh \
    -P solaris_11.props.values

Das Script "ovmt_s11_scprofile.sh" ist Teil der OVM Template Tools.  ovmtconfig wird das installierte Disk Image mounten und dann dieses Script aufrufen.  Dieses wird anhand der Property-Werte aus "solaris_1.props.values" ein Konfigurations-Profil erzeugen.  Diese Profil wird von Solaris beim ersten Booten verwendet, um die Domain zu konfigurieren.

Damit haben wir eine laufende Solaris Gast Domain.  Wenn sie nicht gefallen sollte, ist sie mit "ovmtdeploy -U solarisguest" ganz schnell und sauber wieder de-installiert.  Eine solche Domain ist ein idealer Startpunkt, um damit eigene, komplexere Templates zu entwickeln.  Das werde ich im zweiten Teil der Serie behandeln.

Fuer Wissbegierige hier noch einige Links zum Thema:

Freitag Aug 28, 2015

MOS Dokumente mit DocID aufrufen

Ich habe mich immer wieder gefragt, ob es nicht eine einfachere Methode gibt, ein MOS Dokument zu oeffnen, als sich im Portal zur Suchmaske durch zu klicken um die DocID, die ich ja schon kenne, einzugeben.  Die Idee, das mit einem Search Plugin fuer Firefox zu machen, hatte ich schon lange.  Jetzt hatte ich auch ein wenig Zeit, und hier ist das Plugin.  Einfach als "DocID.xml" in "searchplugins" des Firefox-Profils ablegen, Firefox neu starten und schon kann man im Suchfenster eine DocID eingeben und das Dokument so direkt aufrufen.

<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/" xmlns:os="http://a9.com/-/spec/opensearch/1.1/">
<os:ShortName>MOS DocID</os:ShortName>
<os:Description>MOS DocID Search</os:Description>
<os:InputEncoding>UTF-8</os:InputEncoding>
<os:Image width="16" height="16">data:image/x-icon;base64,
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAA3NCSVQICAjb4U/gAAAAU0lEQVQokWP8z0AaYCJRPekaWFB4/3E4kJERwfyPXymGNsb
/yKqRTMJuMyMjkh9wqUaVYsIUwq+H7GAl6GmYAiZMITyqGcgNVoKWYIk4ogHtEx8A02caF75DNeYAAAAASUVORK5CYII=</os:Image>
<SearchForm>http://support.oracle.com/epmos/faces/</SearchForm>
<os:Url type="text/html" method="GET" template="http://support.oracle.com/epmos/faces/DocumentDisplay?id={searchTer
ms}">
</os:Url>
</SearchPlugin>

(Der Text wird evtl. nicht vollstaendig angezeigt, mit Copy & Paste kann man ihn aber leicht vollstaendig in eine Datei bringen.)

Dienstag Jan 06, 2015

What's up with LDoms - Verzeichnis der Artikel

In den letzten Jahren - ja, es sind schon Jahre - habe ich eine kleine Artikel-Reihe ueber LDoms und ihre verschiedenen Features geschrieben.  Es ist hoechste Zeit, auch ein kleines Inhaltsverzeichnis dafuer zu veroeffentlichen:

Ich werde dieses Verzeichnis aktuell halten, falls es neue Artikel in dieser Reihe geben sollte.

Dienstag Mai 20, 2014

LDoms: Verbesserte vDisk Performance

Bei der Leistung von virtuellem IO sollte man seine Erwartungen in realistischen Grenzen halten.  Darauf habe ich in all den Jahren in allen LDom Workshops hingewiesen.  Und ich werde jetzt nicht damit aufhoeren.  Virtuelles IO ist immer mit gewissen Kosten verbunden, einfach deswegen, weil es einen gewissen Aufwand bedeutet, die physischen IOs in virtuelle IOs zu uebersetzen.  Und bis zur Entdeckung der Zeitreise wird dafuer immer auch ein wenig Zeit gebraucht werden.  Soweit, so schlecht.  Es gibt aber auch gute Nachrichten:

Erstens ist der Overhead virtuellen IOs in vielen Faellen tatsaechlich kleiner als befuerchtet - die LDom Implementierung ist sehr effizient.  Und in vielen dieser vielen Faellen schaded dieser Overhead nicht.  Meist, weil es der Anwendung egal ist, bzw. das virtuelle IO schnell genug.

Zweitens gibt es natuerlich gute und weniger gute Arten, virtuelles IO zu konfigurieren.  Wenn man sich an die guten haelt (wie ich sie bspw. hier besprochen habe), kann man die Anzahl der Faelle, in denen virtuelles IO einfach gut genug ist, noch ein gutes Stueck erhoehen.

Aber es gibt natuerlich auch die Faelle, in denen es einfach nicht reicht.  Gluecklicherweise gibt es noch weitere gute Nachrichten:

Die Leistung des virtuellen Netzwerks wurde mit einer neuen Implementierung erheblich verbessert.  Durch den Einsatz von Large Segment Offload (LSO) und einiger anderer Techniken wurde der Durchsatz gesteigert und die Latenz reduziert - bis an einen Punkt, an dem die Leistung des virtuellen Netzwerks als Grund fuer Performanceprobleme weitgehend entfallen ist.  Das war in LDoms 3.1.  Jetzt ist virtuelles Disk-IO an der Reihe, mit ganz aehnlichen Verbesserungen.

Beim Thema Disk IO und Performance gibt es eine grundlegende Empfehlung:  Die IO-Last auf moeglichst viele LUNs verteilen.  Das war bereits so, lange bevor man auch nur an Virtualisierung gedacht hat.  Der Grund dafuer ist einfach die begrenzte Anzahl an IOPS, die eine einzelne LUN liefern kann.  Dabei ist es egal, ob es sich bei dieser LUN um eine einzelne physische Platte oder ein Volume eines groesseren Disk Arrays handelt.  IOPS einer einzelnen LUN sind begrenzt und IOs fuer diese LUN werden in einer sehr sequentiellen Warteschlange auf diese LUN warten.  Eine einzelne Platte liefert seit Jahren ca. 150 IOPS.  Oder auch 300.  Eine SAN LUN mit einem starken Array im Hintergrund liefert vielleicht 5000 IOPS oder ein paar mehr.  Aber das reicht nicht, heute so wenig wie gestern.  Deswegen hat man RAID 1 erfunden.  Und die Virtualisierung von Servern und Storage aendern nichts an dieser Situation.  Fuer LDoms bedeutet das nun einfach, mehrere LUNs, also mehrere vDisks pro Gast zu konfigurieren. In vielen Faellen ist das ausreichend, um gute IO Performance zu bekommen.  Leider gab es jedoch zu viele Faelle in denen das eben nicht gut genug war und man letzten Endes zurueck zu physischem IO musste.  Nun gibt es natuerlich diverse Moeglichkeiten, physisches IO und Server-Virtualisierung mit LDoms zu verbinden.  Aber befriedigend war die Situation nicht.

Mit der Freigabe von Solaris 11.1 SRU 19 (und einem entsprechenden Patch fuer Solaris 10 wenig spaeter) wird nun auch fuer den vds/vdisk Software Stack eine neue Implementierung eingefuehrt, die diese Situation grundlegend aendert.  Durchsatz und Latenz von virtuellem Disk-IO werden wesentlich verbessert, wie man an den folgenden Diagrammen ablesen kann.

Dieses erste Diagramm zeigt IOPS im Vergleich von Bare Metal mit virtuellem Disk-IO, sowohl mit der alten als auch mit der neuen Implementierung.  Wie man leicht erkennen kann gibt es erhebliche Verbesserungen, die neue Implementierung unterscheidet sich nur marginal von Bare Metal.  Die Unterschiede sind so gering, dass es sich auch um statistische Ungenauigkeiten bzw. normale Schwankungen zwischen zwei Messungen handeln koennte.  Zu beachten ist, dass die hier gezeigten Messwerte mit 28 SAN LUNs erzielt wurden.  Erwartungen, eine einzelne LUN wuerde nun ploetzlich 150k IOPS liefern, muss ich leider enttaeuschen.  Die Verbesserung gegenueber der alten Implementierung sind mit bis zu 55% erheblich.  Wichtig zu beachten ist allerdings, dass man mit nur einem IO Strom (den "Threads" im Diagram) und einer einzelnen LUN weniger offensichtliche Verbesserungen beobachten wird.  Das liegt daran, dass wesentliche Teile der neuen Implementierung sich auf die De-Serialisierung der IO-Infrastruktur konzentrieren, was man natuerlich nicht bemerken wird, wenn man nur einen einzelnen, seriellen IO-Strom misst.  Im wirklichen Leben sind die grossen, IO-hungrigen Anwendungen jedoch meist parallel unterwegs.  Auch wenn das eigene Storage-Backend mit den parallelen Anfragen ueberfordert ist (z.B. weil man aus Versehen auf der einen, internen Platte testet) wird man wenig Veraenderung feststellen.

Durchsatz ist somit kein Problem mehr (mit 150k IOPS und 1.1 GB/sec virtuellem IO in diesem Test meine ich das behaupten zu duerfen).  Aber wie sieht es mit der Latenz aus?  Dazu das naechste Diagramm:

Auch hier sieht man wieder, dass sich die Latenz der neuen Implementierung kaum von Bare Metal unterscheidet.  Der groesste Unterschied sind 4% im Fall von 2 parallelen Threads.   Das ist wenig genug um ueber den Begriff "Zero Overhead" nachzudenken, zumindest in Bezug auf IO Leistung.  Wo wir gerade von Overhead reden:  Ich nennen den Overhead, der durch Virtualisierung entsteht gerne auch "Virtualisierungssteuer" - die Ressourcen die man in die Virtualisierung selbst investiert, oder aber die Performance die durch oder wegen der Virtualisierung verloren geht.  Im Falle von LDoms Disk IO haben wir damit soeben eine erhebliche Steuersenkung erfahren:

Dieses letzte Diagramm zeigt um wie viel hoeher die Antwortzeit mit der alten Implementierung war und wie viel davon wir mit dieser beeindruckenden Programmierleistung  der neuen Implementierung zurueck bekommen.  Vorher musste man bis zu 55% Virtualisierungssteuer fuer virtuelles Disk-IO bezahlen, jetzt sind es 4% oder weniger.  Ein grosses "Danke Schoen!" an Engineering!

Natuerlich darf an dieser Stelle ein Haftungsausschluss nicht fehlen:  Ihre eigenen Ergebnisse werden sich von diesen Testergebnissen unterscheiden.  Die hier gezeigten Resultate wurden mit 28 LUNs aus einer irgendwie gearteten FC Infrastruktur gemessen.  Die Tests wurden mit vdbench in einer Mischung aus 60% lesendem und 40% schreibendem Random-IO gemacht, mit zwischen 2 und 20 parallelen Threads.  Das ist eine IO-Last, die jedes IO-System stark beansprucht und gleichzeitig das IO-Muster, bei dem die hoechste Virtualisierungssteuer beobachtet wurde.  Dennoch muss klar sein, dass sich die Ergebnisse von denen in anderen Tests oder tatsaechlichen Produktionsumgebungen unterscheiden werden und evtl. nicht die gleichen Verbesserungen erreicht werden koennen.  Auch wenn ich sehr optimistisch bin, dass sie sehr aehnlich sein werden.

Abschliessend kann man sagen, dass mit den neuen, wesentlich verbesserten Implementierungen fuer virtuelle Netzwerke und jetzt auch virtuelle Platten die Bandbreite der Anwendungen, die sich problemlos auf virtuellem IO betreiben lassen erheblich vergroessert hat.  Was den Erwartungen der Kunden entspricht, die ich in meinen Workshops treffe:  High End Performance ist eine Selbstverstaendlichkeit fuer SPARC Systeme, virtualisiert oder nicht.

Kurz vor Schluss: Was muss man eigentlich tun um in den Genuss dieser Verbesserung zu kommen?
  • Bei Solaris 11 muss der Update auf Solaris 11.1 SRU 19 in
    • Allen Gast Domains die die neue Implementierung nutzen wollen, und
    • Allen IO Domains die die Infrastruktur hierfuer bereit stellen, eingespielt werden.
    • Darin enthalten ist natuerlich auch der Update auf LDoms Manager 3.1.1
    • Es muessen beide Partner, Gast und IO-Domain aktualisiert werden, ansonsten wird die alte Implementierung weiter verwendet.
  • Einen Patch fuer Solaris 10 wird es in Kuerze natuerlich auch geben.

Update 2014-06-16: Patch 150400-13 fuer Solaris 10 ist nun verfuegbar.  Im Readme stehen die Details.

Donnerstag Mrz 27, 2014

Ein paar Gedanken zu Single Thread Performance

Eines werde ich immer wieder gefragt: Wie misst man Single Thread Performance ?

So gerne ich auch wollte, die Antwort ist leider nicht so einfach wie die Frage.  Und leider auch ein wenig laenger.

Selbst die Definition von Single Thread Performance ist nicht immer die gleiche, weswegen ich damit anfangen moechte.  In diesem Blog ist Single Thread Performance die Menge an Arbeit die eine Software, die als einzelner Instruktions-Strom ablaeuft, in einer gewissen Zeit erledigt.

Das alles dient natuerlich dazu, die Leistung (schon wieder ein schwammiger Begriff..) eines Computersystems, oder manchmal einer Komponente davon, in Bezug auf die zu erwartende Single Thread Performance zu bewerten.

Genug der Vorrede, was uns jetzt interessiert sind die Moeglichkeiten, Single Thread Performance zu messen und natuerlich zu vergleichen.

Das erste, was einem hierzu einfaellt ist ein kleines Testprogramm.  Irgend etwas, von dem wir wissen dass es single threaded  ist und eine Weile dauert.  Je nachdem, was man im taeglichen Leben so macht, koennte das ein kleines Shell-Skript sein, das von 1 bis 1 Million zaehlt, ein SQL-Loop der Fibonacci-Zahlen berechnet oder ein kleines Programm zur Erzeugung kryptographischer Hashes.  Aber bekommen wir damit, was wir wirklich wollen - ein zuverlaessiges Mass der allgemeinen Single Thread Performance eines Systems?  Immerhin sind die Anforderungen all dieser Micro-Benchmarks sehr unterschiedlich.  Manche bevorzugen grosse Caches um die Memory-Latenz zu verstecken.  Andere brauchen hohen Memory-Durchsatz, wieder andere skalieren einfach mit der CPU-Taktrate.  Wie wuerden wir daher die allgemeine Single Thread Leistung eines Systems fuer diese sehr unterschiedlichen Anforderungen bewerten?  Hier ein Beispiel.  Das Diagram zeigt die Leistung verschiedener Tests einer kleinen Testsuite, die ich auf jedem SPARC-System laufen lasse, das ich in die Finger bekomme.  Was die Tests machen, ist nicht interessant.  Wichtig ist, dass sie alle single threaded laufen und nur CPU-gebunden sind

Folgendes ist dabei wichtig:

  1. Test 1 scheint sehr cache-freundlich zu sein - die 3 CPUs mit Caches groesser als 8MB liegen deutlich vorn.  Auch scheint dieser Test von Cache mehr zu profitieren als von Taktrate, da die 1.8 GHz CPU knapp vor der 2.66 GHz CPU liegt. 
  2. All die anderen Tests skalieren ungefaehr mit der Taktrate, das 3.6 GHz System liegt daher vorn.
  3. Es gibt kein festes Verhaeltnis von Leistung und Taktrate.  In Test 1 liegen alle Ergebnisse sehr nahe beinander, waehrend die Unterschiede in Tests 3 und 4 stark schwanken.

Das alles fuehrt letzten Endes zu der Erkenntnis: Single Thread Performance haengt in erster Linie von der Anwendung und den Daten ab - es gibt keine allein selig machende Antwort.  Das sollte natuerlich keine Ueberraschung sein, letztlich ist das bei jedem Benchmark so.  Bei der Bewertung von Single Thread Performance ist es jedoch besonders wichtig, da hier die Unterschiede besonders stark zu Tage treten.  Ein letzter Blick auf das obige Diagramm:  In Test 1 ist das 2.66 GHz System ca. 1/3 schneller als das 2.85 GHz System, und ungefaehr gleich schnell wie das mit 1.8 GHz.  Gemaess Tests 2 und 3 jedoch ist das 1.8 GHz System deutlich schneller als das 2.66 GHz System, aber alle anderen sind schneller als diese beiden.  Das Problem bei der ganzen Sache ist: Man weiss nie, welchen Fall man mit dem jeweils bevorzugten Testprogramm gerade erwischt.  Egal was man testet, egal wie die Resultate ausfallen, es ist zumindest sehr schwierig, damit Performancevorhersagen zu treffen.

Aber vielleicht helfen ja die "offiziellen" Benchmarks weiter.  Der einzige einigermassen relevante, der sich (noch) mit Single Thread Performance beschaeftigt ist SPECcpu2006.  Der Einfachheit halber beschraenke ich mich in dieser Betrachtung auf CINT2006.  Es gibt zwei Varianten davon, den single threaded SPECint_2006 und die Durchsatzvariante SPECint_rate2006.  Da uns Single Thread Performance interessiert, ist SPECint_2006 die natuerliche Wahl.  Leider gibt es auch hier zwei Probleme:
  1. SPECint_2006 ist nicht wirklich single threaded.  Einige der Teilbenchmarks koennen von modernen Compilern sehr gut parallelisiert werden.  Das wird von den Benchmark-Regeln erlaubt und natuerlich oft benutzt.
  2. Nicht alle Hersteller veroeffentlichen SPECint_2006.  Es gibt sehr viele Veroeffentlichungen von SPECint_rate2006 aber sehr viel weniger Veroeffentlichungen der entsprechenden single thread Variante des gleichen Systems.

Wegen dieser Probleme scheint auch SPEC CPU2006 nicht die Antwort auf unsere Frage zu liefern.  Es gibt jedoch viele die meinen, dieses Problem umgehen zu koennen.  Sie argumentieren ungefaehr so:

"SPECint_rate2006 ist nichts anderes als ein paralleler Lauf vieler Kopien von SPECint_2006 auf einem groesseren System.  Wenn ich also die Single Thread Performance dieses Systems wissen moechte, muss ich einfach nur das SPECint_rate2006 Ergebnis durch die Anzahl der CPU Threads oder evtl. durch die Anzahl der verwendeten Kopien, die in der Veroeffentlichung dokumentiert sind teilen, um das Single Thread Ergebnis zu bekommen."

Das klingt eigentlich ganz einfach.  Aber funktioniert es?  Das laesst sich anhand einiger Beispiele ueberpruefen, bei denen es gluecklicher Weise Ergebnisse fuer SPECint_2006 und SPECint_rate2006 gibt.  Um die Betrachtung einfach zu halten, werde ich hier nur den Sub-Benchmark perlbench betrachten, nicht das Gesamtergebnis.  Wer moechte, kann das gerne mit anderen Sub-Benchmarks ueberpruefen.

System SPECint_2006 perlbench SPECint_rate2006 perlbench Number of copies SPECint_rate2006 perlbench / Anzahl der Kopien
Genauigkeit der Single Thread Schaetzung
M3000 16.4 83.5 8 10.4 64%
Power780 4.14 GHz 28.1 1120 128 8.75 31%
Sun Fire X4-2
(Intel Xeon E5-2697 v2 2.7GHz)
41
894
96 9.3
23%

Alle diese Werte sind von spec.org vom 17. Maerz 2014.  Die jeweiligen Werte sind mit ihren Gesamt-Veroeffentlichungen auf spec.org verlinkt.

Es wird sehr deutlich, dass eine Abschaetzung der Single Thread Performance mit diesem einfachen Vorgehen nicht funktioniert.  Warum nicht?  Weil die heutigen CPUs alle multi-threading CPUs sind.  Sie haben nicht nur alle mehrere Kerne, die sich L2 oder L3 Caches und die Memory-Bandbreite teilen.  Sie haben darueber hinaus mehrere Threads, die sich einen Kern teilen.  Der Sinn dieser Threads liegt in einer hoeheren Kernauslastung:  Ein einzelner Thread ist nicht in der Lage, die modernen, schnell laufenden Kerne auch nur annaehernd auszulasten, hauptsaechlich weil die Memory-Latenz mit der Entwicklung der CPU-Taktraten nicht schrittgehalten hat.  Das bedeutet, dass ein zweiter, dritter oder vierter Thread in der Lage ist, zusaetzliche Arbeit zu verrichten ohne die anderen auf diesem Kern laufenden Threads wesentlich zu beeinflussen.  Natuerlich gibt es den Punkt, ab dem der Kern im Wesentlichen ausgelastet ist und daher die zusaetzliche Arbeit, die durch weitere Threads ausgefuehrt wird, mit zunehmender Threadanzahl abnehmen wird.  Das Diagram rechts stellt diesen Zusammenhang idealisiert dar.  Je nach Charakteristik der Rechenlast variiert die optimale Anzahl von Threads zwischen 1 und 8.  Das ist normal und im taeglichen Betrieb eines Rechenzentrums liefern diese CPUs daher hervorragenden Durchsatz.  Allerdings ist es fuer die Kapazitaetsplanung manchmal eine Herausforderung.  Im Falle einer Benchmark-Konfiguration fuer einen Durchsatz-Benchmark wie SPECint_rate2006 jedoch ist maximaler Durchsatz das einzige Ziel.  Daher sind auch die bspw. 2%, die ein weiterer Thread zum Gesamtergebnis noch beitraegt willkommen.  Durchsatz-Benchmarks wie SPECint_rate2006 oder SAP SD 2 Tier werden fuer maximalen Durchsatz optimiert. 

Das bedeutet jedoch zwingend, dass die durchschnittliche Leistung pro Thread deutlich unter der potentiellen Maximalleistung eines Threads liegt.  Und deswegen kann dieser Durchschnitt nicht zur Bewertung der Single Thread Performance herangezogen werden.

Aber welchen anderen Ausweg gibt es?  Hier hilft eine Rueckbesinnung auf das, was wir wirklich wissen wollen.  Single Thread Performance ist ja kein Wert an sich.  Sie hat einen Zweck.  In den meisten Faellen geht es um die Antwortzeit einer Anwendung - Antwortzeit, die unsere Erwartungen erfuellt oder unterschreitet.  Gluecklicher Weise gibt es einen Benchmark, der genau diese Anforderungen stellt:  SPECjbb2013.  Nun weiss ich natuerlich, dass dieser Benchmark sich speziell mit den Anforderungen an einen Application Server befasst.  Was sich stark von denen an bspw. ein Datawarehouse unterscheidet.  Nichts desto Trotz liefert er uns zuverlaessige Hinweise ueber die Single Thread Performance und, noch wichtiger, liefert er uns Hilfen zum Verstaendnis von Single Thread Performance im Vergleich verschiedener Systeme (wenn denn Ergebnisse vorhanden sind...)

Daher also nun ein kurzer Blick auf SPECjbb2013 und wie dieser Benchmark uns vielleicht helfen kann, unsere Frage zu beantworten:

Die Ergebnisse von SPECjbb2013 werden in zwei Werten gemessen:  max-jOPS und critical-jOPS.  max-jOPS ist dabei ein reiner Durchsatz-Wert, der diese Diskussion nicht weiter bringt.  critical-jOPS hingegen ist "a metric that measures critical throughput under service level agreements (SLAs) specifying response times ranging from 10ms to 500ms." (Zitat aus der Benchmark Beschreibung von SPEC.)  Es wird also Durchsatz unter einer Antwortzeiten-Bedingung gemessen.  Damit entsteht ein hoher Druck sowohl auf das System als auch auf die Benchmark-Teams.  Sie muessen das System fuer die sehr realistische Anforderung optimieren, niedrig-latente Antworten bei gleichzeitig hohem Durchsatz zu liefern.  Wie hilft uns das nun auf unserer Suche nach einem Vergleich der Single Thread Performance weiter?  Nun, angenommen wir haben zwei Systeme mit vergleichbarer Konfiguration und Preis.  System A liefert 10000 max-jOPS und 5000 critical-jOPS.  System B liefert 7500 max-jOPS und 6000 critical-jOPS.  System A schafft also einen hoeheren Durchsatz, allerdings nur, solange wir die Antwortzeiten ignorieren.  Der Durchsatz mit System B ist dagegen nicht so hoch, das System schafft jedoch mehr critical-jOPS als System A.  Das ist fuer uns ein Hinweis, dass die Single Thread Performance von System B besser ist als die von System A - es schafft einen hoeheren Durchsatz unter Antwortzeit-Bedingungen.  Zugegeben, auch das ist nicht die "allein selig machende" Antwort auf die Frage nach der absoluten Single Thread Performance, die wir evtl. gesucht haben.  Eine Aussage der Art "System A hat eine 3x hoehere Single Thread Performance als System B" wird es nicht geben.  Das liegt u.A. daran, dass Durchsatz und die Art und Weise wie ein System skaliert und mit einer hoch skalierenden Last umgeht eine grosse Rolle in diesem Benchmark spielt.  Es ist jedoch ein sehr realistisches Szenario das uns einige belastbare Hinweise gibt, was wir bzgl. der Single Thread Performance von verschiedenen Maschinen erwarten koennen.  Wie mit jedem anderen Benchmark auch, muessen diese Schlussfolgerungen natuerlich spezifisch fuer die jeweilige Anwendung, die verwendeten Daten, die Test-Umstaende und aehnliches sein.  Aber SPECjbb2013 ist ein gutest Beispiel dafuer, wie man Hinweise auf Single Thread Performance bekommen kann.

Eine letzte Bemerkung zu SPECjbb2013:  Die Benchmark Teams der verschiedenen Hersteller fangen gerade erst an, diesen neuen Benchmark zu verstehen.  So gibt es bspw. 3 Resultate fuer die Oracle SPARC T5-2, mit critical-jOPS Werte von 23334 bis 43963.  Das macht deutlich, dass man hier vorsichtig vorgehen sollte, moechte man nicht Aepfel mit Birnen vergleichen.  Der Loewenanteil an diesen Unterschieden ist auf die verwendete Java-Version zurueck zu fuehren.  Das erste Ergebnis wurde mit JDK 7u17 erzielt, das zweite, 1.89x bessere mit dem kuerzlich angekuendigten Java 8 JDK.  Das zeigt nicht nur, dass man bei Vergleichen die Software Version beruecksichtigen muss sondern auch, wie Vorteilhaft es sein kann, eine neue Version einzusetzen.  Gluecklicher Weise gibt es zunehmend mehr Einreichungen fuer diesen Benchmark, so dass es in Zukunft hoffentlich einfacher wird, Vergleiche anzustellen.

Geschafft - das war eine etwas lange Antwort auf eine kurze Frage...  Fuer all diejenigen, die noch mehr wissen moechte, hier noch ein paar Vorschlaege:

Vielen Dank an Ruud van der Pas und Patrick McGehearty fuer Ihre Beitraege zu diesem Eintrag!

Benchmark Disclosures:
SPEC and the benchmark names SPECjbb2013 and SPECint are registered trademarks of the Standard Performance Evaluation Corporation. Results as of March 17, 2014 from www.spec.org

Dienstag Okt 01, 2013

CPU-DR fuer Zonen

In meinem letzten Beitrag habe ich beschrieben, wie man die Memory-Konfiguration einer Zone im laufenden Betrieb veraendert.  Die naheliegende Frage ist natuerlich, ob das auch mit einer eventuellen CPU-Begrenzung funktioniert.  Die Antwort lautet natuerlich "Ja".

Manch einer wird sich fragen, warum das ueberhaupt notwendig ist, kann man Zonen doch bspw. mit dem Fair-Share Scheduler ganz hervoragend mit CPU versorgen und gleichzeitig unter Kontrolle halten.  Es gibt jedoch auch Gruende, Zonen mit exklusiven CPUs auszustatten - Lizenzierung oder  SLAs, die eine eher physische Partitionierung der Resourcen vorschreiben.  In solchen Faellen werden Zonen mit einer festen Anzahl von CPUs (oder vielmehr Strands) konfiguiert.  Und dann kann es natuerlich auch wuenschenswert sein, diese Konfiguration zu aendern, ohne die Zone dabei zu booten.  Wie das geht, soll hier beschrieben werden.

Grundsaetzlich gibt es zwei Moeglichkeiten, eine Zone mit einer festen Anzahl von CPUs zu betreiben.  Die klassische ist ein Resource Pool mit einem dazu gehoerenden Prozessorset, an den die Zone gebunden wird.  Eleganter geht das mit der Einstellung "dedicated-cpu" direkt in der Zonenkonfiguration.  In diesem zweiten Fall wird beim Start der Zone ein temporaerer Pool angelegt.  D.h. in beiden Faellen ist die Umsetzung die gleiche.  Und damit ist auch klar, wie die Loesung in beiden Faellen aussieht:  Die Konfiguration des Pools wird geaendert.  In der klassischen Variante ist diese Aenderung persistent.  In der zweiten Variante muss zusaetzlich die Konfiguration der Zone angepasst werden, damit die neue Anzahl von CPUs auch nach einem Zonen-Neustart erhalten bleibt.

Wird eine Zone mit "dedicated-cpu" konfiguriert, wird beim Start der Zone ein temporaerer Pool angelegt.  Dieser, und auch das dazu gehoerende Prozessorset, heisst idR. SUNWtmp_<zonenname>.  Das weitere Vorgehen ist damit fuer beide Faelle gleich:

Nehmen wir an, unsere Zone heisst orazone und hat derzeit 1 CPU.  Sie soll auf 2 CPUs erweitert werden.  Die aktuelle Pool-Konfiguration sieht wie folgt aus:

root@benjaminchen:~# pooladm                

system default
	string	system.comment 
	int	system.version 1
	boolean	system.bind-default true
	string	system.poold.objectives wt-load

	pool pool_default
		int	pool.sys_id 0
		boolean	pool.active true
		boolean	pool.default true
		int	pool.importance 1
		string	pool.comment 
		pset	pset_default

	pool SUNWtmp_orazone
		int	pool.sys_id 5
		boolean	pool.active true
		boolean	pool.default false
		int	pool.importance 1
		string	pool.comment 
		boolean	pool.temporary true
		pset	SUNWtmp_orazone

	pset pset_default
		int	pset.sys_id -1
		boolean	pset.default true
		uint	pset.min 1
		uint	pset.max 65536
		string	pset.units population
		uint	pset.load 687
		uint	pset.size 3
		string	pset.comment 

		cpu
			int	cpu.sys_id 1
			string	cpu.comment 
			string	cpu.status on-line

		cpu
			int	cpu.sys_id 3
			string	cpu.comment 
			string	cpu.status on-line

		cpu
			int	cpu.sys_id 2
			string	cpu.comment 
			string	cpu.status on-line

	pset SUNWtmp_orazone
		int	pset.sys_id 2
		boolean	pset.default false
		uint	pset.min 1
		uint	pset.max 1
		string	pset.units population
		uint	pset.load 478
		uint	pset.size 1
		string	pset.comment 
		boolean	pset.temporary true

		cpu
			int	cpu.sys_id 0
			string	cpu.comment 
			string	cpu.status on-line
Wir sehen in der Definition von pset SUNWtmp_orazone, dass CPU #0 diesem zugeordnet ist. Um den Pool um CPU #1 zu erweitern, sind folgende Kommandos notwendig:
root@benjaminchen:~# poolcfg -dc 'modify pset SUNWtmp_orapset \
                     (uint pset.max=2)' 
root@benjaminchen:~# poolcfg -dc 'transfer to pset \
                     orapset (cpu 1)'

Um umgekehrt diese CPU wieder aus dem Pool zu entfernen, diese Kommandos:

root@benjaminchen:~# poolcfg -dc 'transfer to pset pset_default \
                     (cpu 1)'
root@benjaminchen:~# poolcfg -dc 'modify pset SUNWtmp_orapset \
                     (uint pset.max=1)' 

Nun bleibt nur noch, die korrekte Anzahl von CPUs fuer den naechsten Zonen-Neustart in die Zonenkonfiguration einzutragen.

Fuer den Fall eines eigenen Pools fuer die Zone (klassische Variante) ist in diesem Verfahren lediglich der entsprechende Poolname zu verwenden.

Literatur:

Montag Aug 19, 2013

Memory-DR fuer Zonen

Zonen bieten unter Anderem die Moeglichkeit, den Hauptspeicher zu begrenzen.  Das geht idR. mit dem Zonen-Parameter "capped-memory", bei dem man die drei Werte "physical", "swap" und "locked" jeweils einzeln setzen kann.  "Physical" entspricht dabei der Resource-Control "zone.max-rss", also dem tatsaechlich belegten Hauptspeicher.  "Swap" entspricht "zone.max-swap" - dem belegten Swapspace und "locked" entspricht "zone.max-locked-memory", dem nicht pagebaren Speicher, typischerweise sind das shared memory Segmente.  Swap und Locked Memory sind dabei recht harte Grenzen, beim physischen Speicher ist es etwas "weicher".   Der physische Speicher wird durch rcapd ueberwacht, der ggf. versucht, Speicherseiten jenseits der erlaubten Menge auf das Swapdevice auszulagern.  Je nach Aktivitaet der Prozesse, die diesen Speicher verwenden, ist das mehr oder weniger erfolgreich, hat aber in jedem Fall zur Folge, dass diese Prozesse durch Paging stark beeintraechtigt werden.

Aendert man diese Werte mittels zonecfg, werden die neuen Werte erst nach einem Neustart der Zone wirksam.  Wirklich dynamisch, wie man das z.B. bei LDoms gewohnt ist, ist das nicht.  Es geht aber auch anders, wie ich an einem kleinen Beispiel zeigen moechte:

Gegeben sei eine kleine Zone, deren Speicherkonfiguration wie folgt aussieht:

root@benjaminchen:~# zonecfg -z orazone info capped-memory
capped-memory:
    physical: 512M
    [swap: 256M]
    [locked: 512M]

Um diese Werte im Betrieb zu aendern, muss an zwei verschiedenen Stellen eingegriffen werden.  Fuer den physischen Speicher beim rcapd, der diesen verwaltet.  Fuer swap und locked memory mit dem normalen Resource Control Kommando prctl.  Um also bspw. alle drei Grenzen zu verdoppeln, brauche ich folgende Kommandos:

root@benjaminchen:~# prctl -n zone.max-swap -v 512m -r -i zone orazone
root@benjaminchen:~# prctl -n zone.max-locked-memory -v 1g -r -i zone orazone
root@benjaminchen:~# rcapadm -z orazone -m 1g

Diese neuen Werte werden sofort, bzw. nach dem naechsten Rekonfigurations-Intervall des rcapd wirksam. Dieses kann man ebenfalls mit rcapadm veraendern. Wichtig ist dabei, dass diese Aenderungen nicht persistent sind. D.h. fuer den naechsten Zonen-Neustart gelten die Werte, die mittels zonecfg gesetzt wurden. Will man beides - persistente Aenderung und sofortige Wirkung, muss man an beiden Stellen eingreifen.

Literatur:

  • Solaris Admin Guide:
    http://docs.oracle.com/cd/E19683-01/817-1592/rm.rcapd-1/index.html

Donnerstag Jul 04, 2013

What's up with LDoms: Eine Artikel-Reihe zum Thema Oracle VM Server for SPARC

Unter dem Titel "What's up with LDoms" habe ich soeben den ersten Artikel einer ganzen Reihe veroeffentlicht.  Ziel der Artikelreihe ist es, das vollstaendige Feature-Set der LDoms zu betrachten.  Da das ganze recht umfangreich ist, werde ich hier von der Zweisprachigkeit abweichen und die Artikel ausschliesslich auf Englisch verfassen.  Ich bitte hierfuer um Verstaendnis.

Den ersten Artikel gibt es hier: What's up with LDoms: Part 1 - Introduction & Basic Concepts

Viel Spass beim Lesen!

2012-07-13 Update:

2012-11-06 Update:

2013-07-04 Update:

2015-01-06 Update:

Montag Jun 24, 2013

Das T5-4 TPC-H Ergebnis naeher betrachtet

Inzwischen haben vermutlich viele das neue TPC-H Ergebnis der SPARC T5-4 gesehen, das am 7. Juni bei der TPC eingereicht wurde.  Die wesentlichen Punkte dieses Benchmarks wurden wie gewohnt bereits von unserer Benchmark-Truppe auf  "BestPerf" zusammengefasst.  Es gibt aber noch einiges mehr, das eine naehere Betrachtung lohnt.

Skalierbarkeit

Das TPC raet von einem Vergleich von TPC-H Ergebnissen in unterschiedlichen Groessenklassen ab.  Aber auch innerhalb der 3000GB-Klasse ist es interessant:

  • SPARC T4-4 mit 4 CPUs (32 Cores mit 3.0 GHz) liefert 205,792 QphH.
  • SPARC T5-4 mit 4 CPUs (64 Cores mit 3.6 GHz) liefert 409,721 QphH.

Das ist nicht ganz 100% Skalierbarkeit, wenn man davon ausgeht, dass die doppelte Anzahl Kerne das doppelte Ergebnis liefern sollte.  Etwas anspruchsvoller, koennte man natuerlich auch einen Faktor von 2.4 erwarten, wenn man die hoehere Taktrate mit beruecksichtigt.   Da das TPC keine Schaetzungen und andere Zahlenspielereien erlaubt, ueberlasse ich das dem Leser.  Jetzt jedoch ein Blick auf einige Details, die eine moegliche Erklaerung liefern koennen:

Plattenspeicher

Im Bericht auf BestPerf und auch im Full Disclosure Report der TPC stehen einige interessante Details zum Plattenspeicher und der Konfiguration.   In der Konfiguration der SPARC T4-4 wurden 12 2540-M2 Arrays verwendet, die jeweils ca. 1.5 GB/s Durchsatz liefert, insgesamt also eta 18 GB/s.  Dabei waren die Arrays offensichtlich mit jeweils 2 Kabeln pro Array direkt an die 24 8GBit FC-Ports des Servers angeschlossen.  Mit den 2x 8GBit Ports pro Array koennte man so ein theoretisches Maximum von 2GB/s erreichen.  Tatsaechlich wurden 1.5GB/s geliefert, was so ziemlich dem realistischen Maximum entsprechen duerfte.

Fuer den Lauf mit der SPARC T5-4 wurden doppelt so viele Platten verwendet.  Dafuer wurden die 2540-M2 Arrays mit je einem zusaetzlichen Plattentray erweitert.  Mit dieser Konfiguration wurde dann (laut BestPerf) ein Maximaldurchsatz von 33 GB/s erreicht - nicht ganz das doppelte des SPARC T4-4 Laufs.  Um tatsaechlich den doppelten Durchsatz (36 GB/s) zu liefern, haette jedes der 12 Arrays 3 GB/s ueber seine 4 8GBit Ports liefern muessen.  Im FDR stehen nur 12 dual-port FC HBAs, was die Verwendung der Brocade FC Switches erklaert: Es wurden alle 4 8GBit ports jedes Arrays an die Switches angeschlossen, die die Datenstroeme dann in die 24 16GBit HBA ports des Servers buendelten.  Diese Konfiguration liefert ein theoretisches Maximum von 48x8GBbit FC Bandbreite von den Arrays an die 24 FC Ports des Servers.  Das theoretische Maximum jedes Storage-Arrays waere nun 4 GB/s.  Wenn man jedoch den Protokoll- und "Realitaets"-Overhead mit einrechnet, sind die tatsaechlich gelieferten 2.75 GB/s gar nicht schlecht.  Mit diesen Zahlen im Hinterkopf ist die Verdopplung des SPARC T4-4 Ergebnisses eine gute Leistung - und gleichzeitig eine moegliche Erklaerung, warum nicht bis zum 2.4-fachen skaliert wurde.  Aber natuerlich koennte es auch andere Gruende wie bspw. Software-Skalierbarkeit geben, die hier eine Rolle spielten.

Nebenbei bemerkt: Weder die SPARC T4-4 noch die SPARC T5-4 hatten in der gemessenen Konfiguration irgendwelche Flash-Devices.

Mitbewerb

Seit die T4 Systeme auf dem Markt sind, bemuehen sich unsere Mitbewerber redlich darum, ueberall den Eindruck zu hinterlassen, die Leistung des SPARC CPU-Kerns waere weiterhin mangelhaft.  Auch scheinen sie ueberzeugt zu sein, dass (ueber)grosse Caches und hohe Taktraten die einzigen Schluessel zu echter Server Performance seien.  Wenn ich mir nun jedoch die oeffentlichen TPC-H Ergebnisse ansehe, sehe ich dies:

TPC-H @3000GB, Non-Clustered Systems
System QphH
SPARC T5-4
3.6 GHz SPARC T5
4/64 – 2048 GB
409,721.8
SPARC T4-4
3.0 GHz SPARC T4
4/32 – 1024 GB
205,792.0
IBM Power 780
4.1 GHz POWER7
8/32 – 1024 GB
192,001.1
HP ProLiant DL980 G7
2.27 GHz Intel Xeon X7560
8/64 – 512 GB
162,601.7

Kurz zusammengefasst: Mit 32 Kernen (mit 3 GHz und 4MB L3 Cache), liefert die SPARC T4-4 mehr QphH@3000GB ab als IBM mit ihrer 32 Kern Power7 (bei 4.1 GHz und 32MB L3 Cache) und auch mehr als HP mit einem 64 Kern Intel Xeon System (2.27 GHz und 24MB L3 Cache).  Ich frage mich, wo genau SPARC hier mangelhaft ist?

Nun koennte man natuerlich argumentieren, dass beide Ergebnisse nicht gerade neu sind.  Nun, in Ermangelung neuerer Ergebnisse kann man ja mal ein wenig spekulieren:

IBMs aktueller Performance Report listet die o.g. IBM Power 780 mit einem rPerf Wert von 425.5.  Ein passendes Nachfolgesystem mit Power7+ CPUs waere die Power 780+ mit 64 Kernen, verfuegbar mit 3.72 GHz.  Sie wird mit einem rPerf Wert von  690.1 angegeben, also 1.62x mehr.  Wenn man also annimmt, dass Plattenspeicher nicht der limitierende Faktor ist (IBM hat mit 177 SSDs getestet, sie duerfen das gerne auf 400 erhoehen) und IBMs eigene Leistungsabschaetzung zugrunde legt, waere IBM dennoch nicht in der Lage, die Leistung des Power7 Systems zu verdoppeln.  Und sie wuerden ja mehr als das brauchen, um an die Leistung der T5-4 heran zu kommen.  Das ist insbesondere in der von IBM so geschaetzten "per core" Metric schmerzlich.

In der x86-Welt sieht es nicht besser aus.  Leider gibt es von Intel keine so praktischen rPerf-Tabellen.  Daher muss ich hier fuer eine Schaetzung auf SPECint_rate2006 zurueckgreifen.  (Ich bin kein grosser Fan von solchen Kreuz- und Querschaetzungen.  Insb. SPECcpu ist nicht besonders geeignet, um Datenbank-Leistung abzuschaetzen, da fast kein IO im Spiel ist.)  Das o.g. HP System wird bei SPEC mit 1580 CINT2006_rate gelistet.  Das bis einschl. 2013-06-14 beste Resultat fuer den neuen Intel Xeon E7-4870 mit 8 CPUs ist 2180 CINT2006_rate.  Das ist immerhin 1.38x besser.  (Wenn man nur die Taktrate beruecksichtigen wuerde, waere man bei 1.32x.)  Hier weiter zu rechnen, ist muessig und ich ueberlasse das gern dem Leser.  Die Ergebnisse sind fuer x86 nicht gerade ermutigend...

Natuerlich sind IBM oder HP herzlich eingeladen, diese Werte zu widerlegen.  Aber stand heute warte ich noch auf aktuelle Benchmark Veroffentlichungen in diesem Datensegment.

Was koennen wir also zusammenfassen?

  • Es gibt einige Hinweise, dass der Plattenspeicher der begrenzende Faktor sein koennte, der die SPARC T5-4 daran hinderte, auf jenseits von 2x zu skalieren
  • Der Mythos, dass SPARC Kerne keine Leistung bringen, ist genau das - ein Mythos.  Wie sieht es umgekehrt eigentlich mit einem TPC-H Ergebnis fuer die Power7+ aus?
  • Cache ist nicht der magische Performance-Schalter, fuer den ihn manche Leute offenbar halten.
  • Ein System, eine CPU-Architektur und ein Betriebsystem jenseits einer gewissen Grenze zu skalieren ist schwer.  In der x86-Welt scheint es noch ein wenig schwerer zu sein.

Was fehlt?  Nun, das Thema Preis/Leistung ueberlasse ich gerne den Verkaeufern ;-)

Und zu guter Letzt: Nein, ich habe mich nicht ins Marketing versetzen lassen.  Aber manchmal kann ich mich einfach nicht zurueckhalten...


Disclosure Statements

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

TPC-H, QphH, $/QphH are trademarks of Transaction Processing Performance Council (TPC). For more information, see www.tpc.org, results as of 6/7/13. Prices are in USD. SPARC T5-4 409,721.8 QphH@3000GB, $3.94/QphH@3000GB, available 9/24/13, 4 processors, 64 cores, 512 threads; SPARC T4-4 205,792.0 QphH@3000GB, $4.10/QphH@3000GB, available 5/31/12, 4 processors, 32 cores, 256 threads; IBM Power 780 QphH@3000GB, 192,001.1 QphH@3000GB, $6.37/QphH@3000GB, available 11/30/11, 8 processors, 32 cores, 128 threads; HP ProLiant DL980 G7 162,601.7 QphH@3000GB, $2.68/QphH@3000GB available 10/13/10, 8 processors, 64 cores, 128 threads.

SPEC and the benchmark names SPECfp and SPECint are registered trademarks of the Standard Performance Evaluation Corporation. Results as of June 18, 2013 from www.spec.org. HP ProLiant DL980 G7 (2.27 GHz, Intel Xeon X7560): 1580 SPECint_rate2006; HP ProLiant DL980 G7 (2.4 GHz, Intel Xeon E7-4870): 2180 SPECint_rate2006,

Mittwoch Jun 12, 2013

Den root pool erweitern

Zwischendurch mal ein wenig Laptop-Erfahrung...  Ich habe endlich entschieden, dieses zweite OS von der Platte zu verbannen (Ich hatte es so selten benutzt, dass ich regelmaessig das Passwort zuruecksetzen musste...).  Der Ertrag waren 50g wertvoller Laptop-Plattenplatz - gluecklicher Weise an der richtigen Stelle auf der Platte.  In der Theorie muesste ich also nur die Solaris-Partition erweitern, ZFS Bescheid sagen und den Platz geniessen.  Aber natuerlich gibt es da so verschiedene kleine Fallen.

Um Verwirrung vorzubeugen - es geht hier um x86.  Bei einem normalen SPARC Server hat man die Probleme, fuer die ich hier Loesungen beschreibe gar nicht.

Erste Lektion: Man sollte nicht versuchen, mit fdisk die Partition zu veraendern solange Solaris darauf noch laeuft.  Das funktioniert zwar, aber es gibt freundlichere Varianten des Shutdowns.  (Was hier passiert ist, dass fdisk nicht nur die Partition neu anlegt, sondern auch ein dazu passendes Label schreibt.  Das bedeutet allerdings, dass ZFS den Slice fuer den rpool nicht mehr findet.  Und das wiederum fuehrt zu einem sehr introvertierten Solaris...)  Richtig macht man das, indem man von irgendetwas anderem bootet (PXE, USB, DVD, etc) und dann die Partition veraendert.  Danach nicht vergessen, den Slice fuer den ZFS pool wieder anzulegen.  Wichtig dabei ist, dass dieser Slice wieder mit genau dem gleichen Zylinder anfaengt.  Die Laenge ist natuerlich eine andere.  (Ich zumindest musste das so machen, da  mein rpool in s0 lag.)

Danach ging es weiter wie im Handbuch:  Solaris booten und entweder  "zpool set autoexpand=on rpool" oder zpool online -e rpool c0t0d0s0" und schon waren da 50g mehr Platz.

Habe ich vergessen zu erwaehnen, dass ich doch tatsaechlich vor all dem ein volles Backup gemacht habe?  Ich werde doch langsam alt...

Donnerstag Apr 04, 2013

Ein paar Bemerkungen zur T5

Inzwischen wird fast jeder die Ankündigung der neuen T5 und M5 Systeme gesehen haben.  Ich möchte hier nichts wiederholen, aber doch ein paar erste Gedanken dazu loswerden.  Meine Gedanken, wohlgemerkt, nicht notwendiger Weise die von Oracle.

Bei der Ankündigung war es recht offensichtlich, dass wir in Zukunft noch mehr Freude am Wettbewerb mit IBM haben werden.  Ich werde mich an diesem Krieg der Worte nicht beteiligen sondern nur auf eine sehr lesenswerte Zusammenfassung (der bisherigen Scharmützel) hinweisen, die man bei Forbes findet.  Die zwei Minuten Lesezeit lohnen sich - ich finde es sehr interessant, wie IBM plötzlich das Interesse an Performance verliert...

Da ein Großteil der Aufmerksamkeit die die Ankündigung erregt hat sich auf Performance-Behauptungen bezieht, möchte ich hier einfach eine knappe, übersichtliche Zusammenfassung der gebräuchlicheren Benchmarks angeben, die wir veröffentlicht haben.  Vergleiche mit anderen Systemen überlasse ich anderen - ich will niemanden den Spass nehmen ;-)

Es gibt noch ettliche weitere Veröffentlichungen zum Thema Performance, insbesondere auf dem BestPerf blog.  Manche davon sind recht interessant, weil sie T5 mit x86 vergleichen, etwas was ich all denen empfehlen moechte, die ab und zu ihr Weltbild überdenken wollen.  Ich habe hier diejenigen aufgeführt, die meist als "unabhängig" betrachtet werden.  Nun wissen wir ja alle, dass ein Weltrekord nur so lange gilt, bis der nächste veröffentlicht wird.  Bleibt die Frage, wer der nächste sein wird.  (Wir haben ab und zu auch unsere eigenen Rekorde eingestellt...)   Und zu guter letzt möchte ich erwähnen, dass Performance ja nicht immer alles ist.  Price/Performance ist oft mindestens genauso wichtig.  Im Benchmark-Spiel kann man idR. nur Listenpreise vergleichen.  Wer Lust hat, kann sich damit ja mal amüsieren!  Larry meint dazu lediglich:   “You can go faster, but only if you are willing to pay 80% less than what IBM charges.”

Wettbewerb ist spannend, oder nicht?

About

Neuigkeiten, Tipps und Wissenswertes rund um SPARC, CMT, Performance und ihre Analyse sowie Erfahrungen mit Solaris auf dem Server und dem Laptop.

This is a bilingual blog (most of the time). Please select your prefered language:
.
The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

Search

Categories
Archives
« Mai 2016
MoDiMiDoFrSaSo
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
     
Heute