MongoDB - Riesige Datenmengen schemafrei verwalten

9
magazin Java Architekturen Web Agile www.javamagazin.de Österreich € 10,80 Schweiz sFr 19,50 Luxemburg € 11,15 Deutschland € 9,80 JAVA Mag 5.2014 Kommentar: Wie praxistauglich ist JSF wirklich? 74 WildFly 8 Neue Features plus Interview 64 MongoDB Big Data schemafrei verwalten 56 Alle Infos hier im Heft! 35 Clojure Testing: Alternatives Testframework Midje 14 Software- architektur: Beschränkte Mittel 36 Design for Diagnosability: Wenn das System sagt, was ihm weh tut 44 REACTIVE PROGRAMMING Event-basierte Architekturen und ihre Vorteile > 18 „Die reaktive Zukunft der JVM sieht rosig aus.“ Interview mit Jonas Bonér > 26

description

 

Transcript of MongoDB - Riesige Datenmengen schemafrei verwalten

Page 1: MongoDB - Riesige Datenmengen schemafrei verwalten

magazinJava • Architekturen • Web • Agile www.javamagazin.de

Österreich € 10,80 Schweiz sFr 19,50 Luxemburg € 11,15Deutschland € 9,80Java

Mag

5.2014

Kommentar: Wie praxistauglich ist JSF wirklich? 74

WildFly 8 Neue Features plus Interview 64

MongoDB Big Data schemafrei verwalten 56

Alle Infos hier im Heft!

35

Clojure Testing: Alternatives Testframework Midje 14

Software­architektur: Beschränkte Mittel 36

Design for Diagnosability: Wenn das System sagt, was ihm weh tut 44

Reactive PRogRamming

Event-basierte Architekturen und ihre Vorteile > 18

„Die reaktive Zukunft der JVM sieht rosig aus.“ Interview mit Jonas Bonér > 26

Java Magazin 5.2014

Reactive Program

ming

MongoDB

WildFly 8

JSF Clojure Testing

Softwarearchitektur

Design for Diagnosability

CONNECTED?

Page 2: MongoDB - Riesige Datenmengen schemafrei verwalten

von Tobias Trelle

Die Einstiegshürde bei MongoDB ist sehr niedrig. Ein-fach die Distribution für Ihre Plattform runterladen [2], entpacken und los geht’s. Das in C++ implementierte [3] Executable mongod (bzw. mongod.exe) für den Daten-bankserver liegt im Unterverzeichnis bin. Vor dem Start legen wir noch schnell das Default-Verzeichnis an, in dem MongoDB seine Dateien ablegt:

$ mkdir /data/db$ mongod

Danach horcht der Serverprozess bereits auf dem De-fault-Port 27017, 1 000 Ports höher können wir unter http://localhost:28017 auf ein rudimentäres Admin-GUI

zugreifen. Auf der Kommandozeile verwenden wir das Administrationswerkzeug unserer Wahl, die sog. Mon-go Shell, mit der wir uns zum Serverprozess verbinden:

$ mongoMongoDB shell version: 2.4.8connecting to: test

Wir sind jetzt mit einer leeren Datenbank test verbunden und können dort unser erstes Dokument persistieren:

> db.foo.insert( {hello: "MongoDB"} )

Beim Einfügen dieses einen Datensatzes haben wir be-reits viele Konzepte verwendet, die wir uns im Folgen-den im Detail ansehen werden.

Der Name MongoDB leitet sich vom englischen Begriff humongous ab, was so viel wie „gigantisch“ oder „wahnsinnig groß“ bedeutet. Dahinter verbirgt sich eine quell­offene, dokumentenorientierte NoSQL­Datenbank mit Ausfallsicherheit und horizon­taler Skalierung [1]. Was das im Einzelnen bedeutet, werde ich in diesem Artikel näher beleuchten.

© iS

tock

phot

o.co

m/v

_ale

x

Riesige Datenmengen schemafrei verwalten

MongoDB

javamagazin 5 | 2014

Datenbanken NoSQL­Serie – Teil 9

56 www.JAXenter.de

Page 3: MongoDB - Riesige Datenmengen schemafrei verwalten

