Lass uns Freunde sein: AWS Neptune als Graphdatenbank

Lass uns Freunde sein: Neptune als Graphdatenbank
Der Graphendatenbankservice Neptune ist jetzt in der Preview Phase. Wir konnten erste Erfahrungen mit dem Service sammeln. Neptune unterstützt SPARQL und Apache TinkerPop Gremlin. Ich zeige hier eine Verwendung mit Gremlin.

Der Service läuft erst einmal nur in Virgina. Die Installation benötigt ein VPC und eine Security Group. Das kann auch beides durch den Wizard erstellt werden.

Der Zugriff ist nur im VPC möglich. Installiert man einen Bastion Host, kann man mit einem Tunnel lokal arbeiten. In den Security Groups des Neptune Servers muss Port 8182 vom Bastion Host aus möglich sein. Auf dem Bastion Host muss dann ssh und 8182 offen sein.

Der Endpunkt der Neptune Datenbank, z.B. demo-us-east-1b.cygc21hikgg.us-east-1-beta.rds.amazonaws.com (das ist kein echter Endpunkt) muss dann z.B. in die ssh config eingetragen werden.
Zusätzlich braucht man noch die öffentliche IP des Bastion hosts, z.B. 1.2.3.5.

Dann wäre das Setting in der ssh Config:

Host neptunedemo
 User ec2-user
 Hostname 1.2.3.5
 IdentityFile ~/.ssh/key-des-bastion-hosts.pem
 LocalForward 8182 demo-us-east-1b.cygc21hikgg.us-east-1-beta.rds.amazonaws.com:8182

Nun kann den Tunnel starten mit:

 ssh -f -N neptunedemo

Danach kann man local auf Port 8182 auf die Graphdatenbank zugreifen.

Für den Zugriff kann man die Gremlin Console verwenden.

Installation der Gremlin console

Gremlin benötigt Java.

Auf der Projektseite lädt man die Gremlin Console: Apache TinkerPop

Das Zip Archiv wird entpackt, und dann kann man die Console starten:

 ./apache-tinkerpop-gremlin-console-3.3.1/bin/gremlin.sh

Zugriff mit Gremlin Console

./apache-tinkerpop-gremlin-console-3.3.1/bin/gremlin.sh

\,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin>

Verbindung mit dem Server, also localhost ist in conf/remote.yaml vorkonfiguriert:

 gremlin> :remote connect tinkerpop.server conf/remote.yaml
 ==>Configured localhost/127.0.0.1:8182

Alle Eingaben sollen an dern Remote Server gesendet werden:

 gremlin> :remote console
 ==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182] - type ':remote console' to return to local mode

Die Datenbank ist leer. In V befinden sich alle Knoten, genannt Vertex. In E befinden sich alle Kanten, gennant Edge

Wenn jetzt alle Knoten abgefragt werden, sind sie leer:

 gremlin> g.V()
 gremlin>

Jetzt fügen wir einen Vertex mit zwei Labels hinzu:

 gremlin> g.addV("Label1::Label2::Label3")
 ==>v[4ab0f092-7746-9e3b-7c7b-e3cc1a606975]

Als Ausgabe wird die ID angezeigt. Die IDs sind in neptune reine Strings, es gibt keine numerische ID.

Anzeige des neuen Knotens:

 gremlin> g.V("4ab0f092-7746-9e3b-7c7b-e3cc1a606975")
 ==>v[4ab0f092-7746-9e3b-7c7b-e3cc1a606975]

Eingabe des AWS Beispiels

In der AWS Anleitung wird folgende Beispiel eines Graphen gegeben:

Anlegen der Personen

gremlin> g.addV("person").property("name","Anna")
 ==>v[c0b0f096-2906-2f3a-1881-4714a41dbd47]
 gremlin> g.addV("person").property("name","Justin")
 ==>v[cab0f096-5b3e-c0fe-2ec3-d8af1c26776e]
 gremlin> g.addV("person").property("name","Alana")
 ==>v[3eb0f096-5d9e-26c7-25f2-74eaeccff004]

Jetzt verbinden wir Justin und Anna freundschaftlich:

 g.V().has("name","Justin").next().addEdge("Friend", g.V().has("name","Anna").next())

Und haben damit einen Edge (Kante):

 gremlin> g.E()
 ==>e[30b0f099-ffe1-f774-f03c-7ea1c078b9e1][cab0f096-5b3e-c0fe-2ec3-d8af1c26776e-Friend->c0b0f096-2906-2f3a-1881-4714a41dbd47]

Jetzt können wir abfragen welche Freunde Anna hat. Die Freundschaft ist nur einseitig – das kommt manchmal vor. Deswegen frage ich die eingehenden Kanten ab:

 gremlin> g.V().has("name","Anna").inE("Friend")
 ==>e[30b0f099-ffe1-f774-f03c-7ea1c078b9e1][cab0f096-5b3e-c0fe-2ec3-d8af1c26776e-Friend->c0b0f096-2906-2f3a-1881-4714a41dbd47]

Um jetzt den Namen von Annas Freund zu bekommen, müssen wir von der Kante (Edge) zu dem Knoten (Vertex) navigieren und den Namen ausgeben:

 gremlin> g.V().has("name","Anna").inE("Friend").outV().values("name")
 ==>Justin

Erstes Fazit

Die Installation von Neptune geht um ein Vielfaches schneller und einfacher als z.B. das Aufsetzen von JanusGraph (JanusGraph: Distributed graph database). Für bestimmte Anwendungfälle ist eine Graphdatenbank besser geeignet als eine SQL oder auch eine NoSQL Datenbank.
Mit Neptune ist das auch als gehosteter Service einfach verwendbar.

Weitere Dokumentation

Die TinkerPop/gremlin Dokumentation findet sich auf der Projektsite: TinkerPop3 Documentation.

Es gibt einige Unterschiede in der Implementierung von AWS. Siehe dazu: Neptune Gremlin Implementation Differences – Amazon Neptune

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.