NoSQL-Datenbanken auf Windows Azure als Cloud-Plattform

NoSQL und die Cloud?
Kommentare

Über Jahrzehnte hinweg haben wir in der Softwareentwicklung kaum an Alternativen zu relationalen Datenbanken gedacht. Klar, einige Ansätze gab es Mitte der 90iger mit objektorientierten Datenbanken oder später mit XML-Datenbanken. Ernsthaft durchsetzen konnte sich aber keiner dieser Ansätze und so konnten klassische RDBMS ihre Vorherrschaft unangefochten fortführen. Jetzt hat sich dies aber geändert. Einige „alternative“ Datenbanken erfreuen sich unter dem Begriff „NoSQL“ zunehmend an Beliebtheit, und das vor allem in Cloud-basierten und skalierbaren Systemen immer häufiger. Warum ist das so? Was können so genannte NoSQL-Datenbanken besser, was nicht? Und warum erfreuen sie sich gerade im Zusammenhang mit Cloud Computing immer größerer Beliebtheit?

Genau mit diesen Fragen beschäftigen wir uns in diesem Artikel – ins Besondere mit Fokus auf Windows Azure. Verstehen Sie diesen Artikel als erste Einführung in das Thema, sodass Sie den Kontext und die Optionen für NoSQL in Azure besser verstehen. Vereinfacht dargestellt verstehen die meisten Personen in der Software Industrie mittlerweile unter dem Begriff NoSQL [1], [2], [3] ein Synonym für „Not Only SQL“. Dabei gibt es streng genommen gar keine formale Definition für den Begriff, wie auch einige bekannte Buchautoren bei der Verfassung ihrer Bücher feststellen mussten [3]. Umso mehr fassen wir heutzutage NoSQL-Datenbanken (kurz NoSQL DBs) vereinfacht als solche Datenbanksysteme zusammen, die nicht dem klassischen relationalen Muster mit allen zugehörigen Eigenschaften inklusive ACID-Transaktionen folgen und vielmehr alternative Storage-Konzepte und Transaktionskonzepte implementieren.

Darüber hinaus trifft der Begriff NoSQL auf Basis meiner bisherigen Erfahrung das Thema recht gut. Denn oftmals werden derartige NoSQL DBs gemeinsam mit eben den bekannten RDBMS-Systemen zur Entwicklung einer Gesamtlösung eingesetzt. Und selbst wenn eine Lösung ausschließlich auf nicht relationale Datenbanksysteme setzt, trifft es der Begriff ganz gut – macht er doch klar, dass die Welt der Datenhaltung nicht mehr ausschließlich aus RDBMS besteht und sich auch Alternativen wie MongoDB, Cassandra, CouchDB oder ähnliche als primärer Storage für Anwendungsdaten in bestimmten Fällen durchsetzen. Vor allem im Cloud-Umfeld treffen wir immer häufiger auch auf derartige Architekturen.

Eines sei jedoch gleich gesagt: kein Vorteil ohne Nachteil. Das heißt also, dieser Artikel soll auf keinen Fall ein NoSQL-Fanbericht sein! Sowohl RDBMS als auch NoSQL-Datenbanken haben ihre Vor- und Nachteile – und diese sollten gezielt genutzt und gut verstanden sein, um entscheiden zu können, welches System denn nun auf welchen Anwendungsfall am besten passt.

CAP-Theorem