StorageMongoDB verwaltet Nutzdaten und Indexe grundsätz-lich im RAM und synchronisiert den Arbeitsspeicher mittels des Betriebssystemdiensts mmap [4] periodisch mit dem Dateisystem. Nach dem transparenten Anlegen der Datenbank test und der Collection foo im obigen Beispiel sind im Datenbankverzeichnis /data/db folgen-de Dateien angelegt worden:

16M test.ns 64M test.0128M test.1...

Pro Datenbank gibt es eine .ns-Datei mit Metainfor-mationen sowie eine Reihe von Dateien mit Nutzdaten, die bei einer Größe 64 MB starten und sich jeweils ver-doppeln bis zu 2 GB. Da der mmap-Mechanismus per Default nur alle sechzig Sekunden (!) eine Synchronisa-tion vom RAM und Platte anstößt, gibt es zusätzlich ein Journaling aller schreibenden Operationen, das bei Ab-stürzen einen gewissen Grad an Durabilität sicherstellt. Dieses Journal ist ebenfalls dateibasiert, synchronisiert sich mit im Abstand von 100 ms allerdings wesentlich öfter. Nach einem Servercrash werden alle im Journal befindlichen Schreiboperationen angewandt, bevor der Server für weitere Anfragen zur Verfügung steht. Sie verlieren im Fehlerfall also maximal die Writes, die in den letzten 100 ms nach der letzten Synchronisierung des Journals stattfinden (dieses Intervall ist konfigurier-bar und kann zwischen 2 und 300 ms liegen).

DokumenteEinzelne Datensätze werden in MongoDB Dokumente ge-nannt. Dabei handelt es sich um eine geordnete Menge von Key-Value-Paaren (die man Felder nennt) mit der Eigen-schaft, dass die Werte auch Arrays und eingebettete Do-kumente sein können, also die hierarchische Struktur eines kompletten Objektnetzes abbilden können. Im Speicher und auf Platte werden Dokumente im BSON-Format [5] abgelegt. Dabei handelt es sich um ein binäres Format, das im Gegensatz zu seinem Vorbild JSON [6] aber u. a. über mehr Datentypen und eine bessere Traversierbarkeit verfügt. Das oben verwendete Dokument sieht im BSON-Format in Hexadezimalschreibweise wie folgt aus:

\x18\x00\x00\x00 \x02 hello\x00 \x08\x00\x00\x00MongoDB\x00\x00

Die Zeilenumbrüche sind dabei nur der besseren Lesbar-keit geschuldet und nicht Teil des Dokuments. Die nicht lesbaren Zeichen stellen die Länge des Dokuments, Da-tentyp des Felds, Länge des Strings sowie Endmarker dar. Da BSON-Dokumente schlecht menschenlesbar sind, werden wir im Folgenden stets mit der entspre-

chenden JSON-Darstel-lung arbeiten.

Für jedes Dokument ist ein Feld namens _id obligatorisch. Es nimmt den Primärschlüssel auf, der pro Collection (s. u.) eindeutig sein muss. Setzt man das Feld nicht selbst (was auch nicht empfoh-len wird), generieren die jeweiligen Treiber auto-matisch eine so genann-te Object-ID, eine zwölf Byte lange ID, die sich aus einem Zeitstempel, einer Maschinen- und Prozess-ID sowie einem fortlaufenden Zähler zu-sammensetzt. Diese ID wurde auch für unser Dokument von vorhin erzeugt, was wir sehen können, wenn wir das Dokument wieder suchen:

> db.foo.findOne(){ "_id" : ObjectId("52cf0d0383bf61d4ef4bd215"), "hello" : "MongoDB" }

Die maximale Größe eines Dokuments liegt bei 16 MB, sodass sich auch große Geschäftsobjekte darin ablegen lassen. Schreibende Operationen auf einem Dokument sind atomar im Sinne des ACID-Prinzips, von dem wir uns ansonsten im Laufe dieses Artikels leider eher ver-abschieden werden.

CollectionsDie logischen Namensräume zur Sammlung mehre-rer Dokumente heißen Collections und sind grob mit

Datenbank

Collection

Dokument

Feld

Index

MongoDB

Abb. 1: Strukturelemente eines MongoDB­Servers

ACID ade ...

