Fachhochschule Aachen Fachbereich 9 Medizintechnik und Technomathematik Seminararbeit im Studiengang Scientific Programming Einführung in NoSql-Datenbanken und der Vergleich zu relationalen Datenbanken Von: Alexey Sibirtsev Matr.-Nr.: 843592 Vom: 20.12.2012 Erster Betreuer: Prof. Dr. Bodo Kraft Zweiter Betreuer: Jörg Beckers Abstract Die folgende Seminararbeit „Einführung in NoSql-Datenbanken und der Vergleich zu relationalen Datenbanken“ bietet einen Vergleich von relationalen und nicht relationalen Datenbanken. Dabei wird auf die Herkunft des „NoSql“ Begriffes eingegangen und erläutert, wieso dieser Begriff eine wichtige Rolle in der heutigen IT-Welt spielt. Neben allgemeinen NoSql-Eigenschaften, die die NoSql-Datenbanken von relationalen Datenbanken unterscheiden, werden außerdem die zentralen NoSql-Datenbanktypen vorgestellt und Anhand von Vor- und Nachteilen mit relationalen Datenbanken verglichen. Schlussendlich werden Technologien vorgestellt, die eine zentrale Rolle in NoSql-Datenbanken spielen. Inhaltsverzeichnis 1. EINLEITUNG ............................................................................................................................................. 5 1.1. 1.2. 2. EINFÜHRUNG IN DIE NOSQL-DATENBANKEN ........................................................................................... 7 2.1. 2.2. 2.3. 3. NOSQL-EIGENSCHAFTEN .............................................................................................................................. 7 BREWER‘S THEOREM ................................................................................................................................... 8 DAS BASE-KONSISTENZMODELL.................................................................................................................... 9 DIE WICHTIGSTEN NOSQL-DATENBANKTYPEN ....................................................................................... 11 3.1. KEY-VALUE-DATENBANKEN ........................................................................................................................ 11 3.1.1. Einleitung ....................................................................................................................... 11 3.1.2. Vor- und Nachteile......................................................................................................... 11 3.1.3. Ein Beispiel Anhand der Datenbank „Redis“ ................................................................. 12 3.2. GRAPHENORIENTIERTE DATENBANKEN .......................................................................................................... 14 3.2.1. Einleitung ....................................................................................................................... 14 3.2.2. Vor- und Nachteile......................................................................................................... 14 3.2.3. Ein Beispiel Anhand der Datenbank „Neo4j“ ................................................................ 15 3.3. DOKUMENTORIENTIERTE DATENBANKEN ....................................................................................................... 17 3.3.1. Einleitung ....................................................................................................................... 17 3.3.2. Vor- und Nachteile......................................................................................................... 18 3.3.3. Ein Beispiel Anhand der Datenbank „MongoDB“ .......................................................... 19 3.4. 4. GESCHICHTLICHES ....................................................................................................................................... 5 DER NOSQL-AUFSCHWUNG.......................................................................................................................... 5 SPALTENORIENTIERTE DATENBANKEN ........................................................................................................... 20 3.4.1. Einleitung ....................................................................................................................... 20 3.4.2. Vor- und Nachteile......................................................................................................... 21 3.4.3. Ein Beispiel Anhand der Datenbank „Cassandra“ ......................................................... 22 VERWENDETE TECHNOLOGIEN .............................................................................................................. 25 4.1. MAPREDUCE ........................................................................................................................................... 25 4.1.1. Einleitung ....................................................................................................................... 25 4.1.2. Verfahrensablauf ........................................................................................................... 26 4.1.3. Ein Beispiel zu MapReduce ............................................................................................ 26 4.2. MULTIVERSION CONCURRENCY CONTROL ...................................................................................................... 28 5. ZUSAMMENFASSUNG ............................................................................................................................ 30 6. AUSBLICK ............................................................................................................................................... 31 7. LITERATUR- UND QUELLENVERZEICHNIS ................................................................................................ 32 5 Einleitung 1. Einleitung 1.1. Geschichtliches Der Begriff „NoSql“ ist bereits seit 1998 in der IT-Welt bekannt. Carlo Strozzi hat diesen Begriff erstmals für eine von ihm entwickelte leichtgewichtige Open-Source-Datenbank verwendet. Seine Datenbank folgte allen Prinzipien einer relationalen Datenbank, verzichtete jedoch auf die Verwendung der SQL-Sprache1. Diese Tatsache hat Strozzi daher im Namen der Datenbank festgehalten, indem er seine Datenbank „NoSql“, gemeint als „No Structured Query Language“, nannte. Bei einem im Jahr 2009 abgehaltenen Treffen über verteilte Datenspeicher wurde der NoSqlBegriff von Johan Oskarsson jedoch neu definiert. Mit dem modernen Verständnis des NoSqlBegriffes, der NoSql als „Not only SQL“ umschreibt, hat die aktuelle NoSql-Bewegung begonnen. Bei der Implementierung solcher NoSql-Datenbanken wird nicht nur auf die SQLSprache, sondern auf das Prinzip und Modell der relationalen Datenbanken verzichtet. 1.2. Der NoSql-Aufschwung NoSql erfährt aktuell eine sehr große Aufmerksamkeit und Beliebtheit. Dabei stellt sich jedoch die Frage, wieso es plötzlich zu diesem NoSql-Aufschwung gekommen ist. Schließlich hat man die relationalen Datenbanken bereits seit 1980, als diese in den meisten großen Unternehmen und Behörden den Durchbruch fanden, verwendet und damit große Erfolge erzielt. Einer der Gründe, weshalb NoSql aktuell so viel Aufmerksamkeit gewinnt, ist der enorm große Zuwachs an generierten und verwendeten Daten. So besagt ein Bericht einer großen Beratungsfirma namens „McKinsley & Company“, dass ein durchschnittliches Unternehmen, das unter 1000 Mitarbeiter hat, etwa 3.8 Petabyte Daten lagert und jährlich einen Datenzuwachs von etwa 40 Prozent hat2. „IBM“ stellt in einem Bericht dar, dass täglich 2.5 Quintillionen Byte (2*10^15 Petabyte) entstehen und 90% aller Daten, die weltweit im Umlauf sind, in den letzten zwei Jahren erzeugt wurden3. 1 Die Structured Query Language ist eine Sprache zur Abfrage und Bearbeitung von Datensätzen in relationalen Datenbanken. 2 Quelle der Fakten: http://www.datastax.com/resources/whitepapers/nosql 3 Quelle der Fakten: http://www-01.ibm.com/software/data/bigdata/ 6 Einleitung Ein weiterer Grund für das wachsende Interesse an NoSql-Datenbanken ist die zunehmende Abhängigkeit und Vernetzung der Daten, die u.a. durch soziale Netzwerke und das Web 2.04 beschleunigt wird. Da relationale Datenbanken bezüglich der Datenmenge jedoch schlecht skalierbar sind und komplex vernetzte Datenstrukturen nur schlecht darstellen können, haben sich viele große Unternehmen wie Google oder Amazon auf die Suche nach alternativen Lösungen begeben. Bei dieser Suche sind NoSql-Datenbanken wie „Google‘s Big Table“ und „Amazon SimpleDB“, aber auch andere Technologien wie das MapReduce-Framework entstanden. Ein Teil des NoSql-Aufschwungs beruht sicherlich auch darauf, dass diese großen Unternehmen es schaffen, NoSql-Datenbanken erfolgreich zu verwenden. Dies bringt viele andere Unternehmen dazu, diese neuen Technologien auszuprobieren und möglicherweise Abstand von den relationalen Datenbanken zu nehmen. 4 Das Verhalten der Internetnutzer hat sich mit dem Web 2.0 geändert. Die Internetnutzer konsumieren nicht nur Informationen aus dem Internet, sondern Stellen auch eigene Informationen, z.B. durch soziale Netzwerke oder Wikis, bereit. 7 Einführung in die NoSql-Datenbanken 2. Einführung in die NoSql-Datenbanken 2.1. NoSql-Eigenschaften Alle NoSql-Datenbanken haben allgemeine Eigenschaften, die sie von relationalen Datenbanken unterscheiden. Eine dieser Eigenschaften ist der Verzicht auf ein festes Schema. Dieses Schema ist in relationalen Datenbanken durch eine feste Struktur, die unter anderem aus Relationen und festgesetzten Datenstrukturen besteht, vorgegeben und muss eingehalten werden. Somit kann die Speicherung der Daten in NoSql-Datenbanken flexibler gestaltet oder komplett der Anwendung überlassen werden. Die wichtigsten Eigenschaften und Hauptziele, die viele NoSql-Datenbanken verbindet, sind die Ausfalltoleranz, die Verfügbarkeit und die horizontale Skalierbarkeit5. So bieten viele NoSql-Implementierungen die Möglichkeit, verteilte Datenbanken zu verwenden und die Daten somit auf mehrere Server aufzuteilen. Wie die ursprüngliche NoSql-Datenbank von 1998 verzichten auch die heutigen NoSqlDatenbanken auf die Verwendung der SQL-Sprache. Da es bei NoSql-Implementierungen keinen allgemein geltenden Standard gibt, existiert keine Abfragesprache, die für alle NoSqlImplementierungen gültig ist. Somit werden die Schnittstellen zur Kommunikation zwischen Datenbank und Anwender immer von der jeweiligen Implementierung einer NoSqlDatenbank zur Verfügung gestellt. Jeder NoSql-Datenbanktyp ist für bestimmte Anwendungsfälle ausgelegt. Daher kann man nicht allgemein sagen, dass eine bestimmte NoSql-Datenbankimplementierung die beste Lösung für alle Anwendungsfälle ist. Die Wahl des Datenbanktyps für ein Projekt hängt somit stets von den Projektvorgaben ab. 5 Bei einer horizontalen Skalierbarkeit wird die Leistung eines Systems gesteigert, indem zusätzliche Knoten oder Rechner in das System hinzugefügt werden. Somit hat diese Skalierbarkeit im Gegensatz zur vertikalen Skalierbarkeit keine Grenzen bezüglich der Hardware. 8 Einführung in die NoSql-Datenbanken 2.2. Brewer‘s Theorem Da NoSql-Implementierungen, wie bereits erwähnt, oftmals die Möglichkeit bieten, die Datenbank als ein verteiltes System zu verwenden, spielt das sogenannte Brewer's Theorem eine wichtige Rolle für NoSql-Datenbanken. Brewer‘s Theorem, auch bekannt als „CAP-Theorem“, entstand im Jahr 2000 bei einer Rede von Eric Brewer auf der Fachkonferenz „Principles of Distributed Computing“. Es wurde jedoch erst im Jahr 2002 von Seth Gilbert und Nancy Lynch bewiesen. Es beschreibt den Zusammenhang von drei wichtigen Eigenschaften, die in verteilten Datenbanksystemen eine zentrale Rolle spielen: - Consistency (Konsistenz): Auf jedem Client der Datenbank werden die gleichen Daten zur Verfügung gestellt. Die Konsistenz kann an dieser Stelle auch als „Atomarität“ gesehen werden. Ein Befehl an eine konsistente Datenbank wird entweder ganz oder gar nicht ausgeführt. - Availability (Verfügbarkeit): Ein System, das diese Vorgabe erfüllt, muss immer erreichbar sein. Ein Beispiel ist die Buchung einer Reise auf einem Online-Portal. Wenn die Antwortzeiten des OnlinePortals zu lange sind, erhält der Kunde lediglich eine Nachricht, dass die Seite nicht geladen werden konnte. In diesem Fall würde der Kunde nicht wissen, ob die Buchung nun erfolgreich war oder nicht. Daher ist es notwendig, dass ein System immer in der Lage ist, eine rechtzeitige Antwort zu liefern. - Partition Tolerance (Ausfalltoleranz): Diese Eigenschaft soll sicherstellen, dass ein verteiltes System selbst dann noch funktionsfähig ist, wenn ein Teil des Netzwerks ausfällt. Auch wenn ein Server ausfällt oder eine Verbindung zwischen zwei Servern gestört ist, soll das System weiterhin in der Lage sein, die richtige Antwort zu liefern. Obwohl alle drei Eigenschaften sehr wichtig für verteilte Datenbanken erscheinen, besagt das CAP-Theorem, dass lediglich zwei dieser Eigenschaften in einem verteilten System erreicht werden können. Das folgende Beispiel zeigt, wieso diese drei Eigenschaften nicht vereinbar sind. Wenn man die Ausfalltoleranz gewährleisten möchte, muss ein verteiltes System mit redundanten Daten6 vorhanden sein. Um die Konsistenz erreichen zu können, müsste der 6 Daten gelten als Redundant, wenn sie mehrfacht vorhanden sind. Dies wird häufig dadurch erreicht, dass die Daten z.B. auf andere Festplatten kopiert werden. 9 Einführung in die NoSql-Datenbanken Datensatz bei einer Aktualisierung auf allen Servern gesperrt werden. Das Arbeiten mit solchen Sperren ist vor allem in verteilten Systemen sehr zeitaufwändig, so dass keine Verfügbarkeit mehr gewährleistet werden kann. Die Schwerpunkte einer verteilten Datenbank liegen daher auf jeweils zwei solcher Eigenschaften. Welche dieser Eigenschaften verwendet werden sollen, hängt von dem bevorzugten Verhalten der Datenbank ab. Eine relationale Datenbank folgt immer den ACID-Prinzipien7, selbst wenn die Datenbank als ein verteiltes System implementiert ist. Die Erläuterung der ACID-Prinzipien ist stark verbreitet und sollte jedem Informatiker bekannt sein, weshalb ich nicht weiter auf die Erläuterung dieser Prinzipien eingehen werde. Da die relationalen Datenbanken diesen Prinzipien folgen müssen, muss folglich immer die Konsistenz gewährleistet werden. Um die Ausfalltoleranz und die Verfügbarkeit in einer relationalen Datenbank zu realisieren, versucht man eine hochwertige und leistungsfähige Hardware zu verwenden. Dieses Vorgehen entspricht der sogenannten vertikalen Skalierung8 und ist sehr Kostenintensiv. Bei verteilten NoSql-Datenbanken stehen eher die Ausfalltoleranz und die Verfügbarkeit im Vordergrund, wodurch die Konsistenz vernachlässigt werden muss. Der Grund dafür ist, dass diese Datenbanken häufig für Internetanwendungen (z.B. Online-Shops) verwendet werden und diese immer verfügbar und ausfallsicher sein sollten. Wäre dies nicht der Fall, so würde ein Unternehmen wie Amazon aufgrund fehlender Verfügbarkeit viele Kunden und somit auch Geld verlieren. Eine fehlende Konsistenz würde lediglich den Nachteil bringen, dass ein Kunde möglicherweise einen Artikel kauft, der nicht mehr vorhanden ist. Daher ist es für ein solches Unternehmen einfacher, sich aufgrund der fehlenden Datenkonsistenz bei einem Kunden entschuldigen, als komplett auf ihn verzichten zu müssen. Da die Datenkonsistenz in verteilten Systemen somit nicht dem ACID-Konsistenzmodell entsprechen kann, wird ein anderes Konsistenzmodell für verteilte Systeme verwendet. Dieses Modell wird in dem nächsten Kapitel erläutert. 2.3. Das BASE-Konsistenzmodell Der Begriff „BASE“ steht für „Basically Available, Soft State, Eventually Consistent“ und stellt ein Konsistenzmodell dar. Dieses Konsistenzmodell wird häufig in NoSql-Systemen 7 Die Eigenschaften der Atomarität, Datenkonsistenz, Isolation und Dauerhaftigkeit müssen erfüllt sein. Bei der vertikalen Skalierung wird die Leistung eines Systems gesteigert, indem die Hardware eines Rechners in dem System verbessert wird. 8 10 Einführung in die NoSql-Datenbanken verwendet, da es den Anforderungen von verteilten NoSql-Datenbanksystemen entspricht und auf die Erkenntnisse des CAP-Theorems eingeht. Um den Ansatz des BASE-Konsistenzmodells verstehen zu können, sollte man zunächst die Nachteile des ACID-Konsistenzmodells in verteilten Systemen betrachten. Eine Vorgabe der ACID-Prinzipien ist die ständige Konsistent der Daten. Dies wird gewährleistet, indem ein Datensatz bei einer Änderung gesperrt wird. Somit muss jeder andere Client, der den Datensatz lesen oder ändern möchte, darauf warten, dass die vorherige Transaktion beendet ist. Diese Wartezeiten sind häufig unberechenbar. Bei verteilten Datenbanksystemen, die die Daten auf mehreren Servern replizieren, muss eine solche Sperre zusätzlich mit allen anderen Servern abgesprochen werden. Der Antrag auf eine Sperre wird daher zunächst an alle Server verteilt. Die Antworten der Server, die eine Zustimmung oder eine Absage zur Sperre des Datensatzes beinhalten können, werden daraufhin an den beantragenden Server übermittelt. Sobald der beantragende Server genug Zustimmungen gesammelt hat, muss er nochmals alle Server darüber informieren, dass eine Sperre gesetzt wurde. Nach der Änderung der Daten muss die Information über die Entfernung der Sperre ebenfalls an alle Server verschickt werden. Dabei ist zu beachten, dass die Kommunikation zwischen den Servern über das Netz geht und somit sehr zeitaufwändig werden kann. Um auf diese Weise entstandene Wartezeiten zu verhindern und der Eigenschaft der Verfügbarkeit gerecht zu werden, müssen NoSql-Systeme daher auf Sperren und dadurch auch teilweise auf die Konsistenz verzichten. An dieser Stelle tritt das BASEKonsistenzmodell in Kraft, welches das ACID-Konsistenzmodell in verteilten Systemen ersetzen soll. Es existieren mehrere unterschiedliche BASE-Lösungen mit verschiedenen Konsistenzeigenschaften. Das zentrale und am häufigsten verwendete BASE-Modell sagt aus, dass die Daten zwischen einem konsistenten und einem inkonsistenten Zustand wechseln. Somit sind die Daten lediglich zu einem bestimmten Zeitpunkt für alle Clients „letztendlich konsistent“ (Eventually Consistent), was für die Datenbankenimplementierungen, die BASE verwenden, jedoch akzeptabel ist. Der konkurrierende Zugriff auf die Datensätze wird über das Multiversion Concurrency Control Verfahren geregelt. Das MVCC-Verfahren wird in dem späteren Kapitel „Verwendete Technologien“ erläutert. 11 Die wichtigsten NoSql-Datenbanktypen 3. Die wichtigsten NoSql-Datenbanktypen Im Folgenden werden die vier wichtigsten NoSql-Datenbanktypen, die sich in Key-ValueDatenbanken, dokumentorientierte Datenbanken, graphenorientierte Datenbanken und spaltenorientierte Datenbanken unterteilen lassen, erläutert und mit dem relationalen Datenbankmodell verglichen. Außerdem wird ein praktisches Beispiel zu jedem Datenbanktyp vorgestellt. 3.1. Key-Value-Datenbanken 3.1.1. Einleitung Key-Value-Datenbanken sind die einfachste Form der NoSql-Datenbanken. Sie lassen sich am besten mit den aus der Programmierung bekannten assoziativen Feldern, auch „hash map“ oder „hash table“ genannt, vergleichen. Dabei wird einem Schlüssel in einer Key-Value-Datenbank ein bestimmter Wert zugewiesen. Der Schlüssel liegt üblicherweise in einem Zeichenkettenformat vor. Der Wert kann als eine Zeichenkette oder als eine komplexe Datenstruktur wie z.B. eine Liste, ein Set oder eine Hash-Tabelle dargestellt werden, falls die Implementierung der Datenbank dies zulässt. Weiterhin lassen sich Key-Value-Datenbanken in On-Disk und In-Memory Varianten unterteilen. Während die Daten bei der On-Disk Variante lediglich auf der Festplatte gespeichert werden und der Zugriff somit langsam ist, können Daten bei der In-Memory Variante direkt im Arbeitsspeicher gelagert werden, was die Zugriffszeiten wesentlich verringert. 3.1.2. Vor- und Nachteile Im Gegensatz zu relationalen Datenbanken sind Key-Value-Datenbanken häufig als verteilte Systeme implementiert. Dadurch lässt sich eine sehr gute Skalierbarkeit erreichen. Somit hat man die Möglichkeit, mehrere günstige Server zu einem großen performanten System zusammenzuschließen. 12 Die wichtigsten NoSql-Datenbanktypen Ist die Key-Value-Datenbank als ein verteiltes System implementiert, so wird eine HashFunktion verwendet, um den passenden Server zu einem gegebenen Schlüssel zu ermitteln. Durch diese Vorgehensweise kann man direkt auf den Server zugreifen, der die passenden Informationen bereithält, so dass man nicht alle Server nach dem Schlüssel durchsuchen muss. Die Zugriffszeiten für Lese- und Schreiboperationen bei einer Key-Value Datenbank betragen O(1). Diese Zugriffszeiten sind unabhängig davon, wie viele Daten in der Datenbank gelagert werden. Bei einer relationalen Datenbank können die Zugriffszeiten mit einer anwachsenden Datenmenge schnell in die Höhe steigen. Key-Value Datenbanken sind keine allgemeine Lösung für jedes Softwareprojekt, da diese Datenbanken auch Nachteile mit sich bringen. So ist es z.B. umständlich nach einem bestimmten Wert zu suchen. Um dies zu ermöglichen, müsste man einen zusätzlichen Eintrag erstellen, der von dem Wert auf den Schlüssel verweist, wodurch wechselseitige Beziehungen entstünden. Ist der Wert eine komplexe Struktur, wie z.B. ein Set, so wird die Implementierung schnell unübersichtlich. Da es dem Benutzer überlassen ist, wie er die Daten in der Key-Value-Datenbank speichert, muss dieser auch selbst darauf achten, dass er die Schlüssel korrekt verwendet und die Einträge nicht ausversehen überschreibt. Bei einer falschen Verwendung könnte es somit schnell zu Datenverlusten kommen. 3.1.3. Ein Beispiel Anhand der Datenbank „Redis“ Ein gutes Beispiel für eine performante und häufig verwendete Key-Value-Datenbank ist Redis. Diese Datenbank kombiniert die On-Disk und die In-Memory Varianten, so dass die Daten zunächst im Arbeitsspeicher gelagert werden, bis sie beim Erfüllen bestimmter Kriterien auf die Festplatte verschoben werden können. Durch die Verwendung der InMemory Variante ermöglicht es Redis bis zu 100.000 Schreib- und Lesezugriffe pro Sekunde zu vorzunehmen. Die Daten werden bei einem Schreibzugriff zunächst im Arbeitsspeicher gesammelt und erst ab einer bestimmten Anzahl auf die Festplatte kopiert, wodurch diese große Anzahl an Schreibzugriffen erreicht werden kann. Neben dem Einsatz von Zeichenketten bietet Redis auch die Möglichkeit Sets, sortierte Sets, Hash-Tabellen und Listen als Werte zu verwenden, was die Verwendungszwecke dieser KeyValue Datenbank stark erweitert. 13 Die wichtigsten NoSql-Datenbanktypen Außerdem werden für jeden Datentyp spezifische Funktionen zum Speichern, Löschen und Arbeiten zur Verfügung gestellt. Die Einträge in der Datenbank werden über die datentypspezifischen SET-Funktionen erstellt. Ein Eintrag mit einer Hash-Tabelle als Wert kann wie folgt erstellt werden: HMSET user:testuser name hello lastname world password 123 age 23 Durch diese Operation wird die Hash-Tabelle mit den Attributen name = ”hello”, lastname = “world“, password = ”123” und age = ”23” dem Schlüssel „user:testuser“ zugewiesen. Der Schlüssel lässt sich wiederum in zwei Teile unterteilen. Die Zeichenkette „user“ beschreibt eine Art Namespace9, in dem alle Benutzer angelegt werden sollen. Solche Namespaces sind vom Entwickler, der die Datenbank verwendet, frei wählbar und müssen nicht zwingend eingesetzt werden. Der Wert „testuser“ ist in diesem Beispiel ein Spitzname, über den ein User bekannt ist. In diesem Beispiel wäre es lediglich möglich, einen Benutzer mit dem Spitznamen „testuser“ unter dem Namespace „user“ anzulegen. Falls man einen weiteren Benutzer mit demselben Spitznamen im selben Namespace anlegen würde, würde der alte Benutzer überschrieben, wodurch die Informationen zu diesem verloren gingen. Daher muss der Entwickler bereits auf der Anwendungsseite darüber entscheiden, ob er jeden Benutzernamen lediglich einmal zulässt oder z.B. die einmalige E-Mail Adresse des Benutzers als Schlüssel verwendet. Desweiteren werden atomare Operationen10, wie z.B. die Operation HINCRBY key field increment geboten. Diese Operation erhöht den Wert des Feldes „field“ in der Hash-Tabelle, die sich bei dem Schlüssel „key“ finden lässt. Durch Verwendung der atomaren Operationen hat man die Möglichkeit Race Conditions zu vermeiden. Neben den spezifischen Datentypoperationen bietet Redis auch allgemeine Operationen an. So gibt es hilfreiche Operationen wie EXPIRE key seconds, mit der sich die TTL (Time to life) eines Eintrages einstellen lässt: EXPIRE user:testuser 120 Dieses Beispiel setzt die Lebensdauer von dem Eintrag „user:testuser“ auf 120 Sekunden. Nach Ablauf der Zeit wird dieser Eintrag gelöscht. Über den Aufruf TTL user:testuser lässt sich die verbleibende Lebensdauer des Eintrages abfragen. Falls eine -1 zurück gegeben wird, ist die Lebensdauer des abgefragten Eintrages unendlich. 9 Ein Namespace ist ein Container für mehrere Elemente, die unter dem gleichen Namen zusammengefasst werden können. 10 Eine atomare Operation ist eine Ansammlung von Einzeloperationen, die entweder vollständig erfolgreich ablaufen oder aber komplett fehlschlagen. 14 Die wichtigsten NoSql-Datenbanktypen 3.2. Graphenorientierte Datenbanken 3.2.1. Einleitung Die ersten graphenorientierten Datenbanken entstanden bereits in den 60er Jahren, noch bevor relationale Datenbanken entworfen wurden. Diese Datenbanken waren als Netzwerk- oder hierarchische Datenbanken bekannt und sollten als Allzweckdatenbanksysteme dienen. Dieser Ansatz wurde jedoch weitgehend verdrängt, nachdem das relationale Modell von Edgar Frank Codd im Jahr 1970 vorgestellt wurde. Das relationale Modell erschien damals verständlicher und einfacher, um ein Allzweckdatenbanksystem implementieren zu können. Durch das Wachstum der Graphenstrukturen in Anwendungen und im Internet steigt das Interesse für graphenorientierte Datenbanken derzeit jedoch wieder an. So werden solche Datenbanken vor allem in sozialen Netzwerken wie Twitter11 verwendet. Sie ermöglichen es, komplexe Beziehungsstrukturen abzuspeichern und performant wiederzugeben. Ein Beispiel für eine komplexe Beziehungsstruktur ist das soziale Geflecht von Freunden und Followern12. Hier werden u.a. Informationen zu indirekten Beziehungen benötigt, da man möglicherweise auch Informationen zu den Freunden der Freunde darstellen möchte. Eine Graphendatenbank besteht aus Knoten und Kanten. Während die Knoten immer eine Entität, z.B. eine Person, darstellen, stellen die Kanten die Beziehungen zwischen diesen Entitäten dar. Sowohl Knoten, als auch Kanten können Attribute enthalten, die die Entität oder Beziehung detaillierter beschreiben. 3.2.2. Vor- und Nachteile Graphendatenbanken ermöglichen es, reale Netzwerkstrukturen direkt abzubilden und somit das Verständnis für diese zu erleichtern. Der Einsatz wird jedoch ungleich komplex, falls sie für unpassende Anwendungsfälle verwendet werden. Die Suche in solchen Datenbanken bleibt unabhängig von der Größe der Netzwerkstrukturen stets performant. Diese Performance ergibt sich daraus, dass die graphenorientierten Darenbanken auf JOIN-Operationen13, wie man sie aus den relationalen Datenbanken kennt, verzichten können. Diese JOIN-Operationen 11 Ein soziales Netzwerk. Ein Benutzer dieses Netzwerkes kann eigene Meldungen veröffentlichen und andere Benutzer „beobachten“, so dass er Ihre Meldungen sieht. 12 Umschreibt den Beobachter eines Benutzers in einem sozialen Netzwerk (z.B. Twitter). 13 JOIN-Operationen werden verwendet, um mehrere Tabellen zusammenzuschließen. 15 Die wichtigsten NoSql-Datenbanktypen sind rechenintensiv, in einer relationalen Datenbank jedoch notwendig, um komplexe Beziehungsstrukturen überhaupt erst abfragen zu können. Will man beispielsweise alle Freunde einer Person in einer relationalen Datenbank darstellen, so müsste man diese Informationen in einer eigenen Tabelle festhalten, die die Verweise zwischen der aktuell betrachteten Person und ihren Freunden verwaltet. Um diese Informationen anzeigen zu können, wären bereits mehrere JOIN-Operationen notwendig. Würde man zusätzlich noch Bekannte der Freunde anzeigen wollen, so würde die Abfrage nicht nur unübersichtlich, sondern auch sehr langsam werden. Dieses Problem kann bei den Graphendatenbanken aufgrund ihrer Struktur umgangen werden. Die Traversierung der Kanten14 findet mit einer konstanten Geschwindigkeit statt. Da die theoretische Grundlage der graphenorientierten Datenbanken aus der Graphentheorie stammt, können viele bereits entworfene Algorithmen, wie z.B. der Algorithmus für das "Travelling Salesman Problem, verwendet werden, um das schnelle Navigieren in der Datenbank zu optimieren. Ein Nachteil besteht darin, dass die Nutzbarkeit komplizierter als in relationalen Datenbanken ist, da keine einfach verständliche Abfragesprache wie SQL zur Verfügung steht. 3.2.3. Ein Beispiel Anhand der Datenbank „Neo4j“ Eine weit verbreitete Graphendatenbank heißt „Neo4j“. Diese Datenbank lässt sich sowohl auf einem einzelnen Server, als auch auf einem verteilten System betreiben. Falls die Datenbank auf einem einzelnen Server läuft, hat sie die Besonderheit, dass sie den ACIDPrinzipien weitgehend folgt. Eine Ausnahme ist die unvollständige Datenintegrität. Zwar achtet Neo4j bei der Erstellung und Löschung von Kanten und Knoten darauf, dass diese nicht mehr in der Netzwerkstruktur verdrahtet sind, jedoch können weiterhin beliebige Daten in die Knoten geschrieben werden, da kein festes Schema für diese vorgegeben ist. Als ein verteiltes System wird die Konsistenz der Daten gelockert. In Folge dessen wird das ACID-Modell durch das BASE-Modell ersetzt. Die Knoten und Kanten werden in Neo4j erst geladen, sobald diese auch tatsächlich gefordert werden. Damit bleibt die Datenbank auch bei tiefgehenden Netzwerken performant. Durch die verwendete Struktur ermöglicht Neo4j es, bis zu zwei Millionen Kantenschritte pro Sekunde vorzunehmen. Bei einem sozialen Netzwerk von 1000 Personen, das auch die Freunde der Freunde darstellt, kann Neo4j bereits 1000 Mal schneller lesen als eine relationale Datenbank. Die Schreibgeschwindigkeit der Neo4j Datenbank hängt sehr stark von der verwendeten 14 Die Travesierung beschreibt das „Durchlaufen“ der Kanten. 16 Die wichtigsten NoSql-Datenbanktypen Festplatte ab. So kann man bei der Benutzung einer SSD-Festplatte15 Schreibgeschwindigkeiten von etwa 100.000 Operationen pro Sekunde erwarten. Neo4j hat viele Sprachanbindungen, die die Kommunikation mit der Datenbank ermöglichen. Somit müssen die Anfragen an die Datenbank in der Programmiersprache gestellt werden, die auch für die aktuelle Anwendung verwendet wird. Da sich die Abfragesyntax zwischen den Programmiersprachen unterscheidet, werde ich nicht weiter auf diese Sprachanbindungen eingehen. Neben diesen Sprachanbindungen wird aktuell noch eine Abfragesprache namens „Cypher“ von den Neo4j Erfindern entwickelt. Da diese Implementierung noch nicht abgeschlossen ist, kann sich die Syntax von Cypher jedoch noch ändern. Die Entwickler von Neo4j unternehmen mit Cypher den Versuch, eine für alle Programmiersprachen gültige Abfragesprache zur Verfügung zu stellen. Diese Abfragesprache werde ich im Folgenden an einigen Beispielen erläutern. Mit dem Befehl CREATE (A {name: "Node A"}), (B {name: "Node B", wert:42}) kann beispielsweise ein Knoten A mit dem Attribut name = „Node A“ und ein Knoten B mit den Attributen name = „Knoten B“ und wert = 42 angelegt werden. Eine Beziehung zwischen den Knoten kann bereits bei ihrer Erstellung hergestellt werden. In diesem Fall wird diese Beziehung jedoch erst mit dem nächsten Befehl erstellt: START a = node:node_auto_index(name=“Node A“), b = node:node_auto_index(name=“Node B“) CREATE a-[:kennt]->b Mit START wird der Punkt angegeben, bei dem die Suche in einem Graphen beginnt. Da keine Abfrage, sondern eine neue Beziehung erstellt werden soll, werden zwei Startpunkte benötigt, die lediglich die beiden gewünschten Knoten darstellen. Die Knoten werden üblicherweise über ihren Index ausgewählt. Dieser Index startet bei null und steigt mit der Anzahl der erzeugten Knoten an. Somit hätte der vorher erstellte Knoten A den Index 0 und Knoten B den Index 1. Um die Knoten auch ohne ihren Index auswählen zu können, wird mit :node_auto_index der passende Index zu dem gegebenen Attribut-Wert-Paar ermittelt. Bei dem CREATE wird daraufhin eine Beziehung zwischen den beiden ausgewählten Knoten erstellt. Diese Beziehung geht von Knoten A nach Knoten B und wird durch den Zusammenhang „kennt“ umschrieben. 15 Ein Solid-State-Drive hat einen anderen physischen Aufbau als normale Festplatten und ermöglicht dadurch schnellere Zugriffszeiten. 17 Die wichtigsten NoSql-Datenbanktypen Möchte man nun beispielsweise alle nachfolgenden Knoten von Knoten A haben, die mit einem „N“ beginnen, so müsste die Anfrage folgendermaßen formuliert werden: START n = node:node_auto_index(name="Node A") MATCH n-->follower WHERE follower.name =~ "N.*" RETURN follower.name Der Startpunkt der Anfrage ist Knoten A, der in der Anfrage als n bezeichnet wird. Über die MATCH-Anweisung kann angegeben werden, welche Beziehungen weiter untersucht werden sollen, d.h. über welche Beziehungen die Suche verlaufen soll. In diesem Beispiel wird die benötigte Beziehung nicht weiter spezifiziert, was durch den Pfeil „-->“ gekennzeichnet wird. Daher werden alle direkten Nachfolger von Knoten A betrachtet. Diese Nachfolger werden unter dem Alias „follower“ zwischengespeichert und weiter verarbeitet. Über die WHEREKlausel wird spezifiziert, dass die Nachfolger einen Namen, beginnend mit einem „N“ haben müssen. Die Namen der so gefundenen Knoten werden daraufhin zurück gegeben. Diese Beispiele zeigen nur einen kleinen Teil der vorhandenen Anweisungen und Befehle in Cypher. Die Abfragesprache scheint sehr mächtig zu sein, sobald man weiß wie man sie anwendet. 3.3. Dokumentorientierte Datenbanken 3.3.1. Einleitung Im Gegensatz zu relationalen Datenbanken, die die Daten in Tabellen speichern, arbeitet eine dokumentorientierte Datenbank mit sogenannten Dokumenten. Diese Dokumente sollten nicht als Textdateien, sondern als Sammelcontainer gesehen werden. Jeder Sammelcontainer enthält Schlüssel-Wert-Paare, jeder Wert darf einen nicht atomaren Inhalt, wie z.B. ein Feld oder eine Datei, beinhalten. Die Schlüssel müssen innerhalb eines Dokuments eindeutig sein, dürfen jedoch in jedem anderen Dokument vorkommen. 18 Die wichtigsten NoSql-Datenbanktypen 3.3.2. Vor- und Nachteile Da auch dieser Datenbanktyp schemafrei ist, kann jedes einzelne Dokument verschiedene Schlüssel enthalten und eine unterschiedliche Struktur besitzen. Daraus ergibt sich eine große Freiheit für den Anwender einer solchen Datenbank. Diese Freiheit bringt allerdings auch Nachteile mit sich. So muss die Struktur der Dokumente von dem Anwender selbst festgelegt und kontrolliert werden. Auch wird nicht geprüft, ob der eingegebene Wert wirklich korrekt ist und den Vorstellungen des Anwenders entspricht. Somit muss die Prüfung der Plausibilität auf die Anwendungsebene verlagert werden. Um zumindest ein geringes Maß an Strukturierung zu erreichen, versuchen die meisten dokumentorientierten Datenbanken die Daten in einem JSON-Format16 abzuspeichern und darzustellen, was die Nutzung dokumentorientierter Datenbanken erleichtert. Ein Ziel dokumentorientierter Datenbanken ist die Möglichkeit, zusammenhängende und große Daten geschlossen in der Datenbank abspeichern zu können. Dadurch werden das Verständnis und das Abrufen zusammenhängender Daten erleichtert, wodurch ein großer Vorteil für viele Anwendungsfälle entsteht. Ein gutes Anwendungsbeispiel sind die sogenannten Internet-Blogs17, die aus Blogeinträgen bestehen. Diese Blogeinträge setzen sich meistens aus langen Texten, Kommentaren und Tags zusammen und können in einzelnen Dokumenten abgespeichert werden. In Folge dessen wäre es auch einfach, den Blogeintrag aus der Datenbank auszulesen, indem man das dazu passende Dokument betrachtet. In relationalen Datenbanken müsste man die einzelnen Daten beim Abspeichern zunächst auf verschiedenen Tabellen verteilen und diese Daten bei einer Abfrage wieder durch JOIN-Operationen sammeln. Das Entfernen eines Blogeintrags aus einer relationalen Datenbank wäre ebenfalls komplizierter, da man darauf achten müsste, dass alle Verweise durch Fremdschlüssel korrekt entfernt werden. In einer dokumentorientierten Datenbank müsste man lediglich das Dokument löschen, um einen Blogeintrag zu entfernen. 16 Das JavaScript Object Notation Format ist standardisiert und weit verbreitet. Fast jede Programmiersprache hat passende Bibliotheken, um mit diesem Format arbeiten zu können. 17 Ein Internet-Blog ist eine Art Tagebuch oder Journal, in der eine Person Sachverhalte protokolliert oder Gedanken niederschreibt. 19 Die wichtigsten NoSql-Datenbanktypen 3.3.3. Ein Beispiel Anhand der Datenbank „MongoDB“ Aufgrund des nicht vorhandenen Standards unterscheiden sich die Implementierungen der dokumentorientierten Datenbanken enorm. In der Datenbank namens „MongoDB“ hat man beispielsweise die Möglichkeit, eine von den Entwicklern vorgegebene Abfragesyntax zu verwenden. Da MongoDB weit verbreitet ist, werde ich mich im Folgenden genauer mit dieser Datenbank befassen. Die Dokumente dieser Datenbank werden in dem BSON-Format18 gespeichert und im Arbeitsspeicher abgelegt. Diese Daten können von BSON-fähigen Clients abgerufen werden. Die Datenbank besteht aus beliebig vielen Collections und Dokumenten. Eine Collection ist eine Ansammlung von verschiedenen Dokumenten. Der Benutzer kann bestimmen, welche Collections er anlegt und welche Dokumente er in einer Collection abspeichert. Jedes Dokument bekommt eine ID, durch das es eindeutig identifiziert werden kann. Ein Befehl, um eine Collection mit einem Dokument anzulegen, wäre beispielsweise: db.NoSqlTypen.save({ Name: "Dokumentorientierte Datenbanken", Eigenschaften: "Arbeitet mit Dokumenten", Beispiele:[ "MongoDb", "CouchDb"] }) Durch diesen Befehl wird in der Datenbank „db“ eine Collection namens „NoSqlTypen“ angelegt. In dieser Collection wird ein Dokument mit den Inhalten Name = “Dokumentorientierte Datenbanken“, Eigenschaften = “Arbeitet mit Dokumenten“ und den Beispielen „MongoDb“ und „CouchDb“, die in einem Array gelagert werden, abgespeichert. Über den find-Befehl kann der Inhalt einer Collection abgefragt werden. Dabei werden alle Dokumente, die in der Collection vorhanden sind, im JSON-Format ausgegeben. Um die Ausgabe von mehreren Dokumenten darstellen zu können, wird im folgenden Beispiel angenommen, dass die NoSqlTypen-Collection nun zwei Dokumente verwaltet. Das Ergebnis des Aufrufs db.NoSqlTypen.find() 18 Das BSON-Format ist ein binäres JSON-Format. 20 Die wichtigsten NoSql-Datenbanktypen würde wie folgt aussehen: [ {Name: "Dokumentorientierte Datenbanken", Eigenschaften: "Arbeitet mit Dokumenten", Beispiele:[ "MongoDb", "CouchDb"]}, {Name: "Key-Value-Datenbanken", Eigenschaften: "Arbeitet mit Assoziativen Feldern", Beispiele:[ "Redis"]} ] Mit dem remove-Befehl können Dokumente selbstverständlich auch entfernt werden. So könnten bei der Verwendung des Befehls db.NoSqlTypen.remove({name: "Key-Value-Datenbanken"}) alle Dokumente, die den Parameter „Name“ mit dem Wert “Key-Value-Datenbanken” beinhaltet, gelöscht werden. Der update-Befehl kann verwendet werden, um Änderungen in einem Dokument vorzunehmen. Dabei können entweder das ganze Dokument oder nur bestimmte SchlüsselWert-Paare des Dokuments ersetzt werden. Ein Beispiel, das nur das Eigenschaften-Attribut ersetzt oder dieses hinzufügt, falls es noch nicht vorhanden ist, wäre: Db.NoSqlTypen.update( {name:"Dokumentorientiere Datenbanken"}, {"$set":{"Eigenschaften":"Gut für zusammenhängende Daten"}} ) Das Dokument wäre vollständig ersetzt worden, wenn man auf die von MongoDB bereitgestellte $set-Operation verzichtet hätte. MongoDB stellt mehrere solcher mit einem “$”-Zeichen eingeleiteter Operationen zur Verfügung. So gibt es u.a. auch Operationen, um einzelne Elemente mit dem update Befehl in ein Array einzufügen oder zu löschen. 3.4. Spaltenorientierte Datenbanken 3.4.1. Einleitung Die spaltenorientierten Datenbanken, auch Wide Column Stores genannt, verwenden ein grundlegend anderes Speicherprinzip als die relationalen Datenbanken. 21 Die wichtigsten NoSql-Datenbanktypen Während relationale Datenbanken die Daten zeilenweise im Speicher ablegen, werden die Datensätze einer spaltenorientierten Datenbank spaltenweise abgespeichert. Außerdem werden keine Tabellen, sondern so genannte „Column Families“ verwendet. Diese Column Families haben keine Struktur und können beliebig viele Spalten enthalten. Um das Speicherprinzip näher zu erläutern, sei an dieser Stelle das Beispiel einer Mitarbeiterliste in Tabelle 1 genannt: Tabelle 1: Beispiel einer Mitarbeiterliste MiarbeiterID Name Jahresgehalt 1 Muster 30000 2 Testperson 32000 Die Ablage dieser Daten im Speicher sähe für eine relationale Datenbank vereinfacht wie folgt aus: 1, Muster, 30000; 2, Testperson, 32000; Bei einer spaltenorientierten Datenbank würde die Ablage der Daten folglich anders aussehen: 1, 2; Muster, Testperson; 30000, 32000; Die Vorteile einer solchen Datenspeicherung werden im nächsten Abschnitt näher betrachtet. 3.4.2. Vor- und Nachteile Spaltenorientierte Datenbanken werden vor allem für Analyseprogramme verwendet. Die Durchführung einer Analyse (z.B. Summenbildung, Maximum-/Minimum-Berechnungen) erfordert oftmals nur wenige Spalten, jedoch alle Werte dieser Spalten. Bei einem relationalen Datenbanksystem müssten diese Werte zunächst gesammelt werden, indem die gewünschte Spalte jedes Datensatzes abgerufen wird. Durch diese Vorgehensweise müssten viele sequentielle Lesezugriffe vorgenommen werden, was einen zusätzlichen Zeitaufwand mit sich bringt. In einer spaltenorientierten Datenbank müsste die gewünschte Spalte lediglich einmal ermittelt werden. Die Werte der kompletten Spalte könnten daraufhin schnell abgefragt werden, indem durch den zugehörigen Arbeitsspeicher der Spalte iteriert wird. Die so entstandene Zeitersparnis stellt einen großen Vorteil von spaltenorientierten Datenbanken dar. Ein weiterer Vorteil gegenüber relationalen Datenbanken ergibt sich aus der Speicherersparnis. Dieser Vorteil wird aktuell jedoch kontrovers diskutiert und nicht von allen 22 Die wichtigsten NoSql-Datenbanktypen Datenbankexperten akzeptiert. Im Folgenden werden die Eigenschaften und Vorgehensweisen, die zu dieser Speicherersparnis führen, genauer betrachtet: - Im Datensatz einer relationalen Datenbank muss auch für leere Spalteneinträge Speicher reserviert werden. Bei spaltenorientierten Datenbanken kann ein leerer Eintrag einfach weggelassen werden. Die daraus entstandene Speicherersparnis wird häufig nicht als Vorteil angesehen, da gut strukturierte relationale Datenbanken (Normalisierung) keine leeren Einträge haben sollten und dieser Speicherunterschied somit wegfallen sollte. - Einige Befürworter behaupten, dass eine Speicherersparnis dadurch entsteht, dass gleiche Datentypen im Speicher nebeneinander gelagert werden. Dadurch können diese Daten besser an den Speicher angepasst werden. - Die Lagerung gleicher Datentypen nebeneinander ermöglicht eine Komprimierung der Daten über verschiedene leichtgewichtige Verfahren19. Diese Komprimierungsmethoden werden geschickt verwendet, so dass Operationen auf den komprimierten Daten vorgenommen werden können, ohne diese zuvor dekomprimieren zu müssen. Im Gegensatz zu relationalen Datenbanken können spaltenorientierte Datenbanken nicht besonders gut mit Ad-Hoc Abfragen20 umgehen. Daher muss die Struktur der Datenbank stets an die Datenbankabfragen, die man in der zugehörigen Anwendung verwenden möchte, angepasst werden. Somit ist der Grundsatz spaltenorientierter Datenbanken, dass die Daten so abgespeichert werden sollten, wie sie später abgefragt werden. Diese fehlende Flexibilität ist ein Nachteil dieses Datenbanktyps. 3.4.3. Ein Beispiel Anhand der Datenbank „Cassandra“ Als Beispiel spaltenorientierter Datenbanken sei in diesem Abschnitt die Datenbank „Cassandra“ genannt. Diese war ursprünglich ein Projekt von Facebook, wurde später jedoch unter der GNU General Public License freigegeben und von der Apache Software Foundation weiterentwickelt. Die Datenbank arbeitet als ein verteiltes System, das die Daten auf mehreren Servern aufteilen und replizieren kann. 19 Eine leichtgewichtige Komprimierungsmethode ist z.B. das Zusammenfassen von gleichen Sequenzen. Diese Methoden sind schnell und benötigen keinen komplexen Algorithmus, wie z.B. das LZW-Verfahren. 20 Ad-Hoc Abfragen sind flexible und schnelle Abfragen an ein System, die beliebige Daten zurückgeben können. Die Struktur der Daten spielt bei diesen Abfragen keine Rolle. 23 Die wichtigsten NoSql-Datenbanktypen Cassandra hat mehrere Bestandteile: - Keyspace: Definiert einen Bereich mit zusammenhängenden Daten. - Keys: Ein genauer Identifizierer für einen Datenbankeintrag. - Columns: Die Datenablage erfolgt in den Columns, wobei jede Column ein SchlüsselWert-Paar beinhaltet. - Super Columns: Die Super Columns können mehrere Columns zu einem größeren Eintrag zusammenfassen. So könnte es beispielsweise eine Column mit dem Eintrag „PLZ: 52062“ und eine Column mit dem Eintrag „Straße:Musterstraße“ geben, die gemeinsam in einer Super Column namens „Adresse“ zusammengefasst werden können. - Column Families: Die Column Families sind das Pendant zu den Tabellen in relationalen Datenbanken. Sie schließen die Columns und Super Columns zusammen. Die Daten in einer Column Family können durch die Verwendung der Keys abgefragt werden. Abbildung 1 zeigt eine beispielhafte Zusammensetzung einer Column Family, die Mitarbeiter verwaltet. Die Zeilen der Column Family enthalten einzelne Mitarbeiter, die Super Columns und Columns enthalten nähere Informationen zu diesen Mitarbeitern. Abbildung 1: Beispiel des Aufbaus einer Cassandra Column Family 24 Die wichtigsten NoSql-Datenbanktypen Eine gut strukturierte und an die Datenbankabfragen angepasste Cassandra-Datenbank kann enorme Performance-Vorteile mit sich bringen. Eine Präsentation der Cassandra-Entwickler Lakshman und Malik zeigt, dass die Schreibzeit bei einer über 50 GB großen Datenbank von 300 ms auf 0,12 ms und die Lesezeit bei dieser Datenmenge von 350 ms auf 15 ms sinkt, wenn man Cassandra statt MySql verwendet. Mittlerweile sind mehrere Bibliotheken für verschiedene Programmiersprachen vorhanden, die zur Kommunikation zwischen der Anwendung und der Cassandra-Datenbank dienen. Seit Juni 2011 stellt Cassandra eine Cassandra Query Language, kurz CQL, bereit, die sich sehr stark an SQL orientiert. Es können ähnliche Befehle wie in SQL verwendet werden: SELECT <COLUMN> FROM <COLUMN FAMILY> WHERE <KEY> = keyname; UPDATE <COLUMN FAMILY> SET <COLUMN> = value WHERE <KEY> = keyname; Diese Abfragesprache kann als zusätzlicher Vorteil der Cassandra Datenbank gesehen werden, da die starke Ähnlichkeit zu SQL einen Umstieg von relationalen Datenbanken zu spaltenorientierten Datenbanken erleichtert. 25 Verwendete Technologien 4. Verwendete Technologien In diesem Kapitel möchte ich auf einige häufig in NoSql-Datenbanken verwendete Technologien eingehen. Dazu gehören unter anderem das MapReduce Framwork, das vor allem in verteilten Systemen benötigt wird, um Daten von mehreren Servern zu sammeln, und das Multiversion Concurrency Control Verfahren, das in fast allen NoSql-Datenbanken verwendet wird. 4.1. MapReduce 4.1.1. Einleitung MapReduce bezeichnet ein von Google eingeführtes Framework zur nebenläufigen Bearbeitung großer Datenmengen. Das Framework nimmt ein Set von Schlüssel-Wert-Paaren an, benutzt eine Map- und eine Reduce-Funktion um dieses Set zu verarbeiten und gibt ein neues Set mit Schlüssel-Wert-Paaren als Ergebnis dieser Verarbeitung zurück. Das zurückgegebene Set kann andere Datentypen enthalten, als das zur Verfügung gestellte Set. Die Map- und Reduce-Funktionen spielen eine zentrale Rolle in dem Verfahren und müssen anwendungsspezifisch implementiert werden. Das MapReduce Framework wird in sehr vielen verteilten NoSql-Datenbanken, wie z.B. in Cassandra oder in MongoDB verwendet. Das Framework ermöglicht es den Datenbanken, eine Anfrage an die verschiedenen Server zu verteilen und die Antworten der Server wieder zu sammeln. 26 Verwendete Technologien 4.1.2. Verfahrensablauf Die zu verarbeitenden Daten werden zunächst in Blöcke aufgeteilt, die jeweils einem Schlüssel zugewiesen werden. Durch diesen Vorgang entsteht ein Set mit Schlüssel-WertPaaren. Die Einträge dieses Sets werden an mehrere Map-Prozesse, die unabhängig auf verschiedenen Servern laufen können, aufgeteilt. Diese Prozesse verwenden die MapFunktion, um die Daten weiter zu verarbeiten. Eine Map-Funktion nimmt ein Schlüssel-WertPaar entgegen und erstellt daraus ein neues Set mit Zwischenergebnissen. Die Zwischenergebnissets aller Map-Prozesse werden daraufhin schlüsselweise zusammengefasst, so dass eine Liste von Werten zu jedem Schlüssel entsteht. Dieses Zusammenfassen wird auch „Shuffle“ genannt. Die Schlüssel und die zugehörigen Wertelisten werden dann an verschiedene Reduce-Prozesse verteilt. Diese Prozesse sind genauso wie die Map-Prozesse voneinander unabhängig, verwenden diesmal jedoch die Reduce-Funktion, um die Daten verarbeiten zu können. Die Reduce-Funktion fasst die Wertlisten zu einer bestimmten Anzahl an Ergebnissen zusammen, so dass neue Schlüssel-Wert-Paare entstehen, die die Ergebnisse darstellen. Die Reduce-Funktion wird meistens so gewählt, dass nur noch wenige Werte zu einem Schlüssel übrig bleiben. Die so entstandenen Schlüssel-Wert-Paare werden in einem Set gesammelt und als Ergebnis an den Benutzer zurück gegeben. 4.1.3. Ein Beispiel zu MapReduce Abbildung 2 stellt den Ablauf des MapReduce-Verfahrens anhand eines Beispiels dar. Die Eingangsdaten bestehen aus einer Datei, die die Flugpreise von Flughafen A nach Flughafen B enthält. Jede Zeile enthält einen Fluganbieter, einen Monat und eine Liste der Flugpreise, die in diesem Monat verfügbar waren. Es soll der günstigste Flugpreis des ganzen Jahres für jeden Anbieter ermittelt werden. 27 Verwendete Technologien Abbildung 2: Beispiel für das MapReduce Verfahren Die Daten werden zunächst in etwa gleich große Blöcke aufgeteilt (Splitting). Daraufhin sucht die Map-Funktion den günstigsten Preis für jede übergebene Zeile und speichert diesen unter einem Anbieterschlüssel ab. Nach diesem Schritt werden die vorhandenen Schlüssel-WertPaare nach dem Anbieter gruppiert, so dass jeder Anbieterschlüssel eine Liste von Preisen enthält (Shuffling). Aus diesen Listen sucht die Reduce-Funktion schließlich den günstigsten Preis aus und gibt diesen mit dem passenden Anbieterschlüssel als Ergebnis zurück. 28 Verwendete Technologien 4.2. Multiversion Concurrency Control Das Multiversion Concurrency Control Verfahren, auch MVCC-Verfahren genannt, wird in NoSql-Datenbanken dazu verwendet, konkurrierende Zugriffe auf Datensätze zu kontrollieren und zu verwalten. Es soll ermöglichen, Sperren, wie man sie aus relationalen Datenbanken kennt, zu umgehen und somit eine hohe Verfügbarkeit auch auf verteilten Datenbanksystemen zu erreichen. Um dies zu ermöglichen wird bei jedem Einfügen, Ändern oder Löschen eines Datensatzes eine neue Version dieses Datensatzes erstellt. Damit eine korrekte zeitliche Reihenfolge zwischen diesen Versionen bereitgestellt werden kann, verweist die neue Version eines Datensatzes stets auf die ältere Version. Dies kann beispielsweise durch Zeitstempel gewährleistet werden. Durch diese Versionierung und den Verzicht auf Sperren, hat man immer die Möglichkeit, einen Datensatz zu lesen. Dieser Datensatz ist möglicherweise nicht der aktuellste, jedoch steht er immer zur Verfügung, so dass die Anfragezeiten möglichst gering gehalten werden können. Abbildung 2 zeigt die konfliktfreie Vorgehensweise bei der zeitgleichen Änderung und Abfrage eines Datensatzes. Abbildung 3: Konfliktfreie Vorgehensweise bei dem MVCC-Verfahren Das Erstellen neuer Versionen kann in manchen Fällen zu Konflikten führen. So kann es dazu kommen, dass die aktuelle Version von mehreren Prozessen gleichzeitig gelesen wird und auf Basis dieser gelesenen Version mehrere Änderungen vorgenommen werden. Das Datenbank 29 Verwendete Technologien Management System vergleicht in einem solchen Fall zunächst, welche Änderungen in den jeweiligen neuen Versionen vorgenommen wurden. Es können alle Änderungen übernommen werden, falls sich diese Änderungen auf verschiedene Attribute beziehen. Wenn sich die Änderungen jedoch auf dasselbe Attribut beziehen, muss die Transaktion abgebrochen werden. In Folge dessen wird ein Fehler an die Prozesse, die die neuen Versionen erstellen wollten, verschickt. Abbildung 3 zeigt, wie ein Konflikt bei dem MVCC-Verfahren entstehen kann. Abbildung 4: Entstehung eines Konflikts bei dem MVCC-Verfahren Durch das Abspeichern mehrerer Versionen desselben Datensatzes, steigt der Speicherverbrauch von Datenbanken, die das MVCC-Verfahren verwenden. Um nicht zu viel Speicher für die unterschiedlichen Versionen aufwenden zu müssen, werden alte Versionen daher in einstellbaren Zeitabständen gelöscht. 30 Zusammenfassung 5. Zusammenfassung Der Ursprung der NoSql-Datenbanken liegt bereits weit zurück. Zwar wurden die Ideen und Modelle dieser Datenbanken durch das relationale Modell verdrängt, jedoch erhalten sie mittlerweile wieder eine wichtige Rolle, da sie besser als relationale Datenbanken mit der großen und ständig steigenden Datenmenge umgehen können. Bei der Vorstellung der vier wichtigsten NoSql-Datenbanktypen und dem Vergleich dieser zum relationalen Modell, konnte man bereits erkennen, dass NoSql-Datenbanken keine Allzwecklösungen sind. Bei der richtigen Verwendung können sie jedoch eine sehr gute Verfügbarkeit, Ausfalltoleranz und horizontale Skalierbarkeit bereit stellen. Um diese drei Eigenschaften, die auch die Ziele der NoSql-Datenbanken darstellen, gewährleisten zu können, muss bei der Implementierung von verteilten NoSql-Datenbanken auf die permanente Konsistenz der Daten verzichtet werden. Der Grund dafür liegt bei dem CAP-Theorem, das besagt, dass Ausfalltoleranz, Verfügbarkeit und Konsistenz nicht zur gleichen Zeit erreicht werden können. Die Folge daraus ist, dass das ACID-Konsistenzmodell für die meisten NoSql-Datenbanken nicht mehr gültig ist, so dass ein neues Konsistenzmodell namens „BASE“ eingeführt und verwendet wird. Dieses besagt, dass die Daten zwar nicht ständig, jedoch zeitweise Konsistent sind. Um diese zeitweise Konsistenz zu erreichen, wird eine Versionierung der Datensätze durch die Verwendung des MVCC-Verfahrens bereitgestellt. Neben diesem Verfahren ist das MapReduce-Verfahren ebenfalls äußerst wichtig für NoSqlDatenbanken. Dieses Verfahren ermöglicht es, Daten auf einem verteilten System zu suchen und schlussendlich zusammenzuführen. 31 Ausblick 6. Ausblick Im Gegensatz zu relationalen Datenbanken sind NoSql-Datenbanken nicht standardisiert, was viele Unternehmen von der Verwendung dieser Datenbanken abschreckt. Trotz allem haben sich bereits einige große Unternehmen an die NoSql-Datenbanken herangetraut und diese erfolgreich in ihre Systeme integriert. Dadurch gewinnen NoSql-Datenbanken ständig an Bedeutung, was vermutlich auch weiterhin der Fall sein wird. Relationale Datenbanken sind zwar ausgereifter als NoSql-Datenbanken, allerdings besteht bei NoSql-Datenbanken auch weiterhin viel Potential für neue Fortschritte und Ideen. Die Vorteile, die solche Datenbanken mit sich bringen, werden auch weiterhin viel Aufmerksamkeit auf sich ziehen. 32 Literatur- und Quellenverzeichnis 7. Literatur- und Quellenverzeichnis Browne, J. (01 2009). JulianBrowne.com. Abgerufen am 12 2012 von http://www.julianbrowne.com/article/viewer/brewers-cap-theorem DataStax Corporation. (03 2012). Abgerufen am 12 2012 von http://www.datastax.com/resources/whitepapers/nosql Dean, J., & Sanjay, G. (2004). Google Inc. Abgerufen am 12 2012 von http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com /de//archive/mapreduce-osdi04.pdf EliteInformatiker.de. (08 2011). Abgerufen am 12 2012 von http://eliteinformatiker.de/2011/08/07/zeilenorientierte-und-spaltenorientiertedatenbanken/ EliteInformatiker.de. (06 2011). Abgerufen am 12 2012 von http://eliteinformatiker.de/2011/06/01/nosql-key-value-datenbanken-memcachedb-projectvoldemort-redis/ Ellis, J. (02 2012). DataStax Corporation. Abgerufen am 12 2012 von http://www.datastax.com/dev/blog/schema-in-cassandra-1-1 FH Koeln Wiki. (07 2011). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/CAP FH Koeln Wiki. (07 2011). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/Neo4j FH Koeln Wiki. (07 2011). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/Cassandra FH Koeln Wiki. (07 2011). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/MVCC FH Koeln Wiki. (08 2012). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/KeyValueSysteme FH Koeln Wiki. (11 2012). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/BASE FH Koeln Wiki. (10 2012). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/MongoDB FH Koeln Wiki. (06 2012). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/DokumentenorientierteDatenbank FH Koeln Wiki. (07 2012). Abgerufen am 12 2012 von http://wikis.gm.fhkoeln.de/wiki_db/Datenbanken/MapReduce 33 Literatur- und Quellenverzeichnis Gehrels, B. (07 2012). Humboldt Universität zu Berlin. Abgerufen am 12 2012 von http://www.informatik.huberlin.de/forschung/gebiete/wbi/teaching/studienDiplomArbeiten/running/exposediplomarbeit-benjamin-gehrels.pdf Heise.de. (06 2010). Abgerufen am 12 2012 von http://heise.de/-1012483 IBM Corporation. (01 2012). Abgerufen am 12 2012 von http://www01.ibm.com/software/data/bigdata/ Jansen, R. (12 2010). Heise.de. Abgerufen am 12 2012 von http://heise.de/-1152559 Lakshman, A., & Malik, P. (07 2009). Cassandra Entwickler. Von http://de.slideshare.net/Eweaver/cassandra-presentation-at-nosql abgerufen Meyer, M. (07 2010). Abgerufen am 12 2012 von http://t3n.de/magazin/relationale-datenbankenbekommen-konkurrenz-nosql-neues-224737/ Neubauer, P. (03 2010). Entwickler.de. Abgerufen am 12 2012 von http://entwickler.de/zonen/portale/psecom,id,101,online,2919,.html Neubauer, P. (03 2010). IT-Republik.de. Abgerufen am 12 2012 von http://itrepublik.de/jaxenter/artikel/Graphendatenbanken-NoSQL-und-Neo4j-2906.html Rauch, H. (02 2011). Uni Stuttgart. Abgerufen am 12 2012 von http://de.slideshare.net/HenningRauch/vortrag-graphendatenbanken-uni-stuttgart Redis.io. (kein Datum). Abgerufen am 12 2012 von http://redis.io/ Schnelle, J. (08 2010). pro-linux.de. Abgerufen am 12 2012 von http://www.prolinux.de/artikel/2/1455/3,einleitung.html Soetheer, N. (08 2012). InnoGames. Abgerufen am 12 2012 von http://de.slideshare.net/battlerattle/redis-14013799 Strozzi, C. (2007, 2008, 2009, 2010). Strozzi.it. Abgerufen am 12 2012 von http://www.strozzi.it/cgibin/CSA/tw7/I/en_US/nosql/Home%20Page Ubuntuusers Wiki. (08 2012). Abgerufen am 12 2012 von http://wiki.ubuntuusers.de/Redis Wessendorf, M., & Warzecha, B. (2009 12). IT-Republik.de. Abgerufen am 12 2012 von http://itrepublik.de/jaxenter/artikel/NoSQL-%96-Schoene-neue-Welt-2710.html Wikipedia.de. (05 2012). Abgerufen am 12 2012 von http://de.wikipedia.org/wiki/Graphdatenbank Wikipedia.de. (11 2012). Abgerufen am 12 2012 von http://de.wikipedia.org/wiki/MapReduce Wikipedia.de. (12 2012). Abgerufen am 12 2012 von http://en.wikipedia.org/wiki/Multiversion_concurrency_control Wikipedia.de. (12 2012). Abgerufen am 12 2012 von http://de.wikipedia.org/wiki/Datenbank Wikipedia.de. (12 2012). Abgerufen am 12 2012 von http://de.wikipedia.org/wiki/NoSQL