Beginnen wir zunächst mal mit ein wenig Theorie. Das CAP-Theorem [4] wurde erstmals von Eric Brewer [5] erwähnt. CAP ist dabei die Abkürzung für „Consistency, Availabilty, Partition Tolerance“ und Brewers Theorie war, dass man sich in einer Anwendungsarchitektur für zwei dieser drei Eigenschaften, also Konsistenz, Verfügbarkeit und keine Seiteneffekte durch Scale-out über mehrere Knoten, entscheiden müsse, da man nicht alle drei gleichzeitig implementieren kann. Obwohl diese Aussage meiner Meinung nach etwas dogmatisch ist, so versteckt sich eine doch sehr wichtige Wahrheit dahinter, über die wir als Softwarearchitekten und -entwickler nur allzu oft hinweg sehen möchten: nämlich die Tatsache, dass man im Leben und so auch in Softwarearchitekturen immer wieder Kompromisse eingehen muss. Ob man es nun will oder nicht. Und daher ergibt sich aus dem CAP-Theorem eine ganz zentrale Tatsache: vollständige Sicherheit in Bezug auf Konsistenz bei schnellstmöglicher Performance und 100 Prozent Verfügbarkeit, das gibt es nicht – oder für moderne Lösungen zumindest nicht in wirtschaftlicher Form. Man wird da oder dort Kompromisse eingehen müssen – wer beispielsweise absolute Sicherheit in Bezug auf Konsistenz der Daten braucht, wird auf ressourcenhungrige ACID-Transaktionen mit Locking- oder Snapshot-Mechanismen zurückgreifen müssen. Diese funktionieren zwar, und mit entsprechender Rechenpower auch flott, doch wird ein derartiges System performancetechnisch kaum mit einem System, das Konsistenz nur wesentlich eingeschränkter in Betracht ziehen muss, mithalten können. Schon gar nicht, wenn die Transaktion noch über zwei oder mehr Compute-Knoten hinweg erfolgen soll, das wird nämlich noch viel aufwändiger.

Ein anderes Beispiel ist etwa Konsistenz und Hochverfügbarkeit. Wenn man beides in vollem Umfang haben möchte, muss man synchron Daten auf mehreren Knoten in einem Cluster replizieren, spiegeln oder Transaktionen ausführen und dem Client erst ein „Okay“ geben, wenn die Daten auf allen Clustern im System vorhanden sind. Das dauert länger, führt also zu einer schlechteren Performance. Wenn Performance allerdings wichtiger ist, dann müsste man die Spiegelung der Daten unter Umständen asynchron durchführen – dann besteht aber für einen gewissen Zeitraum die Chance einer Inkonsistenz der Daten, wenn diese noch nicht fertig auf einen Fail-over-Knoten im Cluster gespiegelt wurden und der Primärknoten ausfällt. Oder noch viel einfacher – wenn bereits Clients Abfragen auf die Sekundärknoten ausführen (was zwecks Performance durchaus ein valider Ansatz ist), könnten unter Umständen noch alte Daten zurückgeliefert werden.

Prioritäten setzen und Kompromisse eingehen, um in einem Teilbereich auf Kosten eines anderen Bereichs besser zu werden – das ist die neue (und alte) Welt der Softwarearchitektur, und das jetzt auch bei Datenbanken!

Scale-out oder Scale-up

Vor allem aus dem RDBMS-Umfeld ist Scale-up das bekannte Verfahren, um zu mehr Leistung zu kommen. Das heißt also, man schafft teurere Hardware in Form von mehr CPUs, mehr RAM oder mehr und schnellere Hard Disks für seinen Datenbank-Cluster an, um die Leistung der Datenbankserver zu steigern. Das funktioniert gut, allerdings wird das ab einem gewissen Level schnell extrem teuer und klappt immer nur bis zu bestimmten Belastbarkeitsgrenzen. Dennoch, für RDBMS ist das oft der einfachste Weg, zu mehr Leistung zu kommen, ohne gleichzeitig auf die heißgeliebten Funktionen wie ACID-Transaktionen oder scheinbar (!!) beliebig komplexe Abfragen mit Joins aller Art verzichten zu müssen.