Die ACID-Prinzipien [7] und Transaktionen relationaler Datenbanken werden Sie bei MongoDB (anfangs) schmerzlich vermissen. Änderungen an einzelnen Dokumenten sind zwar atomar, ein Rollback gibt es aber nicht, ganz zu schweigen von Transaktionsklammern, die mehrere schrei-bende Operationen umfassen. In der Praxis erweist sich die Abwesenheit von Transaktionen aber nicht zu einschränkend, da man sehr oft mit einem einzigen Dokument das erledigt, was in relationalen Systemen mehrere Tabellen umfassen würde. Die Dauerhaftigkeit der Daten wird auf Single-Server-Systemen durch das Journaling sichergestellt, bei produk-tiven Clustern zusätzlich durch die Replikation auf mehrere Knoten. Die Abwesenheit von Transaktionen ist jedoch nicht dem Unvermögen der MongoDB-Entwickler geschuldet, sondern beruht auf einer bewussten De-signentscheidung: Performance über alles. Insbesondere beim Sharding müsste ansonsten auf dem gesamten Cluster ein Lock vergeben werden, um übergreifende Transaktionen zu realisieren.

javamagazin 5 | 2014

DatenbankenNoSQL­Serie – Teil 9

57www.JAXenter.de

Page 4: MongoDB - Riesige Datenmengen schemafrei verwalten

der Tabelle einer relationalen Datenbank vergleichbar. Collections werden vor dem ersten Schreibzugriff au-tomatisch angelegt, was in unserem Beispiel auch mit der Collection foo passiert ist. Jede Collection liegt in genau einer Datenbank, die wiederum ein Container für mehrere Collections ist. Abfragen operieren immer auf genau einer Collection. Ein Zugriff auf Daten mehrerer Collections ist nicht möglich; das Konzept eines Joins wie bei relationalen Tabellen ist gänzlich unbekannt. Referenzen auf Dokumente sind über das Mitführen der Object-ID des referenzierten Dokuments dennoch möglich, müssen aber innerhalb der Anwendung selbst implementiert werden (oder durch Nutzung entspre-chender Frameworks).

Die CRUD-Operationen werden ebenfalls auf Ebene der Collection formuliert. Tabelle 1 zeigt die zur Verfü-gung stehenden Methoden.

QuerysZur Suche nach Dokumenten steht eine reichhaltige Abfragesprache zur Verfügung, die im Kern auf dem Prinzip Query by Example [8] basiert, angereichert um spezielle Operatoren. Formuliert werden Abfra-gen in Form von Dokumenten, was bei einer gewissen Komplexität schnell zu tief geschachtelten Strukturen führen kann. Eine einfache Suche nach Dokumenten,

bei denen ein Feld einen bestimmten Wert hat, wird so formuliert:

db.foo.find({hello: "MongoDB"})

Eine UND-Verknüpfung definiert sich über mehrere ein-schränkende Kriterien:

db.foo.find({hello: "MongoDB", version: 2})

Bereichsabfragen lassen sich über sog. Query-Operato-ren abbilden:

db.foo.find({v: {$gte: 2, $lt: 5}})

Diese Abfrage liefert alle Dokumente, bei denen das Feld v größer oder gleich 2 ist und kleiner als 5. Es gibt eine große Menge dieser Operatoren  [9] für die geläufigen Vergleichsoperationen, aber auch solche, die speziell auf Arrays und eingebetteten Dokumenten operieren. Ganz allgemein sind die Werte, gegen die verglichen wird, da-bei immer konstant. Abfragen, die Selbstbezüge innerhalb von Dokumenten benötigen, können allerdings mit einem eigenen Operator $where ausgeführt werden, was einen Scan aller Dokumente der Collection zur Folge hat (und daher tunlichst vermieden werden sollte) (z. B. Listing 1).

Als Ergebnis einer Abfrage wird stets ein Cursor zu-rückgeliefert, über den der Client iterieren kann. Dieser Cursor kann vor dem Lesen des ersten Dokuments noch modifiziert werden, um z. B. die Anzahl der Treffer zu beschränken oder eine gewisse Anzahl an Dokumenten zu überspringen.

