Apache CouchDB ist eine neue Art von Datenbank System. In diesem Kapitel beschreiben wir zunächst, warum es einen Bedarf für solche Systeme gibt. Anschließend gehen wir auf die Motivation ein, die hinter der Entwicklung von CouchDB steckt.
Als CouchDB Entwickler haben wir selbstverständlicherweise ein starkes Interesse daran, CouchDB zu benutzen. Wir möchten erzählen, was uns an CouchDB begeistert. Wir werden zeigen, warum das schemafreie Dokumenten Modell von CouchDB besser für die heute üblichen Anwendungen geeignet ist, warum die eingebaute Query-Engine ein guter Weg ist, die gespeicherten Daten zu lesen und zu verarbeiten und wie das Design von CouchDB Modularisierung und Skalierbarkeit fördert.
Falls man CouchDB mit einem Begriff beschreiben müsste, so ist es Entspann Dich. Es ist der Titel dieses Buches, die Byline von CouchDBs offiziellem Logo und wenn man CouchDB startet, steht dort:
Apache CouchDB has started. Time to relax.
Warum ist Entspannung wichtig? Die Produktivität von Entwicklern hat sich in den letzten fünf Jahren verdoppelt. Für diesen Schub sind hauptsächlich bessere Tools, die gleichzeitig einfacher zu bedienen sind, verantwortlich. Wenn man "Ruby on Rails" als Beispiel nimmt, so sieht man ein unendlich komplexes Framework mit dem der Einstieg jedoch sehr leicht ist. Rails ist eine Erfolgsgeschichte weil das Hauptziel der Entwicklung auf der einfachen Bedienung lag. Das ist einer der Gründe, warum CouchDB entspannend ist. Das Verstehen der Grundkonzepte von CouchDB fühlt sich für jeden natürlich an, der in irgendeiner Form mit dem Web arbeitet. Selbst nicht-technischen Leuten ist es relativ einfach zu vermitteln.
Nicht im Weg zu stehen, wenn kreative Menschen versuchen ein Problem zu lösen, ist eine der wichtigsten Eigenschaften — eine, die CouchDB versucht gut erfüllen. Für uns waren die bestehenden Tools zu schwerfällig — sowohl während der Entwicklung als auch während des Betriebs. Deshalb haben wir uns darauf konzentriert, CouchDB so einfach wie möglich zu halten und es spielend leicht bedienen zu können. Kapitel 3 und Kapitel 4 zeigen das intuitive HTTP basierte REST API.
Ein weiterer Bereich der Entspannung ist der Produktivbetrieb. Im Zusammenspiel mit einer Anwendung, die von echten Benutzern benutzt wird, versucht CouchDB sein Möglichstes, um den Administrator in Ruhe zu lassen. Die interne Architektur ist fehlertolerant, Ausnahmen finden in einer kontrollierten Umgebung statt und werden ordentlich bearbeitet. Einzelne Fehler rauschen nicht durch das ganze System nach oben durch sondern bleiben auf den einen Request beschränkt.
Die Konzepte von CouchDB sind einfach, aber dennoch mächtig und gut dokumentiert. Das Produktionsteam (falls es ein Team gibt, andernfalls sind das sie) brauchen sich keine Sorgen vor unvorhersagbarem Verhalten und schwer nachvollziehbaren Fehlern zu machen. Falls etwas schief gehen sollte, kann man einfach herausfinden, wo das Problem liegt — doch diese Fälle sind selten.
CouchDB ist von Anfang an darauf ausgelegt, mit wechselnder Last intelligent umzugehen. Sollte eine Webseite schlagartig viele Requests bekommen, wird CouchDB sie einfach weiter beantworten ohne einen zu vergessen. Es mag unter Last etwas länger dauern, aber alle bekommen eine Antwort. Sobald der Ansturm vorüber ist, antwortet CouchDB wieder mit gewohnter Geschwindigkeit.
Der dritte Bereich der Entspannung sind wechselnde Hardware Anforderungen ihrer Anwendung. Das wird üblicherweise als Skalierung bezeichnet. CouchDB setzt dem Programmierer Grenzen. Das mag auf den ersten Blick unflexibel erscheinen, doch manche Funktionen wurden ganz bewusst weggelassen, weil mit ihnen der Programmierer in der Lage gewesen wäre, Anwendungen zu schreiben, die nicht skalieren. Das Thema Skalierung von CouchDB wird in Teil IV: Deploying CouchDB ausführlich behandelt.
Kurz gesagt: CouchDB erlaubt keine Dinge, die nachher Ärger machen. Das kann bedeuten, dass man alte Gewohnheiten über Bord werfen muß. In Kapitel 24 Rezepte finden sich eine Liste von üblichen Aufgaben und wie man sie mit CouchDB löst.
Wir glauben das CouchDB die Art, wie dokumentenbasierte Anwendungen gebaut werden, verändern wird. CouchDB verbindet ein intuitives Modell zum Speichern von Dokumenten kombiniert mit einer mächtigen Query-Engine, die so einfach ist, dass man sich fragt, warum das erst jetzt entwickelt wurde.
Django mag für das Web gebaut worden sein, doch CouchDB ist auf dem Web gebaut. Ich habe bisher noch keine Software gesehen, welche die Philosophien von HTTP so vollständig umgesetzt hat. CouchDB lässt Django alt aussehen — genauso wie Django ASP hat alt aussehen lassen.
—Jacob Kaplan-Moss, Django Entwickler
Das Design von CouchDB ist stark an bestehende Web Architekturen und den Konzepten von Resourcen, Methoden und Darstellungen angelehnt. Es kombiniert sie in mächtiger Weise um Daten zu suchen, abzubilden, zu kombinieren und zu filtern. Hinzu kommen Fehlertoleranz, extreme Skalierbarkeit und inkrementelle Replikation. Damit definiert CouchDB genau den Sweet Spot für dokumentenbasierte Datenbanken.
Wir schreiben Software, um unser Leben und das Leben anderer zu erleichtern. Dazu verwenden wir meistens einfache Informationen wie Kontakte, Rechnungen oder Quittungen und verarbeiten sie mithilfe von Computer Software. CouchDB ist ein guter Partner für solche Anwendungen, denn es arbeitet mit der natürlichen Idee von in sich abgeschlossenen Dokumenten, die alle notwendigen Informationen enthalten und mit der Zeit fortgeschrieben werden.
Eine Rechnung enthält alle notwendigen Informationen über einen einzelnen Vorgang. Den Verkäufer, den Käufer, das Datum und eine Auflistung der Dinge oder Dienste, die verkauft wurden. Wie in Abbildung 1 „In sich abgeschlossene Dokumente“ zu sehen ist, gibt es keine abstrakten Referenzen auf dem Stück Papier, die zu einem anderen Stück Papier verweisen, zum Beispiel mit dem Namen und der Adresse des Verkäufers. Buchhalter wissen es zu schätzen, alle Informationen auf einen Blick zu haben. Falls sie die Möglichkeit haben, bevorzugen Programmierer das auch.
Doch genau mit solchen Referenzen werden Daten in relationalen Datenbanken modelliert. Jede Rechnung wird als Zeile in einer Tabelle gespeichert. Diese Zeile verweist auf andere Zeilen in anderen Tabellen — eine für den Käufer, eine für den Verkäufer, eine für jedes Teil was verkauft wurde und noch mehr Zeilen, die wiederum die verkauften Teile genauer beschreiben.
Damit soll der Wert von relationalen Modellen nicht geschmälert werden. Sie sind in vielen Anwendungen im Einsatz und haben sich aus verschiedenen Gründen als sehr nützlich erwiesen. Das vorangegange Beispiel soll zeigen, dass manche Modelle sich nicht so gut für die Daten der realen Welt eignen.
Schauen wir auf eine einfache Adressdatenbank um einen anderen Ansatz zur Modellierung von Daten zu illustrieren. Dazu kann man sich einen Stapel Visitenkarten vorstellen. Genau wie das Beispiel mit der Rechnung enthält eine Visitenkarte alle wichtigen Informationen auf einen Blick. Wir nennen das „in sich abgeschlossene Daten“ und es ist ein wichtiges Konzept beim Verständnis von dokumentenbasierten Datenbanken wie CouchDB.
Die meisten Visitenkarten enthalten ungefähr die gleichen Informationen: den Namen, vielleicht ein Firmenname und Kontaktinformationen. Obwohl die Daten zwischen den einzelnen Karten differieren kann, ist doch das allgemeine Schema immer gleich und Menschen haben keine Schwierigkeiten damit Visitenkarten als solche zu erkennen. So gesehen kann man eine Visitenkarte als ein reales Dokument bezeichnen.
Jan hat vielleicht eine Telefonnummer aber keine FAX Nummer auf seiner Visitenkarte. Dagegen enthält die Karte von J. Chris beide Nummern. Jan muss das Fehlen einer FAX Nummer nicht umständlich und explizit durch „Fax: Nicht vorhanden“ ausdrücken. Durch einfaches Weglassen der FAX Nummer gibt er zu verstehen, dass er keins hat.
Reale Dokumente des gleichen Typs, so wie Visitenkarten, neigen dazu in ihrer Semantik — die Art der Information — sehr ähnlich zu sein. Ihre Syntax oder wie die Information tatsächlich aufgebaut ist, kann jedoch zwischen den einzelnen Karten sehr unterschiedlich sein. Menschen haben damit kein Problem. Für uns sind diese Variationen normal.
Während ein traditionelles relationales Datenbank System erfordert, dass man die Daten im voraus durch ein Schema strukturiert, erlaubt das schema-freie Design von CouchDB die Daten erst nach dem Eintrag in die Datenbank zu strukturieren. Genauso wie man es auch mit realen Dokumenten macht. Wie man mit diesem Ansatz Anwendungen zur Speicherung von Daten entwickelt, wird im folgenden Abschnitt genauer erläutert.
CouchDB ist ein Speichersystem, das für sich allein genommen schon recht nützlich ist. Man kann viele Anwendungen mit den Werkzeugen bauen, die CouchDB bietet. Doch die Vision von CouchDB ist größer. Seine Bestandteile können als Bausteine für große Systeme benutzt werden, um Speicherprobleme für immer stärker wachsende Anwendungen zu lösen.
Ob ein System unglaublich schnell sein muss, Zuverlässigkeit aber nicht allzu wichtig ist (z.B. für Logging), oder ein System Schreiboperationen in zwei verschiedenen, geografisch getrennten Systemen garantieren muss und die damit verbundene höhere Antwortzeit akzeptabel ist — CouchDB erlaubt es solche Systeme zu bauen.
Meist gibt es viele Knöpfe an denen man drehen kann, um ein System zu optimieren. Doch hat der positive Effekt in der Regel auch unerwünschte Nebenwirkungen. Ein Beispiel ist das CAP Theorem, das im nächsten Kapiel ausführlicher behandelt wird. Andere Parameter, die Datenspeichersysteme in der Regel beeinflussen, werden in Abbildung 2 und Abbildung 3 gezeigt.
Reduziert man die Latenz eines Systems, so hat das Auswirkungen auf die Parallelität und den Durchsatz. Das gilt im übrigen nicht nur für Speichersysteme.
Wenn eine Anwendung nach oben skaliert werden soll, muss man drei Faktoren der Skalierung berücksichtigen: die der Leseoperationen, die der Schreiboperationen und die der Daten. Orthogonal zu allen dreien und zu den Parametern aus Abbildung 2 sind viele weitere Parameter wie Zuverlässigkeit und Einfachheit. Man kann viele solcher Graphen zeichnen, die zeigen das verschiedene Funktionen und Eigenschaften das System in eine bestimmte Richtung ziehen oder schieben und damit das System neu formen.
CouchDB ist sehr flexibel und bietet genügend Bausteine um ein System zu bauen, dass auf die aktuellen Anforderungen exakt zugeschnitten ist. Das bedeutet nicht, dass CouchDB eine Eierlegende Wollmilchsau ist, mit der man jedes Datenbank Problem lösen kann, aber man kommt schon sehr weit damit.
Die Replikation von CouchDB ist einer dieser Bausteine. Seine primäre Aufgabe ist die Synchronisation von zwei oder mehr CouchDB Datenbanken. Das mag einfach klingen, doch die Einfachheit ist der Schlüssel um mit der Replikation verschiedene Probleme zu lösen: — Zuverlässige Synchronisation von Datenbanken auf verschiedenen Maschinen um Daten redundant zu speichern — Verteilung der Daten über einen Cluster von CouchDB Instanzen, die jeweils einen Teil der Requests beantworten (Lastverteilung) und Spiegelung der Daten über geografisch weit verteilte Standort wie beispielsweise New York und Tokyo.
Die Replikation von CouchDB benutzt dabei das selbe REST API, das alle anderen Clients auch benutzen. HTTP ist allgegenwärtig und sein Verhalten ist bekannt. Die Replikation von CouchDB arbeitet inkrementell. Das bedeutet, das falls während der Replikation etwas schief geht — weil beispielsweise eine Netzwerkverbindung verschwindet — wird CouchDB genau dort wieder weiter machen, wo es aufgehört hat. Es werden auch nur die Daten übertragen, die notwendig sind, um die Datenbanken zu synchronisieren.
Eine der Grundannahmen in CouchDB ist, das Fehler auftreten werden. CouchDB ist darauf ausgerichtet, Fehler vernünftig zu behandeln anstatt anzunehmen, es wird keine geben. Das inkrementelle Design der Replikation zeigt das am Besten. Die Ideen hinter „Fehler werden passieren“ sind in den Irrtümern der verteilten Datenverarbeitung aufgelistet:
Bestehende Werkzeuge versuchen oft zu verstecken, dass es ein Netzwerk gibt und das eine oder alle der oben genannten Dinge für das aktuelle System nicht zutreffen. Das Ergebnis ist oft genug eine fatale Situation wenn Dinge letzendlich doch schief gehen. CouchDB versucht im Gegenteil gar nicht erst das Netzwerk zu abstrahieren, sondern Fehler vernünftig zu behandeln und den Administrator zu benachrichtigen, wenn das nicht möglich ist.
CouchDB hat viele Lehren aus dem Web gezogen, doch eine Sache wäre gut für das Web: weniger Latenz. Wenn auch immer man auf eine Anwendung warten oder auf eine Webseite warten muss, so ist meist eine Netzwerkverbindung nicht so schnell, wie es gerade erforderlich wäre. Antwortzeiten von ein paar Sekunden anstelle von Millisekunden haben einen großen Effekt auf die User Experience und die Zufriedenheit der Anwender mit dem System als Ganzem.
Was macht man, wenn man offline ist? Das passiert ständig trotz DSL und Kabel Anschluss. Was ist mit dem iPhone, dem G1 oder dem Blackberry, wenn kein Empfang ist? Keine Verbindung bedeutet nicht an die Daten zu kommen.
CouchDB kann in solchen Fällen helfen und in dieser Situation ist Skalierung auch wichtig. Diesmal allerdings in die andere Richtung — nämlich nach unten. Warum nicht eine CouchDB Instanz auf einem Smartphone, die sich mit anderen CouchDB Instanzen synchronisiert, wenn eine Verbindung besteht? Die Synchronisation ist nicht nur sinnvoll für schnelle Benutzerschnittstellen. Es ist einfacher ein System auf hohe Bandbreite und hohe Latenz zu optimieren, als für geringe Bandbreite und geringe Latenz. Mobile Anwendung können anschließend die Daten in der lokalen CouchDB Instanz benutzen und weil die Daten lokal sind, ist die Latenz per Definition gering.
Kann man CouchDB wirklich auf einem Smartphone einsetzen? Erlang, die Sprache in der CouchDB geschrieben ist, wurde für viel kleinere und viel schwächere Geräte als die heute verfügbaren entwickelt und auch eingesetzt.
Das nächste Kapitel zeigt die verteilte Natur von CouchDB. Das letzte Kapitel sollte genug Interessantes enthalten haben, um weiterzulesen. Auf geht's!