Ein alternatives Prinzip zur Steigerung der Belastbarkeit eines Systems kennen alle, die schon länger in der Webentwicklung unterwegs sind: Scale-out. Anstatt einzelne Maschinen hochbelastbar zu gestalten, geht man hier den Weg, die Last möglichst gleichmäßig auf viele Maschinen aufzuteilen. Das ermöglicht die Nutzung weitgehend gewöhnlicher Hardware für die einzelnen Maschinen in einer Farm sowie eine mehr oder weniger triviale Leistungssteigerung durch Hinzufügen neuer Maschinen in die Farm. Mittelfristig und vor allem bei sehr hohen Lastanforderungen ist Scale-out wesentlich kostengünstiger und ermöglicht gleichzeitig höhere Skalierbarkeit, da man nicht so schnell wie beim Aufrüsten von Hardware auf physikalische Grenzen stößt. Vor allem in Public Clouds wie Windows Azure, ist es natürlich wesentlich einfacher und damit auch beliebter, Scale-out-Strategien zu verfolgen, da massenhaft Compute Nodes zur Verfügung stehen und relativ schnell zu Services hinzugefügt und von diesen wieder entfernt werden können. In modernen Softwarearchitekturen ist Scale-out immer in irgendeiner Form zu finden und für global skalierbare Anwendungen wird diese Strategie auch für Datenbanksysteme immer wichtiger.

Natürlich werden Kenner sofort anmerken, dass es mittlerweile bei RDBMS Ansätze für Scale-out-Strategien wie Sharding gibt (Abb. 1). Unter Sharding [6]versteht man die Aufteilung von Daten nach bestimmten Regeln, meist Werteschlüssel bestimmter Felder (z. B. nach Mandanten, Länder und dergleichen). Die Daten laufen dann auf viele kleine Datenbanken, die auf verschiedenen Servern oder ganzen Clustern (z. B. für jedes Land oder für jeden Mandanten eine DB), anstatt einer großen Datenbank auf einem einzelnen Cluster. Eine Masterdatenbank hält dabei die Regeln zur Aufteilung der Daten auf die einzelnen kleinen Datenbanken sowie einheitliche Daten, die nicht aufgeteilt werden müssen.

Abb. 1: Sharding/Partitioning von Daten

Fakt ist jedoch, dass man bei RDBMS meist auf sich gestellt ist, das Sharding zu implementieren. Es gibt zwar Ansätze wie z. B. Azure SQL DB Federations [7], diese erfreuen sich allerdings aufgrund einiger Einschränkungen in Bezug auf traditionelle und klassische Vorteile von RDBMS nicht wirklich großer Beliebtheit.

Das ist einer der Faktoren, der NoSQL-Datenbanken aktuell einen derartigen Aufwind verschafft. Denn die meisten NoSQL-Datenbanken wurden für Scale-out-basierten Betrieb und Cluster-basierten Betrieb mit dem Ziel Ausfallsicherheit und Skalierbarkeit entwickelt. Noch viel interessantere Konfigurationsoptionen lassen viele NoSQL-Systeme wie etwa MongoDB oder Cassandra zu, die verschiedene Priorisierungen zwischen Performance, Konsistenz und Ausfallssicherheit ermöglichen. Man hat also die Wahl und kann mit nativen Out-of-the-Box-Funktionen entscheiden, was einem tatsächlich wichtiger ist. Auch sind beispielsweise bei NoSQL-Datenbanken wie Cassandra über Partition Keys oder MongoDB über Shards-Konzepte wie Sharding nativ integriert und müssen nicht extra auf Anwendungsebene nachgebaut werden.

Aufmacherbild: cloud computing concept von Shutterstock / Urheberrecht: rangizzz

[ header = Seite 2: Flexible Schemata und rasante Anpassungsfähigkeit ]

Flexible Schemata und rasante Anpassungsfähigkeit

Ein weiterer Trend, der sich am Markt bei Softwareherstellern beobachten lässt, ist der zunehmende Ruf nach schnellerer Anpassungsfähigkeit, ohne gleich die Kompatibilität zu unmittelbaren Vorgängerversionen zu brechen. Vor allem bei App-Entwicklern für Tablets und Phones, aber auch immer mehr bei Webentwicklern, findet man schnell Umsetzungen, die flexible Datenbankschemata implementieren. Hierbei könnten unter Umständen in einer Sammlung von Daten auch Datensätze mit unterschiedlichen Feldern enthalten sein (eventuell aus unterschiedlichen Versionen der Anwendung oder aus dynamisch angepassten Schemata durch Benutzer selbst).