Neben dieser Art von Abfragen gibt es noch eine Reihe weiterer Abfragetypen bzw. Indexarten, die wir

Listing 1

> db.where.insert({x:1, y:2})> db.where.insert({x:2, y:1})> db.where.find({$where: "this.x > this.y"}){ "_id" : ObjectId("52dce4171623840876c8ffe7"), "x" : 2, "y" : 1 }

Abfragetyp Beschreibung

Aggregation­Framework Ermöglicht aggregierende Operationen (analog zu GROUB BY in SQL), Umbenennung von Feldern, arithmetische und Datumsoperationen auf Feldern.

Map/Reduce Implementierung des Map/Reduce­Algorithmus [10], der auf den Daten einer Collection operiert. Ganz nett, aber kein Vergleich zu dedizierten Frameworks wie Hadoop.

Geodatensuche Ein brauchbares Subset des GeoJSON­Standards [11] kann als Daten abgelegt und mit eigenen Indexarten und Queryoperatoren gesucht werden. Umkreis­ oder Bereichssuchen lassen sich so sehr leicht implementieren.

Volltextsuche In Version 2.4 noch im experimentellen Status, gibt es einen eigenen Indextyp für Volltextsuche in Textfeldern samt Stemming, Stop­Word­Listen usw. Es reicht nicht an ein Lucene­basiertes Solr oder Elasticsearch heran, ist dafür aber nahtlos integriert.

Tabelle 2: Weitere Mittel für Abfragen im Überblick

Operation Beschreibung

db.<collection>.insert(<dokument>, ...) Fügt ein bzw. mehrere Dokumente ein.

db.<collection>.find(<kriterien>) Sucht Dokumente und liefert einen iterierbaren Cursor zurück.

db.<collection>.findOne(<kriterien>) Sucht und liefert genau ein Dokument zurück.

db.<collection>.findAndModify(<kriterien>,<update>) Sucht, ändert und liefert die Dokumente zurück.

db.<collection>.update(<kriterien>,<update>, <upsert>,<multi>)

Ändern von Dokumenten. Bei gesetztem Upsert Flag wird ein Dokument angelegt, falls zuvor keins existiert, das den Suchkriterien entspricht.

db.<collection>.remove(<kriterien>) Löschen von Dokumenten.

Tabelle 1: CRUD­Operationen im Überblick

javamagazin 5 | 2014

Datenbanken NoSQL­Serie – Teil 9

58 www.JAXenter.de

eclipse total!

Jetzt bestellen unter eclipse-magazin.de/abo oder unter +49 (0) 6123 9238-239 (Mo – Fr, 8 – 17 Uhr)

Ihre Vorteile auf einen Blick:1. Frei-Haus-Lieferung des Print-Magazins

2. Zugriff auf die Magazine mit der Eclipse-Magazin-App für iOS und Android

3. Offline-PDF-Export mit der Intellibook-ID

Page 5: MongoDB - Riesige Datenmengen schemafrei verwalten

kurz erwähnen wollen, deren ausführliche Betrachtung allerdings den Umfang dieses Artikels deutlich ausdeh-nen würde (Tabelle 2). Um die Laufzeit von Abfragen zu optimieren, können Indexe definiert werden.

IndexePro Collection können bis zu 64 Indexe auf einzelnen Feldern bzw. Feldgruppen definiert werden. Intern ver-wendet MongoDB zu Verwaltung der Indexe B-Tree-Datenstrukturen [12]. Neben dem obligatorischen Primärschlüsselindex auf dem Feld _id können Sie also beliebige Sekundärindexe anlegen; dies ist auch im Nachhinein möglich. Angelegt werden Indexe durch die idempotente Operation ensureIndex:

db.foo.ensureIndex( {hello: 1} )

Danach verwenden Abfragen auf dem Feld hello den Index, was Sie mit dem Cursor-Modifier explain() nach-prüfen können. Metainformationen über Indexe werden in der System-Collection system.indexes abgelegt und können dort eingesehen werden.

Um festzustellen, welche Abfragen Langläufer sind und mit Indexen beschleunigt werden könnten, setzen Sie den internen Profiler ein, der bei Bedarf langsame Querys (per Default alles, was länger als 100 ms dauert)

