Spätestens mit Veröffentlichung von Windows Azure wird deutlich, mit welcher Entschiedenheit Microsoft den Weg in Richtung Cloud Computing einschlägt. Neben dem Outsourcing von Infrastruktur verfolgen Unternehmen, die auf Cloud Computing setzen, ein zentrales Ziel: Skalierung von Anwendungen durch Nutzung der Infrastruktur eines Service Providers, die ebenfalls massiv skaliert.
Grundsätzlich gibt es zwei Ansätze, um Anwendungen zu skalieren
Windows Azure setzt intern klar auf den zweiten Ansatz, Scale-out, und unterstützt auch für Anwendungen, die auf Windows Azure betrieben werden, diesen Ansatz.
Aufbau skalierbarer Services
Die Windows Azure Services Plattform bietet mit SQL Services und .NET Services Dienste, die nahelegen, selbstgeschriebene Services, die auf Windows Azure betrieben werden sollen, in entsprechende Tiers zu unterteilen. Folgende Unterteilung empfiehlt sich:
Durch eine klare Trennung dieser Tiers wird eine Skalierbarkeit auf einzelnen Schichten ermöglicht, d.h. Skalierung kann pro Tier entschieden, geplant und umgesetzt werden.
Ein paar Definitionen...
Wird nun eine dieser Schichten auf mehrere Server verteilt, stellt sich die Frage, wie die einzelnen Server konsistent gehalten werden. Hierbei lassen sich drei Level für die Konsistenzherstellung (Consistency Level) unterscheiden:
Um die einzelnen Instanzen abzugleichen, müssen Nachrichten ausgetauscht werden. Hierbei stellt sich die Frage, welche Anforderungen an die Nachrichtenzustellung (Message Assurance) gestellt werden. Dabei gibt es vier grundlegende Anforderungsstufen:
Infrastrukturoptionen
Die letztgenannte Option vereint die Vorteile von Load Balancing und Ausfallsicherheit, stellt an die Software und die Infrastruktur allerdings auch die höchsten Anforderungen: die einzelnen Maschinen müssen sich synchronisieren, im Fall des Ausfalls einer Maschine muss ein Umleiten von Anfragen an die ausgefallene Maschine erfolgen.
Architekturtipps
Für die Architektur einer hoch skalierbaren Anwendung können folgende Empfehlungen gegeben werden:
Tip 1: Auswahl eines high-level-Frameworks
"the higher level the framework you use, the more portable your service will get"
So simpel dieser Satz ist, so groß ist doch auch seine Bedeutung. Bei Einsatz eines Frameworks wie der Azure Services, wird die Entscheidung für ein Hostingmodell (vor-Ort, beim Hoster, bei Microsoft) zu einer Entscheidung, die zum Deploymentzeitpunkt getroffen werden kann. Deshalb empfiehlt sich der Einsatz eines high-level-Frameworks (low-level-Frameworks treffen häufig zu viele Annahmen über die Umgebung, in der sie eingesetzt werden).
Tip 2: Separierung von Service- und Hosting-Codes
Infrastruktur-Code sollte in Konfigurationsdaten und dedizierte, pro Umgebung verwaltbare Konfigurationskomponenten ausgelagert werden. Damit sind bei einem Transfer in eine andere (skalierbarere) Umgebung nur die Hosting-Codes anzupassen.
Tip 3: Partitionierung des Codes (horizontal in Tiers, vertikal z.B. in Schemata)
Schichtenbildung in der Software erlaubt, wie oben bereits beschrieben, Skalierungsmaßnahmen auf den einzelnen Schichten durchzuführen. Wird in der Datenschicht hohe Skalierung gewünscht, so kann diese beispielsweise auf SQL Data Services betrieben werden.
Designtipps
Tip 1: Einsatz loser Koppelung
Lose Kopplung und die Einhaltung von Prinzipien serviceorientierter Architektur schafft die Mobilität von Services und z,B. auch die Voraussetzung, Services auf eine skalierbare Umgebung zu verschieben. Wo die Datenschicht beispielsweise zunächst lokal betrieben werden kann, kann diese bei entsprechend loser Kopplung auch auf SQL Data Services verschoben werden. Solange die Schnittstelle konstant bleibt, bekommen die anderen Schichten hiervon nichts mit.
Tip 2: Verwendung von Caches und "stale" Data
Caches können den Ausfall von Schichten abfangen, indem sie Daten solange bereithalten, solange der "Live" Speicher unverfügbar ist.
Tip 3: Implementierung einiger zentraler "recovery paths"
Nachdem der Ausfall einzelner Serverkomponenten möglich ist, muss es möglich sein, nach Ersatz der fehlerhaften Komponente wieder einen konsistenten Systemzustand herzustellen. Hierfür sollten entsprechende Funktionalitäten bereitgestellt werden.
Tip 4: Vermeidung von Shutdown-Code
Insbesondere im Falle von Cloud Computing sollte immer damit gerechnet werden, dass die Hardware, auf der eine Instanz der Software läuft, (ohne Zeitverzögerung) ausfällt.
Tip 5: Unabhängigkeit von der zugrundeliegenden Topologie
Es sollte vermieden werden, sich Informationen zu verlassen, die vom Administrator, d.h. dem Betreiber der Software zur Laufzeit geändert werden könnten. Also: keine hardcodierten Servernamen, IP-Adressen etc. Diese Informationen sollten, wenn sie benötigt werden, in Konfigurationsdateien ausgelagert werden.