In traditionellen RDBMS hat man derartige Anforderungen immer über komplizierte Workarounds gelöst: etwa eine Vielzahl von Nullable Columns, die dann kryptische Namen wie CustomField1 – CustomFieldX hatten oder komplexe XML-Columns, die dann aber wieder schwierig abzufragen waren. Und selbst kleine Änderungen des Schemas waren in Summe trotzdem wieder kompliziert, nachdem sie, wenn auch noch so klein, komplexe Migrationsstrategien erfordert haben.

Das ist also ein weiterer Trend, der NoSQL-Datenbanken zu mehr Beliebtheit verhilft. Viele NoSQL-Datenbanken gehen den Weg, dass sie selbst kein Schema mehr vorgeben und das Speichern unterschiedlicher Datenstrukturen in ein- und derselben Datensammlung zulassen (also etwa beispielsweise eine Tabelle mit Records, in der jeder Record aus verschiedenen Spalten besteht). Im Azure Table Storage [8], Amazon Dynamo [9], Google BigTable [10] oder etwa Apache Cassandra [11]können Tabellen enorme Ansammlungen an Zeilen mit jeweils unterschiedlichen Spalten beinhalten. So kann man mit Azure Table alle Daten für Kunden aus einem Bestimmten Land – von Kundendaten selbst mit beispielsweise deren Bestellungen – gemeinsam in ein und derselben Tabelle speichern. Das ist durchaus sinnvoll, wenn diese oft gemeinsam abgefragt und verwendet werden. Denn auf diese Weise können diese Daten ohne komplexe Joins eben gemeinsam in einem Query-Request abgefragt werden.

Abb. 2: Verschiedene Arten von doch zusammengehörigen Datensätzen in einer Table

Einfachere Entwicklung, andere Zugriffsmuster

Zuletzt bleibt noch der notwendige Entwicklungsaufwand für den Zugriff auf Datenbanksysteme. Dieser ist dank O/R Mapper für die meisten Entwickler relativ einfach geworden. Bilden O/R Mapper doch eine nette Brücke zwischen relationalen Datenbanken und der objektorientierten Welt im Code. Viele Entwickler sind jedoch der Meinung, dass man für wirklich gute Performance dann doch wieder native (also direkt mit IDbCommand und dergleichen) gegen die Datenbank gehen sollte. Wenn auch nicht immer, aber doch oft zu Recht. Diesen Mapping Layer könnte man sich sparen, wenn das Datenmodell näher am Anwendungsmodell liegen würde oder gar der Anwendungscode das Schema vorgibt und nicht die Datenbank. Ein Weg, den vor allem dokumentbasierte NoSQL-Datenbanken wie MongoDB [12] oder CouchDB [13] gehen. Dort werden Daten nämlich als hierarchische Objektmodelle gespeichert. In MongoDB wird sogar JSON als Repräsentation dieser „Dokumente“ herangezogen. Hier entfällt also ein Mapping von Datenmodell auf Anwendungsmodell unter Umständen komplett.

Ein weiterer Faktor wird ersichtlich, wenn man sich Graph Databases ansieht. Diese verfolgen das Prinzip, Daten in Form von Knoten und Beziehungen zu speichern. Abfragen gegen derartige Datenbanken erfolgen dann ebenfalls in Bezug auf Knoten und vor allem Beziehungen zwischen Knoten wie etwa „ich suche alle Freunde von Mario, die auch schon mal Dark Knight Rises gesehen haben“.

Abb. 3: Schematische Darstellung einer Graph Database

Neo4j ist ein sehr bekanntes Beispiel einer derartigen Graph Database. Neo4j verfügt dabei über eine eigene Query Language namens Cypher, die auf knoten-/beziehungsorientierte Abfragen optimiert ist, wie nachfolgendes Beispiel zeigt:

START p1 = node(*)
MATCH p1-[r1:FRIEND]-(friend)-[r2:WATCHED]->(movie)
WHERE p1.Country = 'Austria' AND movie.title = 'Batman'
RETURN p1.Nickname, friend.Nickname