in der Collection system.profile aufzeichnet, die Ihnen dann zur weiteren Analyse zur Verfügung stehen.

SchemafreiheitEin wichtiges Alleinstellungsmerkmal von MongoDB ist die Schemafreiheit (oder auch -flexibilität). Es gibt keinen Mechanismus, der Dokumenten innerhalb einer Collection eine bestimmte Struktur oder Datentypen für bestimmte Felder aufzwingt:

db.foo.insert({a:1, b: [5, "drei"]})db.foo.insert({a: "zwei", c: {d: 42}})

Primary

Secondary 1 Secondary 2 Secondary n

Abb. 2: Initialer Zustand des Replica Sets

DatenbankenNoSQL­Serie – Teil 9

jessica
Schreibmaschinentext
Anzeige
Page 6: MongoDB - Riesige Datenmengen schemafrei verwalten

Ob es fachlich Sinn ergibt, völlig unterschiedliche Dokumentarten in einer Collection zu verwalten, be-urteilen Sie besser selbst. Inhalte, deren Struktur Sie als Entwickler aber gar nicht oder nur teilweise zur Entwicklungszeit kennen können, z. B. User Generated Content, können so gut in einem Dokument verwaltet werden. Als Paradebeispiel werden gerne semistruktu-rierte Produktkataloge oder Blogsysteme mit beliebig tief strukturierten Kommentaren angeführt. Allgemein lassen sich komplexe Objektnetze und insbesonde-re Vererbung ohne den allseits beliebten Impedance Mismatch relationaler Datenbanken gut in den Griff kriegen. Bei Änderungen an der Fachlichkeit (wir sind ja schließlich agil unterwegs) können Sie mit etwas Ge-schick eine schleichende Migration ihrer Daten on the fly realisieren.

Mit der größeren Freiheit wächst natürlich auch die Verantwortung für das eigene Handeln. Da es kein Schema gibt, müssen die Feldnamen in jedem Doku-ment abgespeichert werden. Allzu lange und sprechende Feldnamen bei extrem hohem Datenvolumen also besser vermeiden. Darüber hinaus ist Ihre Anwendung nun die einzige Instanz, die eine technische Validierung der Da-ten vornimmt. Wo früher die Datenbank bei zu langen Strings oder gar falschen Datentypen den Schreibvor-gang verweigert hat, schreibt MongoDB den Datensatz einfach weg. Das aber sehr schnell.

Replica SetsDie Ausfallsicherheit wird über den Einsatz von Re-plica Sets sichergestellt (Abb. 2). Dabei handelt es sich im Prinzip um einen Master/Slave-Cluster, in dem es einen so genannten Primary und mehrere Secondaries gibt. Der Primary ist der einzige Knoten, der Schreib-zugriffe verarbeitet und an die Secondaries repliziert. Lesezugriffe können wahlweise an beide Arten von Knoten gestellt werden. Im Gegensatz zu einem klas-sischen Master/Slave-Betrieb wählen bei Ausfall oder Nichterreichbarkeit des Primarys die verbleibenden Secondaries einen neuen Primary, sodass der Betrieb ohne Eingreifen aufrechterhalten werden kann (Abb. 3 und 4). Darüber hinaus können spezielle Seconda ries zu Reporting- oder Back-up-Zwecken konfiguriert werden.

Die Replikation wird technisch über das so genannte Oplog realisiert, eine rollierende Collection, in der alle verändernden Operationen aufgezeichnet werden. Das Replikationsprotokoll überträgt diese Operationen an die Secondaries, die diese dann auf ihren lokalen Da-tenbestand anwenden. Bis schreibende Operationen auf alle oder zumindest die Mehrheit aller Knoten im Repli-ca Set propagiert werden, kann eine gewisse Zeit verge-hen. Innerhalb dieser Zeitspanne ist das Gesamtsystem in einem inkonsistenten Zustand, da Lesezugriffe auf Secondaries ggfs. nicht alle über den Primary geschrie-benen Daten liefern. Diesen Zustand nennt man im Englischen eventual consistent, was schlussendlich kon-sistent heißt.

Shard #2

Chunk #3

Shard #1

Chunk #1 Chunk #2

Schlüssel$minKey i -1 i j -1 j $maxKey

