Uberblick ¨uber NoSQL Datenbanken

Werbung
1
Überblick über NoSQL Datenbanken
Seminararbeit Software Systems Engineering - WS 2012 / 2013
Mario David - Student - Master Informatik (SSE)
Universität zu Lübeck
Zusammenfassung—Diese
Seminararbeit
umfasst
die
Einführung, die theoretischen Grundlagen, eine Taxonomie sowie
einige exemplarische Beispiele aus dem Bereich von NoSQL
Datenbanken. Nach einer Einführung der Begriffe sowie einer
Motivation von dem relationalen Modell abzurücken wird u.a.
auf das CAP-Theorem als theoretische Grundlage eingegangen.
Desweiteren werden verschiedene NoSQL Datenbanken
kategorisiert und diese Kategorien einzeln beschrieben.
Dabei werden die beiden Datenbankmanagementsysteme Riak
und CouchDB in ihren Grundzügen vorgestellt und deren
jeweilige Vorzüge herausgearbeitet. Abschließend wird eine
Zusammenfassung gegeben, die beschreibt wo die KernUnterscheide zu RDBM-Systemen bestehen.
Index Terms—NoSQL, Taxonomy, Key-Value-Stores, CAPTheorem, document oriented databases, Riak, CouchDB
I. E INF ÜHRUNG IN N O SQL
Der Begriff NoSQL (not only SQL) beschreibt, statt einer
konkreten Technologie, verschiedenste Ansätze im Bereich
Persistenz. Diese Technologien besitzen als kleinsten gemeinsamen Nenner die Eigenschaft, nicht auf dem relationalen
Datenbankmodell aufzubauen.
Das relationale Datenbankmodell beruht im Wesentlichen
auf Entitäten, dies entspricht einer Tabelle mit Spalten und
Zeilen, und Relationen, also Beziehungen zwischen diesen
Entitäten. Zusätzlich besitzen bieten relationale Datenbanksysteme unter dem Akronym ACID eine starke Konsistenz für
Transaktionen. Diese Eigenschaft lässt sich nur schlecht mit
einer Anforderung nach horizontaler Skalierung vereinbahren,
da um Konsistenz über mehrere Knoten zu gewährleisten ein
großer Kommunikationsaufwand betrieben werden muss.
Es gibt allerdings noch weitere Faktoren, die eine Motivation sein können, von dem relationalen Modell Abstand zu
nehmen:
•
•
•
•
B. Einsatz von NoSQL Datenbanken
NoSQL Datenbanken konzentrieren sich in den meisten
Fällen auf einen Teilaspekt, wie bspw. Skalierbarkeit oder
auch ein ausgeprägtes Datenmodell. Durch diese Spezialisierung bzw. diesen Kompromiss ist der Einsatz einer NoSQL
Datenbank immer nur in Teilbereichen eines Gesamtsystems
zu evaluieren. Auch relationale Datenbanken haben Vorteile,
wie z.B. die Transaktionsfähigkeit oder den hohen Standardisierungsgrad der Abfragesprache (SQL). Daher ist der Einsatz
von NoSQL Technologien häufig auch als Zu- und nicht Ersatz
für bereits bestehende Datenbanksysteme zu sehen.
C. Kategorien im nicht relationalen Umfeld
Wie bereits angesprochen gibt es viele verschiedene Arten
von Datenbanken, die alle unter dem Schlagwort NoSQL
zusammengefasst werden. Diese lassen sich in verschiedene
Kategorien unterteilen:
•
•
•
A. Motivation für nicht relationale Datenbanksysteme
Diese sogenannte horizontale Skalierung (“Scale Out” Skalierung über mehrere Computer) ist häufig Voraussetzung
für Applikationen, die das Nutzeraufkommen mittelfristig
schlecht abschätzen können (Facebook, Google, Twitter, usw.).
Man spricht in diesem Zusammenhang auch von “InternetScale Systems”. Traditionelle relationale Datenbanken skalieren üblicherweise vertikal (“Scale-Up”), sprich: ein Computer
wird mit entsprechend größerer Hardware ausgestattet, um
steigenden Anforderungen weiterhin zu genügen. Diese Art
der Skalierung funktioniert gut für Applikationen, bei denen
das Nutzeraufkommen ein gewisses Maß an Elastizität nicht
übersteigt. Existieren allerdings Skalierungsanforderungen wie
die oben genannten, so lässt sich diese Art der Datenbankskalierung sowohl aus technischen, als auch als Kostengründen
nicht durchführen.
kein Zwang für ein fest definiertes Schema der Datenbank
Hochverfügbarkeit
Kostenvorteile bei Scale Out gegenüber Scale Up
neuartige Abfragemethoden (bspw. Map Reduce)
•
Key-Value Stores
Spaltenorientierte Datenbanken
Dokumentenorientierte Datenbanken
Graphendatenbanken
Die meisten Datenbanken, die dem Begriff NoSQL zugeordnet werden, lassen sich einer dieser Kategorien zuordnen. In
den nachfolgenden Kapiteln wird auf die einzelnen Kategorien
detailliert eingegangen und ggf. eine Datenbank aus dieser
Kategorie näher betrachtet. Zuvor wird jedoch auf verschiedene theoretische Grundlagen eingegangen, die alle der NoSQL
Datenbanken gemeinsam betreffen.
II. T HEORETISCHE G RUNDLAGEN
In diesem Kapitel werden verschiedene theoretische Grundlagen besprochen, die viele der Vorteile einer NoSQL Datenbank überhaupt erst ermöglichen. Desweiteren wird noch
auf das sogenannte CAP-Theorem eingegangen, welches eine
theoretische Basis für alle verteilten Systeme darstellt.
2
A. Horizontale Skalierung durch Sharding und Replikation
Die Möglichkeit horizontal über mehrere Knoten zu skalieren verdanken viele NoSQL Datenbanken dem sogenannten
Sharding. Bei dieser Technologie werden die zu persistierenden Daten horizontal über verschiedene Knoten partitioniert.
Ein Beispiel für eine solche (auch wenn nicht gerade sinnvolle)
Partitionierung ist, die gespeicherten Kundeninformationen
anhand des ersten Buchstabens des Namens auf 26 ClusterKnoten einer NoSQL Datenbank zu verteilen.
Ein wichtiger Aspekt ist hierbei, dass die einzelnen Knoten im Cluster Anfragen lokal beantworten können müssen.
Ansonsten würden Join-Operationen über verschiedene Knoten stattfinden, wodurch die angestrebte Skalierbarkeit negativ beeinflusst wird. Diese lokale Anfragenbearbeitung wird
häufig über Replikation und de-normalisierte Daten gelöst.
Statt auf einen genauen Schnitt der Daten, bei dem exakt
jeder Datensatz einem Knoten zugeordnet ist, zu setzen, werden die Daten dazu auf mehreren Knoten vorgehalten, um
lokale Verarbeitung zu ermöglichen. De-normalisierte Daten
ermöglichen diese lokale Verarbeitung dadurch, dass bspw.
bei einer dokumentenorientierten Datenbank zu einem Kunden zusätzlich alle Bestellungen dieses Kunden als Attribut
gespeichert werden, obwohl die Bestelldaten zusätzlich unter
einem anderen Key / Knoten zu finden sind.
Die Replikation spielt an dieser Stelle eine entscheidende
Rolle. Viele NoSQL Datenbanken verlassen sich, statt auf
einer geringen Anzahl von hochverfügbaren Servern, auf eine Vielzahl von Servern, die isoliert betrachtet nicht hochverfügbar sind. Ein Ausfall eines Knoten im Cluster kann
toleriert werden, da die Daten immer auf mehreren Knoten zur
Verfügung stehen. Dass dieser Fall, der Ausfall eines Knoten,
im NoSQL Bereich als normal angesehen wird zeigt auch die
Verwendung einer verteilten Hashtabelle. Auf diese spezielle
Art einer Hashtabelle wird nachfolgend eingegangen.
B. Verteilte Hashtabellen
Einer der Vorreiter im Bereich NoSQL Datenbanken ist
Amazon Dynamo[1]. Die im Jahr 2007 vorgestellte Lösung
verwendet intern zur Kommunikation zwischen den Knoten des Clusters verteilte Hashtabellen (Distributed Hash
Tables, DHT’s). Diese ermöglichen innerhalb eines P2PNetzwerkes die Ressourcenlokalisierung effizient und schnell
durchzuführen. Verteilte Hashtabellen basieren auf dem Prinzip des sog. “consistent hashing”. Diese besondere Form des
Hashings optimiert den Beitritt, Ausfall und Austritt eines
Knoten im Netzwerk, da hier nicht der gesamte Datenbestand
neu umverteilt werden muss, sondern lediglich die betroffenen
Keys auf die Umliegenden Knoten verteilt werden.
C. CAP Theorem
Alle Arten von verteilten Systemen unterliegen dem CAPTheorem. Es wurde von Eric A. Brewer[2] aufgestellt und
beschreibt die Eigenschaft, dass ein verteiltes System nur 2
von 3 der folgenden Eigenschaften vollständig erfüllen kann:
• Konsistenz (C)
• Verfügbarkeit (A)
Partitionstoleranz (P )
Konsistenz ist die Eigenschaft, dass alle Knoten zu gleichen
Zeit die gleichen Daten sehen. Verfügbarkeit beschreibt die
Eigenschaft in der jede Anfrage von dem System beantwortet
werden kann und Partitionstoleranz bedeutet, dass das Gesamtsystem auch bei Verlust von Nachrichten oder Netzwerkpartitionierung in der Lage ist weiterzuarbeiten.
Bei dem Eintreten einer Netzwerkpartitionierung, bspw.
durch die Verbindungsunterbrechung zwischen zwei Rechenzentren entsteht eine Situation, in der die Daten der Replikate
nicht mehr überall konsistent sind. Die Entscheidung, wie auf
diese Situation reagiert wird, obliegt meist1 dem Entwickler
der NoSQL Datenbank. Entweder die zurückgelieferten Daten sind konsistent (C&P), wodurch evtl. manche Anfragen
nicht mehr beantwortet werden können, oder alle Anfragen
werden beantwortet, sind jedoch ggf. nicht konsistent (A&P).
Die ursprüngliche Formulierung von Eric Brewer in seiner
Präsentation im Jahre 2000[3] lautete:
A shared-data system can have at most two of the
three following properties: Consistency, Availability,
and tolerance to network Partitions.
Dies ist in der Realität, wie Brewer 2012 selbst klarstellte[4]
nicht anzutreffen, da wie oben beschrieben die Situation einer
Netzwerkpartitionierung in WAN Umgebungen jederzeit entstehen kann und somit die Entwickler von NoSQL Lösungen
im wesentlichen lediglich die Wahl zwischen C und A haben
(ggf. wird dem Benutzer der Datenbank die Entscheidung
überlassen - siehe Riak: III-A4). Eine häufig gewählte Antwort
bzw. ein für viele Anwendungsfälle akzeptabler Kompromiss
auf die angesprochene Entscheidung ist BASE. Dieses Akronym steht für die englischen Begriffe “basically available, soft
state, eventually consistent”. Es beschreibt die Eigenschaft,
dass ein verteiltes System grundsätzlich verfügbar ist, allerdings nicht jeder Knoten des Clusters zwangläufig die gleichen Daten zu gleichen Zeit sieht (dies schlussendlich jedoch
tut). Der Begriff “eventually consistency“ wurde vornehmlich
durch Werner Vogels (CTO von Amazon) in seinem gleichnamigen Artikel[5] geprägt. BASE erfüllt die Eigenschaften
A&P des CAP-Theorems und wird häufig von Datenbanken
eingesetzt, die auf Ausfallsicherheit spezialisiert sind. Ein Beispiel für eventually consistent ist der weltweite Domain Name
Service (DNS). Bei der Registrierung einer neuen Domain
dauert die komplette Propagierung der Informationen zu allen
DNS Servern eine gewisse Zeit. Innerhalb dieser Zeit sind die
DNS Server an sich jedoch verfügbar (sofern sie erreichbar
sind), auch wenn sie ggf. noch nicht die korrekten Daten
liefern.
•
III. K EY-VALUE S TORES
Diese Art von Datenbanken speichert, wie der Name schon
vermuten lässt, immer zu einem gegebenen Schlüssel (Key)
einen beliebigen Wert (Value) ab. Diese einfache Art der Datenspeicherung ist in der Regel sehr performant und lässt sich
gut skalieren. Allerdings ist eine solche Datenbank häufig nicht
gut geeignet, um komplexe Abfragen zu realisieren, da die
1 Ggf. ist es möglich als Anwender zur Laufzeit diese Entscheidung zu
treffen. Siehe III-A4
3
Datenbank meist nichts über die Struktur der Werte weiß. Man
kann innerhalb dieser Kategorie noch zwischen In-Memory
Datenbanken und persistenten Datenbanken unterscheiden. Ein
Beispiel für eine In-Memory Datenbank, die ihren gesamten
Datenbestand im Hauptspeicher hält ist memcached[6]. Für
eine persistente Variante ist hier bspw. Riak[7] zu nennen,
auf die nachfolgend detailliert eingegangen wird. Weitere
Datenbanken in dieser Kategorie sind Apache Cassandra[8],
Amazon Dynamo[9] und Redis[10].
A. RESTful Dynamo Implementierung: Riak
Riak ist ein verteilter Key-Value Store, der auf den Prinzipien der Amazon Dynamo Veröffentlichung basiert. Implementiert ist Riak in Erlang, einer funktionalen Programmiersprache
für die Entwicklung von verteilten Systemen. Die Philosophie
hinter Erlang: “Let it crash”, erkennt man auch in Riak wieder.
Riak ist fehlertolerant. Das bedeutet, dass es ein völlig normaler Vorgang ist, Knoten zum Datenbank-Cluster hinzuzufügen
und zu entfernen (beabsichtigt oder unbeabsichtigt).
1) Zugriffsmöglichkeiten: Wie viele NoSQL Datenbanken,
ist auch für Riak die primäre Zugriffsmöglichkeit das HTTP
Protokoll mit der angebotenen REST Schnittstelle. Anfragen
an die Datenbank werden via URLs gestellt. Über Headerinformationen und HTTP-Verben lassen sich unterschiedliche Arten von Anfragen realisieren. Riak antwortet mit den
gängigen HTTP-Statuscodes zur Beschreibung des Status der
Anfrage. Durch die Verwendung von HTTP als Zugriffsprotokoll bietet Riak für jeder Programmiersprache eine Verbindungsmöglichkeit, die in der Lage ist HTTP-Anfragen zu
generieren (bzw. Bibliotheken dafür bereitstellt). Somit ist es
nicht notwendig einen Datenbanktreiber für jede Programmiersprache zu erstellen. Ebenfalls bietet HTTP Möglichkeiten
wie Caching, Security und MIME Types, von denen Riak
profitieren kann, ohne dass es eigene Mechanismen dafür
bereitstellen muss.
HTTP als Transportprotokoll hat allerdings auch einige
Nachteile. So ist die Tatsache, dass HTTP ein ASCII-Protokoll
ist, ein Nachteil bezüglich der Übertragungsgeschwindigkeit.
Für diesen speziellen Fall ist es auch möglich Riak über das
Binärprotokoll “Google Protocol Buffers”[11] anzusprechen.
2) CRUD: Für die Kommunikation mit dem Riak Server
wird in diesen Beispielen das Kommandozeilen-Werkzeug
cURL[12] verwendet. In Riak entspricht eine Datenbank in
etwa einem sogenannten Bucket. Ein Bucket ist eine virtueller
Schlüsselraum, in dem jeder Schlüssel eindeutig sein muss.
Zudem ist es möglich für jeden Bucket verschiedene, voneinbobander isolierte Konfigurationen einzustellen[13]. Das
Standard URL Schema lautet folgendermaßen:
http://localhost:10018/riak/[bucket_name]/[key]
Für die Erzeugung eines Datensatzes gibt es zwei
Möglichkeiten. Entweder durch explizite Angabe des Keys
unter dem der Datensatz später zu finden sein soll:
Anbei ein Beispiel für die erste Variante:
$ curl -v -X PUT http://localhost:10018/riak/dogs/
bob -H ’Content-type: application/json’ -d ’{’
nickname’: ’B.’, ’breed’: ’Australian Kelpie’, ’
age’: 2}’
Um Datensätze eines Buckets abzurufen wird das HTTPVerb GET verwendet:
$ curl http://localhost:10018/riak/dogs/bob
HTTP/1.1 200 OK
X-Riak-Vclock: a85hYGBgzGDKBVIcR4M2cgcs+X4ygymRMY+
V4XJC/Cm+LAA=
Link: </riak/dogs>; rel="up"
ETag: "4pQlxK0OzKmotRvLkoScsq"
Content-Type: application/json
...
{"nickname": "B.", "breed": "Australian Kelpie", age
: 2}
Die Verbindung zwischen zwei Datensätzen innerhalb von
Riak geschieht über die explizite Erstellung von Links. Das
Schema für die Definition von Links ist folgendermaßen:
Link: </riak/[bucket_name]/[key]>; riaktag="[my_tag]
"
Ein Beispiel für die Erstellung eines Link:
curl -X PUT http://localhost:10018/riak/cages/1 -H "
Content-Type: application/json" -H "Link: </riak
/dogs/wuffy>; riaktag=\"contains\"" -d ’{"room"
: 23}’
Nun ist es möglich, diese Links, die in den HTTP-Responses
als Header Informationen verschickt werden, zu durchlaufen:
curl -i http://localhost:10018/riak/cages/1/_,_,_
Die Syntax: , , ist dabei folgendermaßen zu interpretieren: [bucket name],[tag], [keep]. Es ist somit möglich die
Links zwischen Einträgen in der Datenbank auf einen gewissen
Bereich einzugrenzen. Durch die Verwendung von mehrfacher
Anwendung des Link-Walking kann somit bequem durch den
Datenbestand navigiert werden.
3) Map Reduce: Wie viele NoSQL Datenbanken bietet
auch Riak eine Möglichkeit an Daten lokal auf den Knoten zu
verarbeiten und die aggregierten Ergebnisse dann zusammen
zu tragen. Dafür verwendet Riak ein Verfahren namens “Map
Reduce”[14], welches ursprünglich von der Firma Google Inc.
im Jahre 2004 vorgestellt wurde. Die praktische Verwendung
von MapReduce in Riak funktioniert über Javascript. Es werden dabei per HTTP-Request Funktionen mitgeschickt, die in
Javascript definieren, was genau bei einem Map bzw. Reduce
Schritt ausgeführt werden soll. Alternativ ist es auch möglich,
ähnlich wie in relationalen Datenbanken sogennante “Stored
Procedures” anzulegen, die diese Javascript Funktionen in der
Datenbank persistieren. Dann kann in einem Query per Name
auf diese Funktionen zugegriffen werden. Ein Beispiel für eine
solche Anfrage lautet:
curl -X POST -H "content-type:application/json" http
://localhost:10018/mapred --data @-
PUT http://localhost:10018/riak/dogs/bob
{
oder durch die automatische Vergabe des Keys:
POST http://localhost:10018/riak/dogs
"inputs":[
["rooms","23"],["rooms","24"],["
rooms","25"]
4
],
"query":[
{"map":{
"language":"javascript",
"source": "function(v) {
var parsed_data = JSON.parse(v.values[0].data);
var data = {};
data[parsed_data.style] = parsed_data.capacity;
return [data];
}"
}
}]
}
4) CAP Theorem in der Praxis: Die Entscheidung bei einer
verteilten Datenbank, wie auf eine eintretende Partitionierung
des Netzwerkes eingegangen wird, obliegt in der Regel dem
Datenbankentwickler. Dieser Entscheidet, ob das DBMS dem
C&P bzw. dem A&P Ansatz folgt. Riak verfolgt hier eine
interessante Strategie. Grundsätzlich folgt Riak dem A&P Ansatz, allerdings lässt sich der Faktor Konsistenz als Parameter
verstehen, der auf einer Pro-Anfrage-Basis variabel ist.
Dabei gibt bei Anfragen die drei Parameter N, W und R.
N beschreibt die Anzahl Replikate im Cluster, W gibt die
notwendige Anzahl von Knoten, bei denen ein erfolgreicher
Schreibvorgang stattgefunden hat, an, bis der Schreibvorgang
insgesamt als erfolgreich angesehen wurde. Somit gilt für
W < N , dass der Schreibvorgang als erfolgreich akzeptiert
wurde, auch wenn noch nicht alle Schreibvorgänge abgeschlossen sind. Der Parameter R gibt die Anzahl der Konten
an, von denen ein Lesevorgang ausgeführt werden soll. Durch
diese Parameter lassen sich verschiedene Konsistenzmodelle
herbeiführen:
• Eventually Consistency: W + R ∗ N (siehe II-C: BASE)
• Consistency by writes: W = N, R = 1
• Consistency by reads: W = 1, R = N
• Consistency by quorum: W + R > N
Insbesondere die drei letzteren wurden dabei genauer in [15]
beschrieben.
In Riak können diese drei Parameter per URL bzw. im Body
der HTTP Anfrage mitgeliefert werden:
curl -X PUT http://localhost:8091/riak/dogs -H "
Content-Type: application/json" -d ’{"props":{"w
":2, "n_val":1, "r": 2}}’
IV. S PALTENORIENTIERTE DATENBANKEN
Die zweite Kategorie von NoSQL-Datenbanken, auf die hier
näher eingegangen wird sind spaltenorientierte Datenbanken.
Ihren Ursprung hat diese Datenbank in dem Bereich OLAP
(Online Analytical Processing) und ihrer Optimierung. Die
wesentliche Eigenschaft von spaltenorientieren Datenbanken
ist die zusammenhängende Speicherung der Daten einer Spalte auf dem Speichermedium. Bei relationalen Datenbanksystemen wird hingegen Zeilenweise persistiert. Bei OLAPAnwendungen ist genau diese Art der physikalischen Speicherung von Vorteil, da hier in der Regel Auswertungen betrachtet
werden, die sich auf einzelne Spalten und ihre Aggregation
beziehen. Es werden dabei meist keine ganze Datensätze
(bspw. ein Kundendatensatz) betrachtet, sondern eher einzelne
Spalten der gesamten Tabelle (bspw. die Postleitzahlen aller
Kunden) um Auswertungen über den gesamten Datenbestand
zu erstellen.
Die Erzeugung einer Spalte in einem RDBMS ist deutlich
aufwendiger und bezieht sich immer auf die gesamte Tabelle.
Das ist bei spaltenorienterten Datenbank nicht der Fall. Es
kann durchaus eine Spalte in einer Zeile existieren und in der
nächsten nicht. Dieses Verhalten kann auch als Mittelweg in
Bezug auf das Schema zwischen einer relationalen Datenbank
und einem Key-Value Store angesehen werden. Vertreter dieser
Kategorie sind u.a. Google BigTable, bzw. dessen Open Source
Implementierung: HBase, Apache Cassandra.
V. D OKUMENTENORIENTIERTE DATENBANKEN
Ähnlich wie Key-Value Stores, speichern dokumentenorientierte Datenbanken zu einem gegebenen Schlüssel einen Wert
ab. Allerdings hat dieser Wert eine dokumentenartige Struktur
(z.B. ein JSON Dokument). Abgesehen von der gegebenen
Struktur des JSON Formates gibt es allerdings keine weiteren
Einschränkungen bezüglich der Struktur. So können beliebige valide JSON Dokumente unter verschiedenen Schlüsseln
abgelegt werden. Dabei sind auch geschachtelte Strukturen
innerhalb des Dokumentes erlaubt.
Im Unterschied zu Key-Value Stores hat das DBMS also
grundlegende Informationen über die Struktur des Dokuments.
Diese Eigenschaft wird dazu genutzt, mehr Abfragelogik in die
Datenbank zu bringen und direkt zu verarbeiten.
Im Gegensatz zu anderen NoSQL-Kategorien, gibt es bei
den dokumentenorientieren Datenbanken mit Lotus Notes
schon einen Vertreter, dessen Anfänge in die 80er Jahre
zurückreichen. Weitere Datenbankmanagementsysteme in diesem Bereich sind bspw.: MongoDB, CouchDB als auch die
Hybrid-DMB Systeme: Apache Cassandra und Redis. Auf
einen Vertreter (CouchDB) wird stellvertretend im nachfolgenden Kapitel näher eingegangen.
A. CouchDB
CouchDB ist eine solche dokumentenorientierte Datenbank,
wobei der Name als Akronym für “Cluster of unreliable commodity hardware Data Base” steht. Der Fokus lässt sich somit
bereits aus dem Namen erkennen. Statt teurer zuverlässiger
Spezial-Hardware ist die Verwendung eines beliebig großen
Clusters von Standard-Hardware vorgesehen. Der Entwickler
von CouchDB war auch an der Entwicklung von Lotus Notes beteiligt, sodass gewisse Konzepte übernommen wurden,
jedoch um heutige Technologien (z.B. Map Reduce) erweitert
wurde. Implementiert ist CouchDB, ebenso wie Riak, in
Erlang. Auf die wesentlichen Merkmale von CouchDB wird
nachfolgend eingegangen.
1) Datenbankkommunikation per HTTP / REST: Genau wie
bei Riak wird auch bei CouchDB das HTTP-Protokoll verwendet, um mit der Datenbank zu interagieren. Es verwendet
für die verschiedenen CRUD-Operationen die HTTP-Verben.
Um Beispielsweise ein einzelnes Dokument abzufragen wird
folgender Aufruf verwendet:
$ curl http://localhost:5984/music/
ae98eaf98dfef987af6756dfd655e
{
5
"_id":"ae98eaf98dfef987af6756dfd655e",
"_rev":"4-7123476876ad87e6feda876aa",
"name":"Blind Dog",
"albums": [
{"title":"The Last Adventures Of
Captain Dog", "year":2001 },
]
}
Dabei wird eine GET Operation auf die id
ae98eaf98dfef987af6756dfd655e ausgeführt. Als Ergebnis
erhält man das Dokument. Zusätzlich gibt es zwei weitere
id,
rev. Diese beiden Eigenschaften
Informationen:
beschreiben die Identität eines Dokumentes. In CouchDB wird
neben der eindeutigen ID eine zusätzliche Revisionssnummer
gespeichert. Der Grund für dieses Vorgehen wird in Kapitel
V-A3 näher erläutert. Ein neues Dokument kann per HTTP
POST auf die Datenbank URL erzeugt werden:
$ curl -X POST "http://localhost:5984/music/" -H "
Content-Type: application/json" -d ’{ "name": "
Eric Clapton" }’
Hier ist bereits zu erkennen, dass CouchDB kein festes
Schema für die Dokumente vorsieht. Bei dem obigen Beispiel
wurde unter dem Key “albums“ eine Menge von Objekten
gespeichert. Dies ist bei dem neu hinzugefügten Dokument
nicht der Fall.
Bei dem Aktualisieren eines existierenden Datensatzes wird
in CouchDB immer das vollständige Dokument mit den aktualisierten Werten übergeben. Dabei ist wichtig, dass die korrekte
Revisionsnummer verwendet wird.
$ curl -X PUT "http://localhost:5984/music/
ae98eaf98dfef987af6756dfd655e" -H "Content-Type:
application/json" -d ’
{
"_id": "ae98eaf98dfef987af6756dfd655e",
"_rev": "1-7612309098adebbdb12341",
"name": "Eric Clapton",
"albums": ["Pilgrim", "Edge ", "461 Ocean
Boulevard"]
}’
Als Rückgabe erhält man, sofern die aktuellste Revisionsnummer verwendet wurde:
{
"ok":true,
"id":"ae98eaf98dfef987af6756dfd655e",
"rev":"2-4371093810adef123efea12321b"
}
eine Erfolgsmeldung mit der neuen Revisionssnummer des
Dokuments. Weitere Hintergrundinformationen zum Thema
Revisionen und deren Verwendung ist im
2) Verwendung von Views: Views werden in CouchDB,
ähnlich wie in relationalen Datenbanksystemen, dazu verwendet die Daten darzustellen. Im Falle von CouchDB sind
diese Daten meist Dokumente, die zu neuen aggregierten
Dokumenten transformiert werden. Dazu verwendet CouchDB
wie Riak den Map-Reduce-Ansatz. Grundsätzlich gibt es in
CouchDB die Möglichkeit von ad-hoc Anfragen als auch von
vorberechneten Design Dokumenten. Der Unterschied ist im
Wesentlichen, dass bei ad-hoc Anfragen die Map-Funktion auf
jedes Dokument in der Datenbank ausgeführt wird. Dieses
Verhalten schließt einen Einsatz im Produktivbetrieb aus, da
die Berechnung von solchen ad-hoc Anfragen extrem langsam
sein kann. Die alternative: vorberechnete Design Dokumente
werden demnach nicht zum Anfragezeitpunkt ausgewertet,
sondern stattdessen vorberechnet. Dieser Geschwindigkeitsgewinn schlägt sich allerdings negativ in der Flexibilität nieder.
Ein Design-Dokument enthält typischerweise mehrere Views.
Ein Beispiel für einen solchen View ist die Indizierung der
Musikdatenbank nach Namen. Dazu kann folgende, in Java
Script definierte, Map Funktion verwendet werden:
function(document) {
if (’name’ in document) {
emit(document.name, document._id);
}
}
Diese kann per entsprechender HTTP-POST-Operation auf
den CouchDB-Server übertragen werden. Der Reduce Teil
des Views ist dabei optional. Mit folgender Anfrage ist da
daraufhin möglich diesen View zu betrachten:
$ curl ’http://localhost:5984/music/_design/artists/
_view/by_name?key="Eric Clapton"’
{
"total_rows":1,
"offset":0,
"rows":[{
"id":"ae98eaf98dfef987af6756dfd655e",
"key":"Eric Clapton",
"value":"ae98eaf98dfef987af6756dfd655e"
}]
}
3) Multiversion Concurrency Control: CouchDB verwendet ein Verfahren namens “Multiversion Concurrency Control”. Es wird, statt ein Dokument bei einem Update zu
überschreiben, eine weitere Version dieses Dokumentes gespeichert. Da es nun für eine ID mehrere Dokumente gibt,
ist es notwendig, eine Revisionsnummer einzuführen, die
innerhalb dieser ID wieder zu Eindeutigkeit führt. Der Hauptgrund für dieses Vorgehen ist, dass dadurch blockierende
Schreib- / Lesezugriffe verhindert werden können. Statt die
Update-Anfragen verschiedener Benutzer sequentiell abzuarbeiten wird jedes Dokument unter einer anderen Revision
persistiert. Dieses Verhalten entspricht in etwa einem Versionsverwaltungssystem, allerdings kann bei CouchDB nicht
gewährleistet werden, dass stets alle Versionen verfügbar
sind. Durch Komprimierungsvorgänge und Replikation bei
großen Datenmengen sind u.U. alte Revisionen nicht dauerhaft
verfügbar[16]. CouchDB &ist an dieser Stelle sehr explizit
bezüglich Konflikten. Es wird dem Benutzer der Datenbank
überlassen, ggf. eine Konfliktbehandlung selbst durchzuführen.
Für die Kommunikation wird dabei der entsprechende HTTPStatuscode 409 -(Conflict) verwendet.
VI. G RAPHENDATENBANKEN
Die letzte und neueste Kategorie im Bereich NoSQL sind
Graphendatenbanken. Hier wird für die Repräsentation von
Daten ein Graph verwendet. Entsprechend gibt es die Konzepte
von Konten und Kanten zwischen diesen Knoten. Sowohl
an Kanten als auch an Knoten können Key-Value Paare
angehängt werden, die die Daten enthalten. Der besondere
Vorteil an Graphendatenbanken ist die Verwendung der vielen graphentheoritischen Algorithmen zum Traversieren von
Graphen. Da in einem Graphen beliebige Knoten miteinander
6
verbunden sein können, gibt es normalerweise kein Schema
für Graphendatenbanken. Der Einsatzzweck ist immer dort
gegeben, wo man in RDBM-Systemen selbst referenzierende
Entitäten oder Baumstrukturen vorfindet. Ein Beispiel dafür
sind Freundschaftsbeziehungen in sozialen Netzwerken.
Vertreter dieser Kategorie sind u.a. Neo4J und BigData.
Bezüglich der Anfragesprachen gibt es im Bereich Graphendatenbanken im Gegensatz zu anderen Kategorien der NoSQL Bewegung eine gewisse Konsolidierung, da die Art auf
Graphen zuzugreifen sich in den Implementierungen nicht
wesentlich unterscheidet. Ein bekannter Vertreter einer solchen
Anfragesprache ist die domänenspezifische Sprache “Gremlin”, mit der es möglich ist auf verschiedene Datenbanken aus
diesem Umfeld zuzugreifen.
A. Semantic Web Datenbanken
Eine Unterkategorie der Graphendatenbanken stellt der Bereich der Semantic Web Datenbanken dar. Diese Datenbanken
ermöglichen den Zugriff auf Graphen, die aus RDF Triplen
bestehen. Die Abfragesprache ist mit SPARQL / SPASQL
(SPARQL innerhalb einer SQL Anfrage) allerdings fest definiert. Dieses feste Schema in der Abfrage, aber auch bei der
Datenbasis (RDF-Tripel haben immer eine gewisse Struktur),
ist der Hauptunterschied zu anderen Graphendatenbanken.
VII. Z USAMMENFASSUNG
Der Bereich der NoSQL Datenbanksysteme ist äußerst
vielfältig. Die einzelnen Kategorien unterscheiden sich im dem
Grad, in dem Sie von dem klassischen, relationalen Modell
abweichen. Dieser Grad hängt im Wesentlichen von folgenden
beiden Eigenschaften ab:
•
•
Kenntnisse über das Schema der Daten
Flexibilität der Anfragen
Einfache Key-Value Datenspeicher haben wenig Kenntnis
über das Schema. Daher sind die Anfragearten gewissermaßen begrenzt. Die Anfragelogik wird in dieser Kategorie in
Richtung der verwendenden Anwendung verschoben. Hybridmodelle, wie Spaltendatenbanken oder Dokumentenorientierte
Datenbanken gehen hier einen Mittelweg, der einem entweder gewisse Schemastrukturen vorgibt und somit in der
Lage ist, mehr Flexibilität in der Anfrage zu ermöglichen.
Durch ihre unterschiedlichen Annahmen an Konsistenz (siehe
CAP-Theorem) sind viele NoSQL Datenbanken in der Lage
Hochverfügbarkeit und ein einfaches horizontales Skalieren
zu ermöglichen. Nichtsdestotrotz gibt es auch weiterhin den
Bedarf an relationalen Datenbanksystemen. Diese sind insbesondere dann von Vorteil, wenn die genaue Struktur der
Daten zu Beginn festgelegt werden kann bzw. eine sehr große
Anfrageflexibilität notwendig ist.
Zusammenfassend lässt sich sagen, dass NoSQL Datenbanken das relationale Modell keineswegs ersetzen werden.
Vielmehr ist es wahrscheinlich, dass diese beiden Welten in
Koexistenz innerhalb eines Projektes verwendet werden, um
die Vorteile, die beide Ansätze besitzen zu vereinen.
L ITERATUR
[1] G. DeCandia, D. Hastorun, M. Jampani, G. Kakulapati, A. Lakshman,
A. Pilchin, S. Sivasubramanian, P. Vosshall, and W. Vogels. Dynamo:
Amazon’s highly available key-value store. [Online]. Available:
http://www.allthingsdistributed.com/files/amazon-dynamo-sosp2007.pdf
[2] S. Gilbert and N. Lynch. Brewer’s conjecture and the feasibility
of consistent, available, partition-tolerant web services. [Online].
Available: http://lpd.epfl.ch/sgilbert/pubs/BrewersConjecture-SigAct.pdf
[3] D. E. A. Brewer. Towards robust distributed systems.
[Online]. Available: http://www.cs.berkeley.edu/∼brewer/cs262b-2004/
PODC-keynote.pdf
[4] ——.
Cap
twelve
years
later:
How
the
”rules”have
changed.
[Online].
Available:
http://www.infoq.com/articles/
cap-twelve-years-later-how-the-rules-have-changed
[5] W. Vogels. Eventually consistent - revisited. [Online]. Available:
http://www.allthingsdistributed.com/2008/12/eventually consistent.html
[6] Memcached official website. [Online]. Available: http://memcached.org/
[7] B. T. Inc. Riak official website. [Online]. Available: http://basho.com/
products/riak-overview/
[8] A. S. Foundation. Apache cassandra official website. [Online].
Available: http://cassandra.apache.org/
[9] Amazon. Amazon dynamo db official website. [Online]. Available:
http://aws.amazon.com/de/dynamodb/
[10] Citrusbyte. Redis official website. [Online]. Available: http://redis.io/
[11] G. Inc. Google protocol buffers: An overview. [Online]. Available:
https://developers.google.com/protocol-buffers/docs/overview
[12] “curl official website.” [Online]. Available: http://curl.haxx.se/
[13] B. T. Inc. Riak bucket explanation. [Online]. Available: http:
//docs.basho.com/riak/1.2.1/references/appendices/concepts/Buckets/
[14] J. Dean and S. Ghemawat. Mapreduce: Simplied data
processing
on
large
clusters.
[Online].
Available:
http://static.googleusercontent.com/external content/untrusted
dlcp/research.google.com/de//archive/mapreduce-osdi04.pdf
[15] E. Rahm, Mehrrechner-Datenbanksysteme: Grundlagen der verteilten
und parallelen Datenbankverarbeitung. Addison-Wesley (Deutschland)
GmbH, 1994.
[16] Versioning
docs
in
couchdb.
[Online].
Available:
http://jchrisa.net/drl/ design/sofa/ list/post/post-page?startkey=
%5b%22Versioning-docs-in-CouchDB%22%5d
Herunterladen