Langsame OS-Laufwerke, schnelle Daten-Laufwerke
Über die Jahre habe ich festgestellt, dass Menschen häufig im Zweifel zugunsten von hochleistungsfähigem, hochzuverlässigem Datenspeicher für eine Betriebssystempartition entscheiden, aber langsamen, “kosteneffizienten” Speicher für kritische Datenbestände wählen. Ich bin erstaunt, wie oft ich dies vorfinde, und nun, mit dem Aufkommen von Hypervisoren, sehe ich, wie sich dasselbe Verhalten auch dort wiederholt – was die zuvor bestehenden Probleme noch verschärft.
In vielen Systemen haben wir es heute mit nur einem einzigen Speicher-Array zu tun, das von allen Komponenten des Systems gemeinsam genutzt wird. In diesen Fällen stehen wir nicht vor dem Problem, die Leistung unseres Speichersystems aus dem Gleichgewicht zu bringen. Dies ist einer der großen Vorteile dieses Ansatzes und ein wesentlicher Grund, warum er so nachdrücklich empfohlen wird. Die gesamte Leistung liegt in einem gemeinsamen Pool, und die Komponenten, die die Leistung benötigen, haben Zugriff darauf.
In vielen Fällen stelle ich fest, dass Menschen – sei es im Bestreben nach gesteigerter Leistung oder Zuverlässigkeitsgestaltung oder aus technischer Notwendigkeit – ihre Speicher-Arrays auftrennen und Hypervisoren und Betriebssysteme auf das eine Array und Daten auf ein anderes legen. Doch was ich schockierend finde, ist, dass die dem Hypervisor oder Betriebssystem gewidmeten Arrays oft erstaunlich groß in der Kapazität und extrem hoch in der Leistung sind – oft unter Einsatz von Spindeln mit 15.000 U/min oder gar Solid-State-Laufwerken zu enormen Kosten. Fast immer in RAID 1 (gemäß den gängigen Standards von 1998).
Was hier verstanden werden muss, ist, dass Betriebssysteme selbst praktisch keine Speicher-IO-Anforderungen haben. Es gibt eine geringe Menge, vor allem für die Systemprotokollierung, doch das ist auch schon alles, was benötigt wird. Betriebssystempartitionen sind nahezu vollständig statisch. Erforderliche Komponenten werden in den Speicher geladen, größtenteils beim Systemstart, und werden nicht erneut aufgerufen. Selbst in Fällen, in denen Protokollierung erforderlich ist, werden diese Protokolle häufig an ein zentrales Protokollierungssystem gesendet und nicht in den Systemspeicherbereich, was auch diesen Bedarf reduziert oder sogar beseitigt.
Bei Hypervisoren ist dieser Effekt sogar noch extremer. Da Hypervisoren weit leichtgewichtiger und weniger umfangreich sind als herkömmliche Betriebssysteme, verhalten sie sich eher wie eingebettete Systeme und sind in vielerlei Hinsicht in vielen Fällen tatsächlich eingebettete Systeme. Hypervisoren werden beim Systemstart in den Speicher geladen, und ihr Medium wird, während ein System läuft, fast nie wieder benötigt, abgesehen von gelegentlicher Protokollierung. Da Hypervisoren physisch klein sind, ist selbst die gesamte Zeit, die benötigt wird, um einen vollständigen Hypervisor vom Speicher zu lesen, sehr gering, selbst auf sehr langsamen Medien, weil die Gesamtgröße sehr klein ist.
Aus diesen Gründen ist die Speicherleistung für Betriebssysteme und insbesondere für Hypervisoren von geringer bis gar keiner Bedeutung. Der Unterschied zwischen schnellem und langsamem Speicher wirkt sich wirklich nur auf die Systemstartzeit aus, bei der der Unterschied von einer Sekunde oder dreißig Sekunden selten bemerkt würde, wenn überhaupt. Wann würde irgendjemand selbst mehrere zusätzliche Sekunden während des Starts eines Systems wahrnehmen, und in den meisten Fällen sind Startvorgänge seltene Ereignisse, die höchstens einmal pro Woche während eines automatisierten, routinemäßigen Systemneustarts in einem geplanten Wartungsfenster auftreten, oder sehr selten, manchmal nur einmal alle paar Jahre, bei Systemen, die nur im Notfall offline genommen werden. Selbst das langsamste denkbare Speichersystem ist für diese Rolle weitaus schneller als nötig.
Selbst langsamer Speicher ist für Aktivitäten der Systemprotokollierung im Allgemeinen um ein Vielfaches schneller als nötig. In jenen seltenen Fällen, in denen die Protokollierung sehr intensiv ist, haben wir viele Möglichkeiten, dieses Problem anzugehen. Die naheliegendste und gängigste Lösung besteht hier darin, Protokolle an ein anderes Laufwerks-Array zu senden als an das, das vom Betriebssystem oder Hypervisor verwendet wird. Dies ist eine sehr einfache Lösung und letztlich sehr praktisch in Fällen, in denen sie gerechtfertigt ist. Die andere gängige und überaus nützliche Lösung besteht darin, Protokolle schlicht gar nicht auf dem lokalen Gerät zu behalten und sie an ein entferntes Protokollsammlungswerkzeug wie Splunk, Loggly oder ELK zu senden.
Das andere wesentliche Anliegen, das die meisten Menschen rund um ihre Betriebssysteme und Hypervisoren haben, ist die Zuverlässigkeit. Es ist üblich, mehr Anstrengungen auf den Schutz dieser vergleichsweise unwichtigen Aspekte eines Systems zu richten als auf die oft unersetzlichen Daten. Betriebssysteme und Hypervisoren lassen sich jedoch bei Bedarf leicht von Grund auf neu aufbauen, mittels Neuinstallationen und manueller Neukonfiguration, wo nötig. Die Details, die verloren gehen könnten, sind im Allgemeinen relativ trivial neu zu erstellen.
Das bedeutet nicht, dass diese System-Dateisysteme nicht gesichert werden sollten, natürlich sollten sie das (in den meisten Fällen). Doch für den Fall, dass auch die Backups fehlschlagen, ist es selten, dass der Verlust einer OS-Partition oder eines OS-Dateisystems wirklich eine Tragödie bedeutet, sondern nur eine Unannehmlichkeit. Es gibt in nahezu allen Fällen Wege zur Wiederherstellung ohne Zugriff auf die Originaldaten, solange das “Daten”-Dateisystem getrennt ist. Und aufgrund der Natur von Betriebssystemen und Hypervisoren sind Änderungen selten, sodass Backups im Allgemeinen weniger häufig erfolgen können, möglicherweise nur manuell ausgelöst, wenn Updates angewendet werden!
Bei vielen modernen Systemen im Bereich DevOps und Cloud Computing ist es sehr verbreitet geworden, Betriebssystem- und Hypervisor-Dateisysteme als vollständig entbehrlich zu betrachten, da sie aus der Ferne über ein Systemabbild oder ein Konfigurationsmanagementsystem definiert werden. In diesen Fällen, die immer häufiger werden, besteht kein Bedarf an Datenschutz oder Backups, da das gesamte System darauf ausgelegt ist, nahezu augenblicklich und ohne jede besondere Interaktion neu erstellt zu werden. Das System ist vollständig selbstreplizierend. Dies trivialisiert den Bedarf am Schutz von System-Dateisystemen weiter.
Zusammengenommen ergeben der fehlende Bedarf an Leistung und der fehlende Bedarf an Schutz und Zuverlässigkeit, der in erster Linie durch einfache Neuerstellung abgedeckt wird, ein System-Dateisystem mit ganz anderen Anforderungen, als wir gemeinhin annehmen. Das bedeutet nicht, dass wir mit unserem Speicher leichtsinnig umgehen sollten; wir wollen weiterhin einen Speicherausfall vermeiden, während ein System läuft, und ein unnötiger Neuaufbau ist eine Verschwendung von Zeit und Ressourcen, selbst wenn er sich nicht als katastrophal erweist. Daher ist es wichtig, ein sorgfältiges Gleichgewicht zu finden.
Aus diesen Gründen ist es natürlich heute gängige Praxis, das Betriebssystem oder den Hypervisor auf demselben Speicher-Array wie die Daten unterzubringen – weil kaum bis gar kein Bedarf an Speicherzugriff auf die Systemdateien zur selben Zeit besteht, zu der ein Zugriff auf die Datendateien erfolgt, sodass wir große Synergie erzielen, indem wir schnelle Startzeiten für das OS und keine nachteiligen Auswirkungen auf die Datenzugriffszeiten erhalten, sobald das System online ist. Dies ist das wesentliche Mittel, mit dem Systemdesigner heute dem Bedarf an einer effizienten Nutzung von Speicher begegnen.
Wenn das Betriebssystem oder der Hypervisor von den Arrays getrennt werden muss, die Daten halten – was weiterhin aus unzähligen Gründen vorkommen kann –, streben wir im Allgemeinen danach, angemessene Zuverlässigkeit zu geringen Kosten zu erzielen. Bei Verwendung von herkömmlichem Speicher (lokalen Festplatten) bedeutet dies den Einsatz kleiner, langsamer, kostengünstiger rotierender Laufwerke für den Betriebssystemspeicher, im Allgemeinen in einer einfachen RAID-1-Konfiguration. Ein Beispiel aus der Praxis ist die Verwendung von “umweltfreundlichen” SATA-Laufwerken mit 5400 U/min in den kleinstmöglichen Größen. Diese ziehen wenig Strom und sind sehr günstig in der Anschaffung. SSDs und Hochgeschwindigkeits-SAS-Laufwerke würden gemieden, da sie einen Aufpreis für einen Schutz kosten, der irrelevant ist, und für eine Leistung, die vollständig verschwendet wird.
Bei weniger herkömmlichem Speicher ist es üblich, ein kostengünstiges SAN mit hoher Dichte zu verwenden, das den Speicher niedriger Priorität für viele Systeme auf gemeinsam genutzten, langsamen Arrays konsolidiert, die nicht repliziert werden. Dies ist nur in größeren Umgebungen wirksam, die den zusätzlichen Architekturentwurf rechtfertigen können und im Prozess der Speicherkonsolidierung eine ausreichende Dichte erzielen können, um die nötigen Kosteneinsparungen zu schaffen, doch in größeren Umgebungen ist dies vergleichsweise einfach. SAN-Boot-Geräte können über viele Server hinweg sehr kostengünstige Arrays zur Kosteneinsparung nutzen. Im virtuellen Bereich könnte dies einen leistungsschwachen Datastore für virtuelle OS-Festplatten und einen anderen, leistungsstarken Pool für virtuelle Datenfestplatten bedeuten. Dies hätte denselben Effekt wie die Boot-SAN-Strategie, jedoch in einem moderneren Umfeld, und könnte zur Umsetzung leicht die SAN-Architektur im Hintergrund nutzen.
Schließlich, und am eindrücklichsten, gilt bei Hypervisoren die allgemeine Faustregel, sie auf SD-Karten oder USB-Sticks zu installieren statt auf herkömmlichem Speicher, da ihre Leistungs- und Zuverlässigkeitsanforderungen sogar noch viel geringer sind als die herkömmlicher Betriebssysteme. Würde ein Laufwerk dieser Art ausfallen, während ein System läuft, würde es normalerweise tatsächlich ohne jegliches Problem weiterlaufen, da das Laufwerk nach dem anfänglichen Start des Systems nie verwendet wird. Erst bei einem Neustart würde ein Problem festgestellt, und zu diesem Zeitpunkt könnte ein Backup-Boot-Gerät verwendet werden, etwa eine zweite SD-Karte oder ein zweiter USB-Stick. Dies ist die offizielle Empfehlung für VMware vSphere, wird von Microsoft-Vertretern häufig für HyperV empfohlen und ist über die OEM-Anbieter von HyperV offiziell unterstützt und wird oft, aber nicht so breit unterstützt, für Xen, XenServer und KVM empfohlen. Die Verwendung von SD-Karten oder USB-Laufwerken für den Hypervisor-Speicher macht einen Virtualisierungsserver effektiv zu einem eingebetteten System. Auch wenn sich dies für Systemadministratoren, die es gewohnt sind, herkömmliche Festplatten als Notwendigkeit für Server zu betrachten, unnatürlich anfühlen mag, ist es wichtig, sich daran zu erinnern, dass hochkritische Systeme der Enterprise-Klasse wie Router und Switches Jahrzehnte halten und genau dieselbe Strategie aus genau denselben Gründen verwenden.
Eine gängige Strategie für Hypervisoren in diesem eingebetteten Modus mit SD-Karten oder USB-Laufwerken besteht darin, zwei solcher Geräte zu haben, bei denen es sich tatsächlich um eine SD-Karte und ein USB-Laufwerk handeln kann, jedes mit einer Kopie des Hypervisors. Fällt ein Gerät aus, ist das Booten vom zweiten Gerät nahezu ebenso wirksam wie ein herkömmliches RAID-1-System. Doch anders als bei den meisten herkömmlichen RAID-1-Aufbauten verfügen wir auch über ein vergleichsweise einfaches Mittel, Systemupdates zu testen, indem wir jeweils nur ein Boot-Gerät aktualisieren und den Vorgang testen, bevor wir das zweite Boot-Gerät aktualisieren, was uns einen zuverlässigen, gut getesteten Rückfall lässt, falls ein Versionsupdate schiefgeht. Dieser Vorgang war tatsächlich auf großen UNIX-RISC-Systemen verbreitet, bei denen Boot-Geräte häufig lokale Software-RAID-1-Sets waren, die eine ähnliche Praxis unterstützten, besonders verbreitet in AIX- und Solaris-Kreisen.
Es sei außerdem angemerkt, dass dieser Ansatz zwar die bewährte Vorgehensweise für die meisten Hypervisor-Szenarien ist, es jedoch tatsächlich keinen Grund gibt, warum er nicht auch auf vollständige Betriebssystem-Dateisysteme angewendet werden kann, außer dass es oft mehr Aufwand bedeutet. Einige Betriebssysteme, insbesondere Linux und BSD, sind sehr geschickt darin, auf eingebettete Weise installiert zu werden, und können mit ein wenig Planung leicht für die Installation auf SD-Karte oder USB-Laufwerk angepasst werden. Dieser Ansatz ist keineswegs verbreitet, doch es gibt keinen technischen Grund, warum er unter den richtigen Umständen nicht ein ausgezeichneter Ansatz wäre, abgesehen von der Tatsache, dass ein Betriebssystem fast nie auf physischer Hardware statt auf einem Hypervisor installiert werden sollte. In jenen Fällen, in denen physische Installationen notwendig sind, ist dieser Ansatz äußerst sinnvoll.
Wenn Sie Speichersysteme entwerfen und planen, denken Sie daran, achtsam zu sein, wie Lese- und Schreibmuster wirklich aussehen werden, wenn ein System läuft. Und denken Sie daran, dass sich der Speicher seit der Entwicklung vieler herkömmlicher Leitlinien recht dramatisch verändert hat und nicht das gesamte Wissen, das zu ihrer Entwicklung herangezogen wurde, heute noch zutrifft oder gleichermaßen zutrifft. Denken Sie nicht nur darüber nach, welche Speichersubsysteme versuchen werden, Speicherleistung zu nutzen, sondern auch, wie sie miteinander interagieren werden (zum Beispiel: Fordern zwei Systeme nie gleichzeitig Speicherzugriff an, oder geraten sie regelmäßig in Konflikt?) und ob ihre Zugriffsleistung wichtig ist oder nicht. Allgemeine Betriebssystemfunktionen können auf einem Datenbankserver überaus langsam sein, ohne negative Auswirkungen; alles, worauf es ankommt, ist die Geschwindigkeit, mit der auf eine Datenbank zugegriffen werden kann. Selbst der Zugriff auf Anwendungs-Binärdateien ist oft irrelevant, da auch sie, einmal in den Speicher geladen, dort verbleiben und nur die Speichergeschwindigkeit die laufende Leistung beeinflusst.
Nichts hiervon soll nahelegen, dass es ratsam ist, OS- und Datenspeichersubsysteme voneinander zu trennen; oft ist es das nicht. Ich habe in der Vergangenheit darüber geschrieben, wie die Konsolidierung dieser Subsysteme recht häufig die beste Vorgehensweise ist, und das gilt auch heute noch. Doch es gibt auch viele sinnvolle Fälle, in denen es Sinn ergibt, bestimmte Speicheranforderungen voneinander zu trennen, oft beim Umgang mit großmaßstäblichen Systemen, bei denen wir die Kosten senken können, indem wir teuren Speicher bestimmten Anforderungen und kostengünstigen Speicher anderen Anforderungen widmen, und in genau diesen Fällen möchte ich aufzeigen, dass Betriebssysteme und Hypervisoren sowohl in Bezug auf Leistung als auch auf Zuverlässigkeit als die niedrigste Priorität betrachtet werden sollten, außer in den extremsten Fällen.