Abb. 5: Verteilung der Daten anhand des Shard Keys

Primary

Secondary 1 Primary Secondary n

PPPPPPPrrrriiimmmaaaaarrrryyyyyyyrimmaa

Abb. 4: Neuer Primary wurde gewählt

Primary

Secondary 1 Secondary 2 Secondary n

PPPPPPPrrrriiimmmaaaaarrrryyyyyyyrimmaa

Abb. 3: Ausfall des Primary­Knotens

Shard #1(mongod)

Anwendung

Shard #2(mongod)

Konfig-Server

(mongod)

Router(mongos)

Abb. 6: Rollen beim Sharding

javamagazin 5 | 2014

Datenbanken NoSQL­Serie – Teil 9

60 www.JAXenter.de

Page 7: MongoDB - Riesige Datenmengen schemafrei verwalten

kennt nur Informationen über die Infrastruktur der Umgebung und speichert keinerlei Nutzdaten ab.

•Die Konfigurationsserver sind die Buchhalter, die über die einzelnen Chunks auf den Shards und deren Verteilung anhand des Shard Keys informiert sind. Auch hier werden keine Nutzdaten abgelegt.

•Ein Shard kann ein einzelner mongod-Prozess sein oder in produktiven Systemen besser ein ganzes Re-plica Set, das die eigentlichen Daten verwaltet.

Beim Schreiben von Daten befragt der Router die Kon-fig-Server, in welchen Chunk auf welchem Shard das Dokument eingefügt bzw. geändert werden soll und delegiert die entsprechende Operation an den passen-den Shard (Abb. 6). Bei Abfragen, die idealerweise den Shard Key als Teil der Suchkriterien verwenden, gibt der Konfig-Server Auskunft darüber, welcher Shard bzw. welche Gruppe von Shards die gewünschten Daten vor-hält, sodass eine gezielte Abfrage einer Teilmenge aller Knoten erreicht wird.

In produktiven Systemen wird empfohlen, mit drei Konfig-Servern zu arbeiten. Pro Instanz eines Applica-

ShardingUm horizontal zu skalieren, setzt MongoDB auf das so genannte Sharding, bei dem die Daten einer Collection redundanzfrei auf mehrere Shards verteilt werden. Die Verteilung der Dokumente passiert anhand eines einmal festzulegenden Schlüssels, des Shard Keys, der analog zu einem Index aus einem Feld oder einer Feldgruppe bestehen kann. Die Dokumente werden dabei in Blöcke, genannt Chunks, zusammengefasst. Wenn die Größe eines Chunks eine bestimmte Grenze (Default: 64 MB) übersteigt, erfolgt eine Aufteilung des Wertebereichs und ein neuer Chunk entsteht, der ggf. nun auf einem anderen Shard liegt (Abb. 5).

Ein interner Balancer sorgt dafür, dass die Chunks im-mer in etwa gleichmäßig über die Shards verteilt werden, um die Last auch entsprechend gleichmäßig verteilen zu können. Das Set-up für eine Sharding-Umgebung bringt eine gewisse Komplexität mit sich, da hier drei verschie-dene Rollen von Serverprozessen zum Einsatz kommen:

•Der Router nimmt die Anfragen der Anwendung ent-gegen und delegiert diese an die einzelnen Shards. Er

Technische Eigenschaften

Datenmodell Dokumentenorientiert, d. h. ein einzelner Datensatz besteht aus einer geordneten Menge von Key­Value­Paaren mit reichhaltigen Datentypen; Arrays und eingebettete Dokumente erlauben hierarchische Strukturen; Felder bzw. Feldgruppen können mit Sekundärindexen belegt werden

Suchmöglichkeiten Reichhaltige Query­Language, Aggregation­Framework, Map/Reduce, Geodaten mit Bereichssuchen, rudimentäre Volltextsuche

Integration in BI­Tools Pentaho, Jaspersoft, Hadoop­Adapter

Typisches Einsatzszenario Event Logging, semistrukturierte Daten, komplexe Objektnetze, hohe Schreib­/Leseoperationen

Horizontale Skalierbarkeit Sharding zur Skalierung von Lese­ und Schreibzugriffen, Replica Sets zur Skalierung von Lesezugriffen

Hochverfügbarkeit Replica Sets mit automatischem Failover, Master/Slave­Betrieb

Implementiert in C++

Unterstützte Betriebssysteme Linux, Solaris, Mac OS, Windows

Monitoring­Werkzeuge mongostat, mongotop, MMS (Cloud­Dienst und On­Premise)

Back­up­Lösung Manuell über Dateisystem, MMS (Cloud­Dienst und On­Premise)

Lizenz und Support

Aktuelles stabiles Release 2.4.8 (2.6 erscheint in Kürze)

Open Source Ja. Lizenz ist größtenteils GNU Affero General Public License (AGPL); Teile stehen unter Apache License, Version 2.0; Quellcode auf GitHub: https://github.com/mongodb/mongo

Kosten der kommerziellen Version Siehe [16]

Features der kommerziellen Version Kerberos­Authentifizierung, SNMP, SSLMMS (MongoDB Monitoring Service): http://mms.mongodb.comMonitoring und Back­up­Dienste

Zusätzlicher professioneller Support Verfügbar

Nutzung mit der JVM

Java­APIs Java­Treiber siehe [17]

APIs für andere JVM­Sprachen Scala, Groovy

APIs für andere Non­JVM­Sprachen MongoDB Drivers and Client Libraries, siehe [13]

Object Mapper (Java) Spring Data MongoDB, Morphia, JongoJPA­Provider: Eclipse Link MongoDB, Data Nucleus, Hibernate OGM

Tabelle 3: Spezifikation von MongoDB

javamagazin 5 | 2014

DatenbankenNoSQL­Serie – Teil 9

61www.JAXenter.de

Page 8: MongoDB - Riesige Datenmengen schemafrei verwalten

tion Servers können Sie jeweils einen eher leichtgewich-tigen Routerprozess betreiben. Jeder Shard sollte intern durch ein Replica Set zwecks Ausfallsicherheit realisiert sein, sodass eine produktive Umgebung zum Beispiel so aussehen kann wie in Abbildung 7.

APIClientanwendungen verbinden sich über ein proprietä-res binäres TCP/IP-basiertes Kommunikationsprotokoll mit einem MongoDB-Server bzw. einem Routerpro-zess. Daneben existiert eine REST-artige Schnittstelle, die sich aber maximal zu Testzwecken einsetzen lässt und nur Lesezugriffe unterstützt. Für nahezu alle gän-gigen und auch exotische Sprachen gibt es eine Treiber-

Write Concern – der Grad an Sicherheit

Der so genannte Write Concern legt bei schreibenden Operationen den Grad an Sicherheit fest, mit dem Sie Ihre Daten persistiert wissen wollen. Er setzt sich aus den folgen-den vier Attributen zusammen:

■ w: Anzahl an Knoten, die Schreiboperationen als erfolg-reich bestätigen müssen. Der symbolische Wert "majority" erfordert bei Replica Sets die Bestätigung von der aktuel-len Mehrheit der Knoten. Default ist 1.

■ wtimeout: Timeout in Millisekunden. Erfolgt nach dieser Schwelle keine Rückmeldung, liegt ein Fehler vor. Per Default ist der Timeout unendlich.

■ j: Diese boolesche Flag steuert, ob bis zur nächsten Syn-chronisation des Journals gewartet werden soll. Default ist false.

■ fsync: Diese boolesche Flag steuert, ob die Daten direkt auf die Platte durchsynchronisiert werden sollen. Default ist false, da dies i.d.R. eine sehr teure Operation wäre.

Viele Treiber bieten für die gängigsten Kombinationen dieser Parameter Konstanten an, so auch der Java-Treiber [13].

bibliothek, die den Zugriff auf das Backend in einem relativ einfachen API kapselt, da Dokumente sich sehr einfach auf eine Map oder ein assoziatives Array abbil-den lassen.

Der Java-Treiber ähnelt vom Abstraktionsgrad eher dem JDBC-API. Zentrale Klassen sind DB, DBCollec-tion und BasicDBObject im Paket com.mongo, die eine Datenbank, eine Collection und ein Dokument zugreif-bar machen.