In dieser Abfrage werden alle Personen gesucht, die Freunde haben, die einen Film mit dem Titel Batman geschaut haben. Eine derartige Abfrage ist natürlich auch mit RDBMS möglich, aber weder so elegant noch mit einer derart hohen Performance wie diese mit einer auf solche Abfragen optimierten Datenbank wie Neo4j möglich ist.

Windows Azure und NoSQL

Wir wissen nun, warum NoSQL immer mehr zum Thema wird. Außerdem habe ich festgestellt, dass die Beliebtheit von NoSQL DBs vor allem in Public-Cloud-Systemen häufiger zum Vorschein kommt. Daher sehen wir uns jetzt an, wie es bei Windows Azure um NoSQL DBs steht. Für mich ist dabei immer eine Frage wichtig: Was bietet die Plattform als fertigen Softwareservice an, und was muss man selbst in Virtual Machines oder als automatisch betriebenen Cloud-Service (Web/Worker) betreiben. Tabelle 1 gibt einen Überblick über einige (nicht alle) NoSQL-Datebanken im Zusammenhang mit Windows Azure.

Datenbank Fertiger Plattformservice Betrieb in Azure (VM, Web/Worker)
Azure Table Storage Ja Nein
Apache Hadoop Ja [15] (Azure HDInsight) Virtual Machines
MongoDB Ja (mongolab.com) Virtual Machines (oder Web/Worker*) [18]
Apache Cassandra Nein Virtual Machines
RavenDB [14] Nein, [17] (in Arbeit durch RavenHQ) Virtual Machines (oder Web/Worker*) [19]
CouchDB Nein Virtual Machines
Neo4j Nein Virtual Machines
Redis Ja [21], (garantiadata.com Virtual Machines (oder Web/Worker*) [20]

Tabelle 1: Einige NoSQL-Datenbanken und Windows Azure

Wie Tabelle 1 zeigt, gibt es einige NoSQL-Datenbanken bereits als fertige Plattformservices, entweder als Bestandteil von Windows Azure selbst, wie im Falle von Hadoop mit Windows Azure HDInsight, oder von Drittherstellern angeboten, wie etwa MongoDB von mongolab.com. Der Vorteil eines fertig angebotenen Service besteht im Wesentlichen darin, dass man sich in keiner Weise selbst um irgendeine Infrastruktur kümmern muss. Man legt einfach Datenbanken über ein Serviceportal an, bekommt Zugangsdaten für eigene Anwendungen, die etwa als Verbindungszeichenfolgen verwendet werden und kann loslegen. Abbildung 4 zeigt dies anhand des Beispiels MongoLab mit einer MongoDB-Datenbank.

Abb. 4: MongoDB as a Service mit MongoLab

Optimal ist es natürlich, wenn es für eine Datenbank, ob RDBMS oder NoSQL, einen derartigen Service gibt. Im RDBMS-Umfeld gibt es für Azure in diesem Bereich z. B. Azure SQL DB [23] oder für MySQL-Fans auch MySQL as a Service von ClearDB [24]

Die nächste Option wäre dann der Betrieb in Windows Azure Platform as a Service, also Web/Worker Roles als Cloud-Service. Warum so und nicht gleich als Virtual Machines? Nun, ganz einfach, im Falle von Web/Worker Roles kümmert sich Windows Azure um das Management der Betriebssysteme. Das heißt, wir müssen uns selbst nicht mit Themen wie OS Patching und Updates beschäftigen, was Zeit und damit auch Geld spart. Für einige Datenbanken gibt es diesbezüglich Anleitungen, wie man diese in Windows Azure Web/Worker Roles betreiben kann. Meist funktioniert das Ganze dann auch im Zusammenhang mit Windows Azure Drive [25], also einer Möglichkeit, eine Virtual Hard Disk (VHD) als persistente Festplatte an eine Web/Worker Role anzubinden, sodass Daten auf dieser persistent im Azure BLOB Storage gehalten werden. Das würde ich allerdings niemandem empfehlen, da Windows Azure Drive noch immer im Previewstadium ist und aller Voraussicht nach durch eine Alternative abgelöst wird, die ähnlich funktioniert, wie VHDs in Azure Virtual Machines. Vom Azure-Team gibt es dazu allerdings noch keine Details. Wem allerdings das automatische Management wichtiger ist, als das Risiko des Einsatzes einer Previewtechnologie – nur zu, es funktioniert auf jeden Fall und MS Open Tech hat sogar über die letzten Jahre einige Open Source Packages veröffentlicht, die als Beispielimplementierung derartiger Umsetzungen herangezogen werden können.

Die letzte Option für den Betrieb von NoSQL-Datenbanken in Windows Azure sind dann noch Virtual Machines. Grundsätzlich funktioniert das Einrichten der NoSQL-Datenbanken in diesem Fall genauso, wie auch auf eigenen Servern. Allerdings gibt es in Azure dabei einige Aspekte zu beachten:

  • Einrichtung eines Virtual Networks
  • Einsatz von Availability Sets
  • OS Tweaks und Tunings

[ header = Seite 3: Virtual Networks ]

Virtual Networks

Viele NoSQL DBs beginnen erst so richtig zu glänzen, wenn man ihre Replikations- und Sharding-Funktionen einsetzt. Dafür benötigt man dann aber natürlich mehrere Virtual-Machine-Instanzen. Zudem sollen diese dann auch den Anwendungen wie etwa Webanwendungen oder/und Web-APIs zur Verfügung gestellt werden. Um all diese Komponenten miteinander zu verbinden, empfiehlt sich die Einrichtung eines Virtual Networks über das Azure-Management-Portal oder über eine der Command-Line-Optionen (Azure PowerShell [26] oder Azure Cross Platform Commad Line Interface [27]). Abbildung 5 zeigt ein derartiges Netzwerk mit mehreren Virtual Machines, die sogar in unterschiedlichen Cloud-Services laufen können.

Abb. 5: Ein Virtual Network mit Virtual Machines aus verschiedenen Cloud-Services

In ein derartiges Virtual Network können Sie auch Cloud-Services mit Web- und Worker-Roles hinzufügen, sodass diese dann als Bestandteil der Anwendung direkt auf ihre MongoDB, Cassandra oder andere Nodes zugreifen können. Außerdem bekommen ihre VMs innerhalb eines Virtual Networks IP-Adressen zugeordnet, die sich nicht mehr ändern, solange Sie die Maschine nicht entweder löschen oder über das Windows-Azure-Management-Portal oder das Service-Management-API explizit herunterfahren (und damit Deallozieren, sodass nichts verrechnet wird). Gleichbleibende IP-Adressen sind für viele NoSQL-Systeme wie etwa MongoDB sehr hilfreich, da Mongo beispielsweise Knoten in einem Replicaset entweder über einen DNS oder über die Hosts-Datei des Betriebssystems mit einem Namen (anstatt der IP-Adresse) auflösen können muss (lt. mongodb.org).

Availability Sets

Als Nächstes ist es äußerst wichtig, dass Sie beim Betrieb Ihrer Virtual Machines von Availability Sets Gebrauch machen. Azure stellt sicher, dass alle Virtual Machines, die dem gleichen Availabiltiy Set zugeordnet sind, in verschiedenen „Fault Domains“ [28] betrieben werden. Eine Fault Domain zeichnet sich durch einem Single-Point-of-Failure in einem Azure-Rechenzentrum aus. Ein Server-Rack ist etwa in vielen Rechenzentren eine Fault Domain, da die Maschinen eines Racks über einen gemeinsamen Netzwerkrouter mit dem Rest des Rechenzentrums verbunden sind. Durch eine Aufteilung der Maschinen auf mehrere Fault Domains wird erreicht, dass ein Fehler in einer Fault Domain nicht zum Komplettausfall des gesamten Clusters führt. Microsoft gewährt bei Virtual Machines auch nur ein SLA (in Höhe von 99,95 Prozent), wenn Virtual Machines in einem Availabiltiy Set mit mindestens zwei VMs/Availability Set betrieben werden. Abbildung 6 zeigt die Konfiguration eines Availability Sets für Virtual Machines mit einem Beispielcluster, der über zwei Fault Domains und drei Update-Domains hinweg vom Azure Fabric Controller gemanaged wird.

Abb. 6: Korrekter Einsatz von Availability Sets in Azure

Eine weitere, wichtige Erkenntnis aus Abbildung 6 sind die so genannten Update-Domains. Windows Azure muss natürlich auch die zugrunde liegenden Hostbetriebssysteme, welche die VMs betreiben, aktualisieren. Dafür muss die VM runtergefahren werden, wenn ein Reboot des Hostsystems notwendig ist. Update-Domains stellen sicher, dass dies für VMs innerhalb eines Availability Sets nicht gleichzeitig passiert, sondern nacheinander, sodass der gesamte Service aufgrund eines Updatezyklus nicht komplett ausfällt, sondern weiterhin verfügbar bleibt. Sie sehen also, der Einsatz von Availability Sets ist unbedingt notwendig für den ausfallsicheren Betrieb eines Systems – und umso wichtiger für den stabilen Betrieb eines Datenbankclusters, egal ob RDBMS oder NoSQL.

OS Tweaks und Tunings

Hier sind zwei Punkte aus meiner Erfahrung wichtig: die Wahl des Betriebssystems und die korrekte Konfiguration von Data Disks. Beginnen wir mit Ersterem, der Wahl des Betriebssystems. Sie sollten unbedingt in Azure (und nicht lokal) testen, mit welchem Betriebssystem (insbesondere Linux oder Windows) sich die NoSQL-Datenbank besser (schneller) verhält. Ein Beispiel aus der Praxis aus einem Projekt mit einem meinen Softwareherstellerpartner in Spanien mit MongoDB: sowohl unter Windows als auch Linux konnten wir grundsätzlich gute Write-Performance mit MongoDB in Azure erzielen. Allerdings kam es mit steigender Anzahl der Records in einer Mongo Collection ab 20 Millionen Records alle paar Minuten zu massiven Ausreißern was die Performance betrifft – unter Windows. Nach umfangreichen Tests hat sich herausgestellt, dass MongoDB standardmäßig in regelmäßigen Abständen eine so genannte fsync-Operation ausführt. Diese führt die Daten aus einem Journal, eine Art Commit-Log, in die eigentlichen Data Files über. Unter Windows ist diese Operation im Falle von MongoDB leider synchron implementiert während sie unter Linux (CentOS war Bestandteil unserer Tests) diese Operation asynchron funktioniert. Das heißt unter Windows wurde der komplette MongoDB-Prozess für die Zeitdauer dieser Operation einfach alle paar Minuten blockiert, was zu Delays in der Verarbeitung geführt hat. In diesem Fall gehen wir nun also den Weg, MongoDB in Windows Azure Virtual Machines mit Linux CentOS als Guest OS zu betreiben. Kern der Geschichte: Testen Sie die von Ihnen angestrebte NoSQL-Datenbank unter Azure VMs mit verschiedenen Betriebssystemversionen und -typen und wählen Sie dann jene, mit der Sie die für Ihre Situation besten Ergebnisse erzielt haben.

Der zweite Punkt ist eine passende Konfiguration von Data Disks. Zunächst sollten Sie Ihre Daten immer in Data Disks und nicht auf den Operating System Disks ablegen. Data Disks können wesentlich größer werden und haben zuverlässigere Standarddateisystem-Cache-Optionen voreingestellt. Meist empfiehlt es sich auch, mehrere Data Disks an jede einzelne VM anzuhängen, um die Schreib-/Lesegeschwindigkeit (IOPS) zu verbessern. Auch hier hängt es wiederum davon ab, die Disks in Abhängigkeit von Details in Bezug auf die verwendete NoSQL DB zu optimieren und nicht einfach standardmäßig immer das größte RAID Stripe einzurichten.

Bei MongoDB habe ich etwa gute Erfahrungen mit RAID-Stripe-Set-ups unter Linux CentOS mit vier Data Disks über den Logical Volume Manager (LVM) gemacht. Bei Apache Cassandra wurde die Read-Performance mit RAID Stripes und zunehmender Anzahl von Disks eher schlechter, da ein Read dann Disk Scans von unter Umständen allen Disks des RAID-Verbunds mit sich bringt. Bei Systemen, die eine manuelle Aufteilung der Data Files auf die Data Disks erlauben, ist unter Umständen überhaupt von einem RAID-Stripe-Verbund abzusehen. Unter Windows beispielsweise ist es in Azure besser, Storage Pools oder manuelle Aufteilung von Data Files auf Data Disks durchzuführen, anstatt den NTFS-Software-RAID-Stripe-Mechanismus zu verwenden.

Außerdem sollten Sie die Read/Write-Cache-Optionen auf das Verhalten ihrer NoSQL DB abstimmen. Im Falle von MongoDB hat sich beispielsweise der ReadAhead-Cache des Filesystems und der Azure Data Disks als suboptimal herausgestellt und wir konnten in unserem konkreten Fall die beste Performance durch Deaktivierung des Data-Disk-Cache im Portal und in Betriebssystemebene erreichen.

Diese letzten Optimierungen sollten Sie unbedingt durchführen. Auch wenn es auf den ersten Blick etwas aufwändig klingt, dieser Aufwand lohnt sich später und für die Zukunft. Es sei auch ganz klar gesagt, dass unterschiedliche Rahmenbedingungen und Systeme zu anderen Erkenntnissen als den oben genannten führen können. Daher sollte man auf jeden Fall ein wenig Zeit in Performancetests investieren, wenn man den Einsatz eines NoSQL-DB-Systems auf Azure (oder auch anderen Plattformen) plant.

Zum Abschluss – Polyglot Persistence

Dies waren erste Gedanken rund um NoSQL und vor allem NoSQL im Zusammenhang mit Windows Azure. NoSQL-Datenbanken bergen auf jeden Fall großes Potenzial in sich, meiner Meinung nach aus zwei Gründen. Erstens sind viele NoSQL-Datenbanken mit der Idee, die Eigenschaften Konsistenz, Skalierbarkeit und Verfügbarkeit gemeinsam mit Performance entsprechend priorisieren zu können, um auf diese Weise Abstriche in einem Bereich für Benefits in einem anderen Bereich leichter erreichen zu können. Zweitens gibt es einige gute Beispiele für NoSQL-Datenbanken, die sich auf sehr spezielle Arten von Anwendungen konzentrieren, wie etwa Graph Databases. Doch all das zeigt genau eines: Sowohl verschiedene NoSQL DBs als auch traditionelle RDBMS haben klare Stärken, die sie in bestimmten Bereichen ausspielen können, aber auch Schwächen in anderen Bereichen. Und genau dort können sie sich unter Umständen wiederum ergänzen.

Betrachten Sie also die Frage nach NoSQL oder RDBMS nicht als „entweder/oder“, sondern erwägen Sie auch Mischformen von Architekturen, in denen die entsprechenden Datenbanken genau dort eingesetzt werden, wo sie ihre Stärken ausspielen können, um in anderen Bereichen für andere Datenbanksysteme Platz zu machen. In diesem Fall sprechen wir von Polyglot Persistence. Falls es Sie interessiert, dann werfen Sie doch einen Blick auf ein Projekt, an dem ich gemeinsam mit einigen Kollegen aus unserem Team beteiligt war, welches dieses Konzept auf den Punkt bringt und demonstriert: Cloud Ninja Polyglot Persistence (http://cn2p.codeplex.com/). In diesem Projekt haben wir verschiedene Varianten von NoSQL-Datenbanken und auch traditionelle RDBMS-Datenbanken für die Lösung eines bekannten Problems eingesetzt – den guten, alten Retail Store (also ein Shopsystem). Viel Spaß beim Schmökern und mit dem Einstieg in eine total spannende, neue und offene Welt von modernen, skalierbaren Datenbanklösungen!

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -