Stefan Zörner
24.03.2023
Informationen zu speichern und zu verarbeiten ist eine elementare Aufgabe in der Softwareentwicklung. Seit den 80er-Jahren prägen relationale Datenbanken wie Oracle, IBM Db2 und MySQL die Systemlandschaften vieler Unternehmen und Organisationen. Doch nicht alles lässt sich optimal in Tabellenspalten abbilden und mit SQL abfragen. Für Daten, in denen die Beziehungen untereinander die Hauptrolle spielen, bieten sich graphbasierte Lösungen an. Der bekannteste Vertreter dieser Gattung ist Neo4j. Welche Ziele verfolgt dieses Datenbankprodukt und mit welchen Architekturansätzen erreicht es diese?
Steckbrief: Graphdatenbank Neo4j
Name: Neo4j
Software-Gattung: Graphdatenbank
Veröffentlicht: 2007 (Version 1.0: Februar 2010)
Herkunft/Ursprung: Neo4j, Inc., Community Edition ist Open Source (GPL v3)
Zielplattform: Cross-Plattform (u.a. Linux, Windows …)
Programmiersprache(n): implementiert in Java (und Scala), Web-Tools in TypeScript, Cloud-Aspekte in Go
Homepage: neo4j.com
Wir schreiben das Jahr 2016. Journalisten der Süddeutschen Zeitung suchen in den sogenannten Panama Papers [PAN], einem spektakulären Daten-Leak, nach Verdachtsmomenten für Delikte wie Geldwäsche oder Steuerbetrug im großen Stil. Dazu wurde aus den Inhalten der 11,5 Millionen E-Mails und anderen Dokumenten (Urkunden, Passkopien …) ein riesiges Beziehungsgeflecht in einer Datenbank aufgebaut. Erwähnte Personen und Unternehmen bildeten dabei Knoten, Beteiligungen und Verwandtschaftsbeziehungen unter diesen Verbindungen.
Szenenwechsel: Wenn der Streaming-Dienst der Wahl Filme oder Musik empfiehlt („das könnte Dir auch gefallen“), bilden Seh-/Hörverhalten und Bewertungen (jeweils eigene aber vor allem auch anderer) die Grundlage dafür. Auch diese Daten lassen sich gut als Graph abbilden. So können z.B. Personen, Medien und Genres Knoten sein, Konsum und Bewertungen Kanten dazwischen, jeweils mit Attributen dran (Anzahl Sterne, wie oft oder wie viel gesehen oder gehört …).
Neben diesen Beispielen gibt es viele weitere Informationsarten, die sich gut durch Graphen darstellen lassen. Die zugehörigen Daten ließen sich auch in einer relationalen Datenbank speichern – Tabellen für Personen, Filme, Genres … und Beziehungen mit Fremdschlüsseln. Die Auswertungen erfolgen dann mit Joins in den SQL-Abfragen. Dieser Lösungsansatz war jahrzehntelang Standard für Persistenz-Fragen aller Art. Mit dem NoSQL-Trend (ab ca. 2009, siehe z.B. [Wal+2010]) wuchs die Akzeptanz, dass in bestimmten Anwendungsfällen und unter bestimmten Voraussetzungen andere Speichertechniken deutlich besser geeignet sind. Sie ergänzen den relationalen Ansatz – NoSQL == Not only SQL.
Als Konsequenz etablierten sich für besondere Anwendungsfälle und Qualitätsanforderungen (z.B. schwächere Konsistenz im Tausch gegen höhere Verfügbarkeit) Persistenzlösungen jenseits der relationalen Datenbanken. Abbildung 1 zeigt wichtige Kategorien, nennt jeweils typische Anwendungsgebiete und prominente Produkte. Bei den graphbasierten Systemen ragt Neo4j bezüglich seiner Popularität (siehe z.B. [DBER]) heraus.
Neo4j begann sein Produktleben allerdings nicht als allgemeine Datenbanklösung, sondern um 2002 als recht spezialisierter Bestandteil eines kommerziellen Onlinedokumentenmanagementsystems. Dort war es für die Echtzeitsuche in verschlagworteten Dokumenten über Sprachgrenzen und Bedeutungshierarchien hinweg und für die Abbildung von Nutzern, Gruppen und Rechten für Enterprise-Kunden verantwortlich. 2007 wurde die Komponente als Neo4j aus dem Produkt herausgelöst und als Open-Source unter der GPL veröffentlicht (siehe [GitHub]). Die Version 1.0 erschien 2010, hinter Neo4j steht seit Beginn das ursprünglich in Schweden gegründete Unternehmen Neo4j Inc.
Tabelle 1 beinhaltet zentrale Architekturziele der Lösung; die Reihenfolge spiegelt deren Wichtigkeit wider. Mit welchen Lösungsansätzen erreicht die Software diese Ziele?
Ziel | Beschreibung (und zugehörige(s) Software-Qualitätsmerkmal(e)) |
Einfache Realisierung graphbasierter Anwendungen | Mit Neo4j lassen sich Graph-gestützte Anwendungen einfach umsetzen. Alle am Entwicklungsprozess Beteiligten erleben eine gute Nutzerfreundlichkeit. Neo4j steht relationalen Datenbanken bezüglich der Lernkurve etwa bei Entwickler:innen in nichts nach. (Nutzerfreundlichkeit aus Sicht der Entwicklung) |
Schnelle Ausführung von Abfragen | Neo4j führt komplexe Abfragen auch auf sehr großen Datenmengen in kürzester Zeit aus. Insbesondere solche, die sich auf Verknüpfungen zwischen Daten beziehen. Auch die Ausführung aufwändiger Graph-Algorithmen erfolgt sehr effizient. (Effizienz) |
Zuverlässig im Betrieb | Neo4j speichert Daten verlässlich und sichert deren Konsistenz zu. Auch in unternehmenskritischen Anwendungsfällen kann Neo4j eine hohe Verfügbarkeit darstellen. Gespeicherte Daten sind vor unberechtigtem Zugriff sicher. (Zuverlässigkeit, Sicherheit) |
Lauffähig auf vielen Hard- und Softwareplattfomen | Neo4j lässt sich serverseitig auf allen relevanten Zielsystemen betreiben. Es ist leicht in bestehende Systemlandschaften integrierbar. Bezüglich der Auswahl von Clients, die auf die Daten zugreifen wollen, gibt es keine relevanten Einschränkungen. (Portierbarkeit, Integrierbarkeit) |
Leicht ausbaubar und erweiterbar um neue Funktionalität | Die Lösung lässt sich gut erweitern, durch das Neo4j-Team ebenso wie durch Anwender aus der Community. Dies betrifft Anpassungen vorhandener Bestandteile ebenso wie neue Funktionalität, die auf den gespeicherten Daten operiert. Neo4j ist für offen für technologische und methodische Trends. (Erweiterbarkeit) |
Anders als bei relationalen Datenbanken, wo viele Entwickler:innen zumindest Grundkenntnisse der Konzepte und speziell der Abfragesprache SQL besitzen, sind graphbasierte Produkte den meisten zunächst neu. Gleichwohl ist es entscheidend für den Erfolg von Neo4j, dass Entwicklungsteams einfach Lösungen damit bauen und weiterentwickeln können – das Produkt muss also leicht zugänglich sein.
Hierbei hilft, dass bei graphbasierten Datenbanken das konzeptionelle Modell dem Datenmodell entspricht. Daten aus einem Beispielgraph wie in Abbildung 2 lassen sich 1:1 als Knoten und Kanten speichern – die für NoSQL typische Schemafreiheit von Neo4j erleichtert den Start. Dies und der interaktive Neo4j-Browser (siehe Abbildung 3) zum Explorieren der Daten lassen auch Nicht-Entwickler:innen kontinuierlich im Prozess mitwirken, von ersten Ideen am Whiteboard bis hin zu interaktiv entwickelten Abfragen. Diese werden in Neo4j in der Sprache Cypher, sozusagen dem Pendent zu SQL, formuliert. Cypher ist ebenfalls textbasiert, aber mit visueller Anmutung durch ASCII-Art. Muster für Knoten werden beispielsweise mit runden Klammern umschlossen, Beziehungen mit Pfeilen dargestellt. (:Game)-[:RUNS_ON]->(s:System) WHERE s.name = “Game Boy” passt im Beispiel in Abbildung 2 auf alle Spiele, die auf dem Nintendo Game Boy laufen.
Dass Neo4j auch kompliziertere Abfragen mit Verbindungen über viele Hops effizient ausführt, liegt vor allem am dedizierten Graph-Datenmodell. Beziehungen werden als Datenstruktur direkt in der Datenbank materialisiert, was ein Traversieren von „Pointern“ ohne viele Sub-Abfragen und Joins erlaubt. Neo4j sitzt also nicht auf einer vorhandenen Datenbank, sondern bietet eine hochspezialisierte Implementierung auf der Java Virtual Machine. Eine hohe Parallelisierung bei der Ausführung von Abfragen tut ihr übriges. Java als Programmiersprache für Middleware und systemnahe Software wie Datenbanken ist übrigens keine ungewöhnliche Wahl. Die Zeiten, als Java als inperformant galt, sind spätestens seit Java NIO vorbei. So sind beispielsweise die Suchmaschine Elasticsearch, die Datenbank Cassandra und die Streaming-Lösung Kafka ebenfalls in JVM-Sprachen realisiert.
Um Daten auch um Fehlerfall oder bei konkurrierenden Zugriffen konsistent in die Datenbank zu bringen bietet Neo4j ACID-Transaktionen an. Und wer Neo4j für geschäftskritische Anwendungsfälle einsetzen möchte, etwa für Empfehlungen in einem Webshop, hat (neben der Performance) auch hohe Ansprüche an Verfügbarkeit und Zuverlässigkeit. Um das Ganze im Blick zu haben bietet Neo4j neben üblichen Monitoring-Möglichkeiten auch spezifische Metriken, beispielsweise Datenbankstatistiken oder Laufzeiten für Cypher-Abfragen, an.
Im Clusterbetrieb unterscheidet es zwischen Primary und Secondary Servers. Erstere handeln Schreiboperationen nach dem Raft-Algorithmus (siehe [Ong+2013]) über Konsens aus. Zweitere replizieren Transaktionen asynchron von einem Primary und dienen vor allem der Lastverteilung bei Abfragen (Details zum Clustering in Neo4j unter [Manual]).
Um Daten vor unerwünschten Zugriffen zu schützen besitzt Neo4j ein Rollenkonzept. Die Authentifizierung und die Zuordnung zu Rollen kann an einen LDAP-fähigen Verzeichnisdienst (z.B. Active Directory) delegiert werden. Verbindungen zu Neo4j im binären Bolt-Protokoll sind bei der Nutzung von SSL verschlüsselt. Die Implementierung von Neo4j mit Java-Technologien sorgt dafür, dass der Server auf vielen Hard- und Softwareplattformen läuft. Die Bereitstellung als Container-Image ist heute üblich und ebenfalls gegeben. Darüber hinaus bietet Neo4j Inc. mit AuraDB ein „fully managed“ SaaS-Angebot in der Cloud an – für erste Gehversuche (z.B. überschaubare Datenmengen) sogar zeitlich unbeschränkt kostenlos.
Um Client-Anwendungen zu realisieren, die mit Neo4j kommunizieren, stellt Neo4j offizielle Bolt-Treiber für die gängigsten Programmiersprachen bereit: aktuell sind das .NET, Java, JavaScript, Go und Python. Hinzu kommen weitere Implementierungen aus der Community, etwa für C/C++ und PHP. Darüber hinaus ist ein Programmiersprachen-agnostischer Zugriff über die HTTP-API von Neo4j eine Option.
Datenbank zugreifen, sondern innerhalb der Datenbank werkeln wollen. Eigene Prozeduren etwa oder eigene Funktionen, die aus Cypher-Abfragen nutzbar sein sollen. Hier finden sich mit Plugins und im Extremfall Unmanaged Server Extensions für HTTP-Endpunkte passende Konzepte in Neo4j. Die Implementierung erfolgt in JVM-Sprachen, Neo4j stellt eine passende Dokumentation bereit.
Überhaupt ist das Material, welches das Neo4j-Team zum Aneignen von Wissen rund um Graphdatenbanken im Allgemeinen und Neo4j im Besonderen bereitstellt, vorbildlich. Es gibt nicht nur Artikel, Beispieldatenbanken, Manuals für den Betrieb und reichlich Tutorials. Die Graph Academy [Academy] von Neo4j bietet darüber hinaus kostenlose und interaktive Kurse zu grundlegenden Konzepten, der Abfragesprache Cypher und der Implementierung von Client-Applikationen in verschiedenen Programmiersprachen an. Neo4j läuft dabei parallel in einer Sandbox mit Zugriff direkt aus den Online-Kursen – zu Lösungen in den Übungen erhält man automatisch Feedback. All dies zahlt auf das höchste Architekturziel von Neo4j ein: die gute Zugänglichkeit für Entwicklungsteams.
Die vielen Erweiterungspunkte – sei es von außen über die Zugriffsprotokolle Bolt und HTTP mit Hilfe von Cypher oder von innen über Plugins - dienen auch dem Neo4j-Team und seiner Community dazu, die Software für neue Trends zu öffnen. So findet sich heute eine GraphQL-Integration ebenso wie Konnektoren für Streaming-Lösungen wie Kafka oder Spark. Anwendungsfälle rund um Data Analytics und Machine Learning deckt Neo4j mit seiner Graph Data Science-Bibliothek ab, einer Sammlung von Algorithmen und ML-Modellierungsmöglichkeiten.
Neo4j ist heute weitaus mehr als eine Allzweckdatenbank für Graphdaten. Seine Rolle als wichtigster Vertreter dieser Datenbankkategorie im großen NoSQL-Zoo ist aber unbenommen. Sie war mein Hauptgrund, es hier in den Architektur-Porträts abzunehmen. Darüber hinaus ist es unabdingbar, Lösungsansätze jenseits des Mainstreams zu kennen, um auch in besonderen Situationen angemessene Entscheidungen zu treffen. Nicht zufällig bildet polyglotte Persistenz einen Eckpfeiler des Architekturstils Microservices, der Flexibilität und technologische Freiheit hochhält (siehe [Fow+2014]). Und nicht zuletzt ist Neo4j ein exzellentes Beispiel für qualitativ hochwertige Entwicklerdokumentation.
[Academy] Neo4j GraphAcademy
[DBER] DB-Engines Ranking, monatlich aktualisierte Rangfolge von Datenbanken nach Popularität
[Fow+2014] Martin Fowler, James Lewis: “Microservices. A definition of this new architectural term”, Blog-Beitrag 2014
[GitHub] Neo4j bei GitHub
[Manual] Neo4j Operations Manual, Clustering
[Ong+2013] Diego Ongaro, John Ousterhout: “In Search of an Understandable Consensus Algorithm”, Stanford University 2013
[PAN] Süddeutsche Zeitung: “Panama Papers. Die Geheimnisse des schmutzigen Geldes”
[Wal+2010] Dj Walker-Morgan, Oliver Diedrich: “NoSQL im Überblick”, c’t Magazin 2010, online
Dieses Porträt ist ursprünglich in der IT Spektrum, Ausgabe 2 | 2023 als fünfter Teil einer Reihe über Architektur-Ikonen der Softwareentwicklung erschienen. Rückmeldungen aller Art gerne an mich per E-Mail. Insbesondere auch Wünsche für weitere Porträts.
Architektur-Porträt: Die Programmiersprache Go
Architektur-Porträt: Der statische Website-Generator Hugo
Architekturikonen in Software Überblick über alle Porträts