Aufbauend auf dem Treiber gibt es in Java (und ande-ren OO-Sprachen) Frameworks zum Object/Document Mapping (als Analogon zum O/R Mapping). Als wich-tigste Vertreter sind hier Morphia, Spring Data Mon-goDB und Jongo zu nennen [14], [15]. Diese bieten u. a. eine annotationsbasierte Abbildung von Klassen auf Dokumente, simplere Formulierung von Querys und einiges mehr.

Dipl.-Math. Tobias Trelle ist Senior IT Consultant bei der codecen-tric AG, Solingen. Er ist seit knapp zwanzig Jahren im IT-Business unterwegs und interessiert sich für Softwarearchitekturen und ska-lierbare Lösungen. Tobias hält Vorträge zum Thema NoSQL und MongoDB auf Konferenzen und Usergruppen und ist Autor des Buchs „MongoDB – Ein praktischer Einstieg“ im dpunkt.verlag.

Konfig-

Server #3

Shard #1

Primary

Secondary

Secondary

Shard #2

Primary

Secondary

Secondary

Shard #n

Primary

Secondary

Secondary

Konfig-

Server #2

Konfig-Server #1

Router #1

ApplicationServer #1

Router #m

ApplicationServer #m

...

...

Abb. 7: Produktive Sharding­Umgebung

Links & Literatur

[1] http://www.mongodb.org

[2] http://www.mongodb.org/downloads

[3] https://github.com/mongodb/mongo

[4] http://en.wikipedia.org/wiki/Mmap

[5] http://bsonspec.org/

[6] http://json.org/

[7] http://de.wikipedia.org/wiki/ACID

[8] http://de.wikipedia.org/wiki/Query_by_Example

[9] http://docs.mongodb.org/manual/reference/operator/query/#query-selectors

[10] http://de.wikipedia.org/wiki/MapReduce

[11] http://geojson.org/geojson-spec.html

[12] http://de.wikipedia.org/wiki/B-tree

[13] http://docs.mongodb.org/ecosystem/drivers/

[14] Trelle, Tobias: „Morphia, Spring Data & Co“, in Java aktuell 04.2013

[15] Java Persistence Frameworks for MongoDB: http://de.slideshare.net/tobiastrelle/j-16761910

[16] http://info.mongodb.com/rs/mongodb/images/MongoDB_Subscription_Value.pdf

[17] https://github.com/mongodb/mongo-java-driver

Professionelle Programmierung statt Spaghetti-Code

Der Code ist die Wahrheit. Der Code bestimmt, ob ein System läuft oder nicht – frühere Entwurfsdokumente wirken nur mittelbar durch den Code. Die Programmierer verantworten die Qualität des Codes und da-mit die Qualität des Systems.

Manche halten Programmierung für eine langweilige, anspruchslose Be-schäftigung. Das ist falsch, denn langweilige, anspruchslose Program-me schreibt ein Generator, und den Generator schreibt ein qualifizier-ter Programmierer. Qualifizierte Programmierer gibt es auf der ganzen Welt: in Mitteleuropa, Osteuropa, Fernost und anderswo. Das Problem ist nur: Je weiter sie weg sind, desto teurer und fehleranfälliger ist die Kommunikation.

Unser Vorschlag: Die Programmierer bekommen eine vernünftige Aus-bildung (egal wo sie sitzen), und die Manager rechnen Nearshore und Farshore ehrlich.

http://www.qaware.de/de/manifest

1. Platz für QAware im Wettbewerb Great Place to Work

QAware_Java-Magazin_Spaghetti_GPtW_v_03_DIN_A4.indd 1 17.03.14 19:36

javamagazin 5 | 2014

Datenbanken NoSQL­Serie – Teil 9

62 www.JAXenter.de

Page 9: MongoDB - Riesige Datenmengen schemafrei verwalten

JAVA3

Jetzt 3 Top-VorTeile sichern!

Jetzt abonnieren! www.javamagazin.de

Alle Printausgaben frei Haus erhalten

Intellibook-ID kostenlos anfordern (www.intellibook.de)

Abo-Nr. (aus Rechnung oder Auftrags bestätigung) eingeben

Zugriff auf das komplette PDF-Archiv mit der Intellibook-ID

www.javamagazin.de

1

2

3