MongoDB - Riesige Datenmengen schemafrei verwalten
Upcoming SlideShare
Loading in...5
×
 

MongoDB - Riesige Datenmengen schemafrei verwalten

on

  • 666 views

 

Statistics

Views

Total Views
666
Views on SlideShare
305
Embed Views
361

Actions

Likes
1
Downloads
4
Comments
0

11 Embeds 361

https://blog.codecentric.de 287
http://feedly.com 22
http://www.slideee.com 20
http://feeds.feedburner.com 11
https://feedly.com 10
http://feedproxy.google.com 4
http://blog.codecentric.de 3
https://www.newsblur.com 1
https://reader.aol.de 1
http://reader.aol.com 1
http://www.feedspot.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    MongoDB - Riesige Datenmengen schemafrei verwalten MongoDB - Riesige Datenmengen schemafrei verwalten Document Transcript

    • magazinJava • Architekturen• Web • Agile www.javamagazin.de Österreich €10,80 Schweiz sFr 19,50 Luxemburg €11,15Deutschland €9,80 JavaMag 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 > 26JavaMagazin5.2014 ReactiveProgrammingMongoDBWildFly8JSFClojureTestingSoftwarearchitekturDesignforDiagnosability CONNECTED?
    • 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: $ mongo MongoDB shell version: 2.4.8 connecting 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. © iStockphoto.com/v_alex Riesige Datenmengen schemafrei verwalten MongoDB javamagazin 5|2014 Datenbanken NoSQL-Serie – Teil 9 56 www.JAXenter.de
    • Storage MongoDB 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.0 128M 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). Dokumente Einzelne 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: x18x00x00x00 x02 hellox00 x08x00x00x00MongoDBx00 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. Collections Die 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
    • 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. Querys Zur 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
    • 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. Indexe Pro 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. Schemafreiheit Ein 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 Anzeige
    • 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 Sets Die 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
    • 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- Sharding Um 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, SSL MMS (MongoDB Monitoring Service): http://mms.mongodb.com Monitoring 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, Jongo JPA-Provider: Eclipse Link MongoDB, Data Nucleus, Hibernate OGM Tabelle 3: Spezifikation von MongoDB javamagazin 5 |2014 DatenbankenNoSQL-Serie – Teil 9 61www.JAXenter.de
    • 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. API Clientanwendungen 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 Application Server #1 Router #m Application Server #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 javamagazin 5|2014 Datenbanken NoSQL-Serie – Teil 9 62 www.JAXenter.de
    • JAVA 3 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