Archive

MySQL Feinabstimmung der Benutzerrechte

MySQL Benutzerrechteverwaltung

Rechte pro Tabelle und sogar pro Spalte sinnvoll einstellen

Nachdem du in in unserem Artikel MySQL Datenbank erstellen und löschen gelernt hast, wie man in MySQL eine Datenbank erstellt und löscht und dir in unserem Artikel zum Thema Wie erstelle ich einen MySQL Benutzer und weise ihm Rechte zu? gezeigt wurde, wie man einem Nutzer Zugriff auf eine Datenbank in MySQL gewährt, wird dir in diesem Tutorial schrittweise näher gebracht, wie du Benutzerrechte nicht nur für eine Datenbank definierst, sondern pro Tabelle und sogar pro Spalte für bestimmte Nutzer festlegst. Beim Tutorial zu ‚MySQL Feinabstimmung der Benutzerrechte‘ werde ich mit dir im Sinne eines Real-Live Case eine Datenbank erstellen, diese mit Tabellen füllen und vier frei erfundenen Nutzern spezifische Rechte auf bestimmte Tabellen und/oder Tabellenspalten dieser Datenbank zuweisen. Einige in diesem Tutorial einführende Shell-Commands werden dir somit bereits aus unseren oben genannten Artikeln bekannt sein, werden jedoch trotzdem gezeigt, um den Gesamtkontext für dich greifbar zu machen. Du kannst also alle Schritte bei dir am Rechner anhand dieses Tutorials nachbilden und simulieren.

Fallbeispiel

  • Feinabstimmung der Benutzerrechte
  • Es soll möglich sein Nutzerrechte nicht lediglich auf bestimmte Datenbanken zu vergeben, sondern diese sogar zum einen zu spezifizieren und in Anwendung auf den pro Kopf Nutzer zu individualisieren. Hierbei wird davon ausgegangen, dass einem bestimmten Nutzer nur auf bestimmte Tabellen oder nur auf bestimmte Spalten einer Tabelle oder mehrerer Tabellen Zugriff erlaubt wird. Im Hinblick auf Spalten wäre ein denkbares Szenario, dass ein bestimmter Nutzer in einer bestimmten Tabelle nur die Inhalte der Spalten A und B, nicht aber die der Spalte C anschauen und/oder editieren kann und lediglich ein Nutzer mit allen Rechten vollen Zugriff auf alle Tabellen und deren Inhalte hat.

Anwendungsszenario

Es wird zur Verbildlichung im Sinne eines Real-Live Case von einer Datenbank zur Systemverwaltung von Blogeinträgen ausgegangen, die nach der Implementierung die unten aufgeführten Tabellen FAVORITENLISTE, NUTZER, REDAKTEUR, CHEFREDAKTEUR, BLOGEINTRAG und FAVORISTENLISTEenthaltenBLOGEINTRAG mit Inhalten enthalten soll.

Tabellen der Datenbank Blogeinträge

Für die Vergabe von Rechten ist hierbei wichtig, dass jeder Redakteur ein Nutzer ist, aber nicht jeder Nutzer ein Redakteur und dass jeder Chefredakteur ein Redakteur ist, aber nicht jeder Redakteur ein Chefredakteur. Chefredakteure haben kompletten Zugriff auf die Datenbank Blogeinträge, sie können unter anderem Tabellen anlegen und diese sichten, editieren und löschen. Redakteure hingegen haben eingeschränkten Zugriff auf Tabellen der Datenbank. Sie dürfen keine Tabellen anlegen und haben nur für bestimmte Tabellen und/oder Tabellenspalten Rechte. Ein Redakteur hat alle Rechte an der Tabelle REDAKTEUR. In der Tabelle NUTZER darf er lediglich die in den Spalten Benutzername, EMailAdresse und FavoritenlisteID befindlichen Inhalte einsehen. Auch die Inhalte der Tabelle BLOGEINTRAGenthaltenFAVORITENLISTE darf ein Redakteur lediglich einsehen, wobei er hier Zugriff auf alle Spalten hat. In der Tabelle BLOGEINTRAG darf ein Redakteur lediglich die Inhalte der Spalten Titel, Text und Benutzername updaten, jedoch sowohl die komplette Tabelle sichten, als auch neue Einträge hinzufügen.
Als Nutzer darf man in der Tabelle NUTZER die Spalten Benutzername, EMailAdresse und FavoritenlisteID einsehen, in den Tabellen REDAKTEUR, BLOGEINTRAG und FAVORITENLISTEenthaltenBLOGEINTRAG darf man jeweils lediglich die Inhalte sichten, das bezieht sich jedoch hierbei auf alle Spalten der jeweiligen Tabelle. Für die Tabelle FAVORITENLISTE sollen NUTZER gar keine Rechte haben.

Umsetzung

Zunächst werden unter dem root-Account die vier in der Einführung dieses Tutorials genannten Nutzer mit dem CREATE USER-Command, sowie die Datenbank
Blogeinträge mit dem CREATE DATABASE-Command angelegt.

mysql -u root -p
password: *********

mysql> CREATE USER 'jens'@'localhost' IDENTIFIED BY 'passwort1';
Query OK, 0 rows affected (0,00 sec)

mysql> CREATE USER 'katrin'@'localhost' IDENTIFIED BY 'passwort2';
Query OK, 0 rows affected (0,00 sec)

mysql> CREATE USER 'natascha'@'localhost' IDENTIFIED BY 'passwort3';
Query OK, 0 rows affected (0,00 sec)

mysql> CREATE USER 'michael'@'localhost' IDENTIFIED BY 'passwort4';
Query OK, 0 rows affected (0,00 sec)

mysql> CREATE DATABASE Blogeinträge;
Query OK, 0 rows affected (0,00 sec)

Danach werden die Rechte vergeben, die ein Chefredakteur haben soll, wie ich zu Beginn des Anwendungsszenarios geschildert habe.

mysql> GRANT ALL PRIVILEGES ON Blogeinträge.* TO 'jens'@'localhost';
Query OK, 0 rows affected (0,00 sec)

In MySQL werden Berechtigungen in bestimmten Systemtabellen gespeichert, deren Werte mittels dem SELECT-Command zur Einsicht wiedergegeben werden können.
Informationen zu Nutzerberechtigungen werden in der mysql.user-Systemtabelle gespeichert. In der mysql.db-Systemtabelle sind die Werte zu Datenbankberechtigungen zu finden. Die Daten zu Tabellenberechtigungen hingegen sind in der mysql.tables_priv-Systemtabelle gespeichert und Informationen zu Spaltenberechtigungen in der mysql.columns_priv-Systemtabelle. Die Attribute der mysql.tables_priv-Systemtabelle beziehen sich auf Rechte an Tabellen einer bestimmten Datenbank – in diesem Fall die Datenbank Blogeinträge – und die Attribute der Tabelle mysql.columns_priv-Systemtabelle nehmen Bezug auf Rechte an bestimmten Spalten dieser Tabellen. Hinter den Attributen der jeweiligen Tabelle, wie Sie in der unten stehenden Tabelle aufgelistet sind, stehen Werte. Möchte man die Werte der Attribute User, Host, Db, Select_priv und Insert_priv aus der mysql.db-Systemtabelle zur Sichtung wiedergegeben haben, würde der Command SELECT user,host,db,select_priv,insert_priv FROM db dies erfüllen. Andernfalls, wenn man z.B. alle Attributwerte angezeigt bekommen möchte, würde der Command SELECT * FROM db genügen. Eine Referenz zu den in der unten stehenden Tabelle aufgelisteten Attributen, bzw. Privilegien-Parametern ist in der MySQL-Online-Dokumentation zu finden, wo erklärt wird, welche MySQL Privilegien bereitgestellt werden.

Tab. 1: Informationsstruktur – Attribute, deren Werte unter dem Command SELECT * FROM user, SELECT * FROM db, SELECT * FROM tables_priv oder SELECT * FROM columns_priv einsehbar sind.

Tabelle user

Tabelle db

Tabelle tables_priv

Tabelle columns_priv

user

db

tables_priv

columns_priv

Host

Host

Host

Host

User

Db

Db

Db

Select_priv

User

User

User

Insert_priv

Select_priv

Table_name

Table_name

Update_priv

Insert_priv

Grantor

Column_name

Delete_priv

Update_priv

Timestamp

Column_priv

Create_priv

Delete_priv

Table_priv

Timestamp

Drop_priv

Create_priv

Column_priv

 

Reload_priv

Drop_priv

   

Shutdown_priv

Grant_priv

   

Process_priv

References_priv

   

File_priv

Index_priv

   

Grant_priv

Alter_priv

   

References_priv

Create_tmp_table_priv

   

Index_priv

Lock_tables_priv

   

Alter_priv

Create_view_priv

   

Show_db_priv

Show_view_priv

   

Super_priv

Create_routine_priv

   

Create_tmp_table_priv

Alter_routine_priv

   

Lock_tables_priv

Execute_priv

   

Execute_priv

Event_priv

   

Repl_slave_priv

Trigger_priv

   

Repl_client_priv

     

Create_view_priv

     

Show_view_priv

     

Create_routine_priv

     

Alter_routine_priv

     

Create_user_priv

     

Event_priv

     

Trigger_priv

     

Create_tablespace_priv

     

ssl_type

     

ssl_cipher

     

x509_issuer

     

x509_subject

     

max_questions

     

max_updates

     

max_connections

     

max_user_connections

     

plugin

     

authentication_string

     

password_expired

     

password_last_changed

     

password_lifetime

     

account_locked

     

Im Hinblick auf das Anwendungsszenario müsstest du unter dem root-Account in die Standard-MySQL-Datenbank wechseln, um dir die Attributwerte der
mysql.user-Systemtabelle oder der mysql.db-Systemtabelle anzeigen zu lassen. Aus dem
eingeblendeten Output entnimmst du, dass der Nutzer Jens in der Datenbank z.B. für
sämtliche SELECT- und INSERT-Operationen Rechte besitzt. Besäße er sie nicht, wäre der
Attributwert nicht ‚Y‘ für ‚Yes‘, sondern ‚N‘ für ‚No‘.

mysql> USE MYSQL;

mysql> SELECT user,db,select_priv,insert_priv FROM db;
+---------------+---------------+-------------+-------------+
| user          | db            | select_priv | insert_priv |
+---------------+---------------+-------------+-------------+
| jens          | Blogeinträge  | Y           | Y           |
+---------------+---------------+-------------+-------------+
1 row in set (0,00 sec)

Tabellen in MySQL anlegen und Attributwerte validieren

Da der Nutzer Jens als Chefredakteur alle Rechte an der Datenbank Blogeinträge hat, können unter seinem Account Tabellen angelegt werden. Hierzu loggst du dich zunächst mit seinen Benutzerdaten ein und wechselst mittels dem USE-Command in die Datenbank Blogeinträge.

mysql -u jens -p
password: *********

mysql> USE Blogeinträge;
Database changed

Im Anschluss daran kannst du als Chefredakteur mit dem CREATE TABLE-Command Tabellen zur Datenbank hinzufügen. Die Syntax des CREATE TABLE-Command sieht vor, dass in der Klammerung, die nach CREATE TABLE folgt, die jeweiligen Attribute (Spalten) der Tabelle gelistet sind. Hinter jedem Attribut steht der Datentyp. IDs z.B. lassen sich gut als ganzzahlige Werte abbilden, was einem INTEGER entspricht. Nach der Definition des Datentyps folgt die Definition, die klar stellt, ob es sich um einen Primärschlüssel oder einen Fremdschlüssel handelt oder der Wert hinter dem Datentypen einfach nicht null sein darf. Im Anschluss daran kann ein CHECK erfolgen, muss aber nicht. Mittels dem CHECK kannst du eine Bedingung definieren, die bei jedem neuen Eintrag in die betreffende Spalte prüft, ob der Eintrag valide ist. Zur Verdeutlichung dient z.B. der CHECK in der Tabelle NUTZER für die Spalte Geschlecht. Hier ist der Datentyp als Character der Länge 1 definiert und darf nicht null sein, was bedeutet, dass für jeden Eintrag in dieser Spalte ein Wert stehen muss. Letztlich folgt der CHECK, in dem geprüft wird, ob die durch INSERT– oder UPDATE-Operation hinzugefügte Zeichenkette der Länge 1 den Wert ‘w’ oder ‘m’ hat. Bei der Festlegung des Fremdschlüssels ist hingegen REFERENCES wichtig. Erneut nehme ich Bezug auf die Tabelle NUTZER. Als letztes Attribut dieser Tabelle steht die FavoritenlisteID. Zunächst wird sie, wie alle anderen Attribute, nach der vorgestellten Syntax deklariert. Im Nachgang daran wird über REFERENCES zusätzlich zur erfolgten Deklaration die Referenz des Fremdschlüssels FavoritenlisteID hergestellt, was bedeutet, dass eindeutig gemacht wird, aus welcher Tabelle der Fremdschlüssel FavoritenlisteID kommt, also in welcher Tabelle er selber Primärschlüssel ist. Und dies wiederum ist die Tabelle FAVORITENLISTE, die vor der Tabelle NUTZER via CREATE TABLE-Command erstellt wurde. In diesem Zusammenhang solltest du generell immer die Reihenfolge berücksichtigen, in der du Tabellen anlegst. Tabellen, deren Primärschlüssel in anderen Tabellen Fremdschlüssel ist, sollten immer vor diesen zweitgenannten Tabellen angelegt werden. In der MySQL-Dokumentation kannst du weiterführende Informationen zur CREATE TABLE-Syntax nachlesen.

mysql> CREATE TABLE FAVORITENLISTE(
FavoritenlisteID INT PRIMARY KEY CHECK(FavoritenlisteID > 0));
Query OK, 0 rows affected (0,04 sec)

mysql> CREATE TABLE NUTZER(
Benutzername VARCHAR(50) PRIMARY KEY CHECK(LENGTH(Benutzername) > 0), 
EMailAdresse VARCHAR(50) NOT NULL CHECK(EMailAdresse LIKE '%@%.de' OR EMailAdresse LIKE '%@%.com'), 
Geschlecht CHAR(1) NOT NULL CHECK(Geschlecht IN ('w', 'm')), 
Geburtsdatum DATE NOT NULL, 
Passwort VARCHAR(10) NOT NULL CHECK(LENGTH(Passwort) > 0), 
FavoritenlisteID INT NOT NULL CHECK(FavoritenlisteID > 0), 
FOREIGN KEY(FavoritenlisteID) REFERENCES FAVORITENLISTE(FavoritenlisteID));
Query OK, 0 rows affected (0,06 sec)

mysql> CREATE TABLE REDAKTEUR(
Benutzername VARCHAR(50) PRIMARY KEY CHECK(LENGTH(Benutzername) > 0), 
Vorname VARCHAR(50) NOT NULL CHECK(LENGTH(Vorname) > 0), 
Name VARCHAR(50) NOT NULL CHECK(LENGTH(Name) > 0), 
Vorstellungstext TEXT CHECK(LENGTH(Vorstellungstext)  CREATE TABLE CHEFREDAKTEUR(
Benutzername VARCHAR(50) PRIMARY KEY CHECK(LENGTH(Benutzername) > 0), 
Telefonnummer VARCHAR(20) NOT NULL CHECK(LENGTH(Telefonnummer) > 0), 
FOREIGN KEY(Benutzername) REFERENCES REDAKTEUR(Benutzername));
Query OK, 0 rows affected (0,06 sec)

mysql> CREATE TABLE BLOGEINTRAG(
BlogeintragID INT PRIMARY KEY CHECK(BlogeintragID > 0), 
Erstellungsdatum DATE NOT NULL, 
Änderungsdatum DATE CHECK(Änderungsdatum >= Erstellungsdatum), 
Titel VARCHAR(250) NOT NULL CHECK(LENGTH(Titel) > 0), 
Text TEXT CHECK(LENGTH(Text)  0), 
FOREIGN KEY(Benutzername) REFERENCES REDAKTEUR(Benutzername));
Query OK, 0 rows affected (0,08 sec)

mysql> CREATE TABLE FAVORITENLISTEenthaltenBLOGEINTRAG(
BlogeintragID INT NOT NULL CHECK(BlogeintragID > 0), 
FavoritenlisteID INT NOT NULL CHECK(FavoritenlisteID > 0), 
PRIMARY KEY(BlogeintragID, FavoritenlisteID), 
FOREIGN KEY(BlogeintragID) REFERENCES BLOGEINTRAG(BlogeintragID), 
FOREIGN KEY(FavoritenlisteID) REFERENCES FAVORITENLISTE(FavoritenlisteID));
Query OK, 0 rows affected (0,05 sec)

Mittels dem SHOW TABLES-Command kannst du dir im Anschluss daran, angemeldet als Nutzer Jens, nun die in der Datenbank Blogeinträge befindlichen Tabellen ansehen. Es werden alle Tabellen angezeigt, da der Nutzer Jens als Chefredakteur alle Rechte an allen Tabellen hat.

mysql> SHOW TABLES;
+------------------------------------+
| Tables_in_Blogeinträge             |
+------------------------------------+
| BLOGEINTRAG                        |
| FAVORITENLISTEenthaltenBLOGEINTRAG |
| CHEFREDAKTEUR                      |
| FAVORITENLISTE                     |
| NUTZER                             |
| REDAKTEUR                          |
+------------------------------------+
6 rows in set (0,00 sec)

Rechte in MySQL pro Tabelle und/oder Spalte definieren

Nachdem die Datenbank Tabellen enthält, kannst du die jeweiligen Nutzerrechte pro Tabelle und /oder pro Spalte definieren. Beginnen wir mit dem Nutzer Katrin, welcher die Rechte eines Redakteurs haben soll. Wenn du dich unter dem Account von Katrin einloggst und in die Datenbank Blogeinträge wechseln willst, bekommst du die im unteren Codeblock eingeblendete Fehlermeldung, die dich darauf aufmerksam macht, dass dir die Rechte auf die Datenbank Blogeinträge fehlen.

mysql -u katrin -p
password: *********

mysql> USE Blogeinträge;
ERROR 1044 (42000): Access denied for user 'katrin'@'localhost' to database 'Blogeinträge'

Um dem Nutzer Katrin spezifische Rechte an bestimmten Tabellen und/oder Spalten der Datenbank Blogeinträge zu gewähren, müssen diese zunächst – wie die allgemeinen Rechte, die Jens als Chefredakteur hat – definiert werden. Nur sind die Rechte des Redakteurs eben eingeschränkt. Zunächst musst du dich wieder unter dem Root-Account in MySQL einloggen.

mysql -u root -p
password: *********

Aus der Einleitung zum Anwendungsszenario weißt du, dass ein Redakteur alle Rechte an der Tabelle REDAKTEUR hat. Der GRANT-Command ist dir bereits aus dem in der Einleitung dieses Tutorials erwähnten Artikel Wie erstelle ich einen MySQL Benutzer und weise ihm Rechte zu? bekannt und wird bei der Spezifizierung von Tabellenrechten ebenso genutzt, wie bei der allgemeinen Rechtevergabe, wie ich sie bereits für den Chefredakteur Jens zu Beginn des Anwendungsszenarios umgesetzt habe. Jedoch wird der GRANT-Command nun detaillierter. Um festzulegen, dass Katrin alle Rechte an der Tabelle REDAKTEUR hat, wird nicht der bisher geläufige Command im Sinne von

mysql> GRANT ALL PRIVILEGES ON Blogeinträge.* TO 'katrin'@'localhost';
Query OK, 0 rows affected (0,00 sec)

genutzt, sondern er wird genauer formuliert, nämlich als

mysql> GRANT ALL PRIVILEGES ON Blogeinträge.REDAKTEUR TO 'katrin'@'localhost';
Query OK, 0 rows affected (0,00 sec)

Hierbei wird nicht nur die Datenbank angetriggert, sondern die hinter der Datenbank stehende Tabelle REDAKTEUR. Wenn du die Rechte noch weiter spezifizieren willst, also nicht lediglich auf bestimmte Tabellen einschränken willst, sondern sogar auf Spalten, sieht der GRANT-Command wieder etwas anders aus. Dann wird nämlich für jede Art von Zugriff bzw. Operation definiert, auf welche Spalten einer bestimmten Tabelle der betreffende Nutzer diese Operation ausüben darf. Hierzu wird in der Syntax der Name der betreffenden Operation, gefolgt von dem in Klammern gesetzten Bestandteil vor dem ON TABELLE.SPALTE des Commands deklariert. Wie dies in der Kommandozeile realisiert wird, siehst du in den folgenden Shell-Snippets, in denen die weiteren Rechtevergaben für den Nutzer Katrin stattfinden, wie sie in der Einleitung zum Anwendungsszenario erläutert worden sind. Dort wird für Katrin als erstes die SELECT-Operation auf die Spalten Benutzername, EMailAdresse und FavoritenlisteID der Tabelle NUTZER gewährt.

mysql> GRANT SELECT (Benutzername, EMailAdresse, FavoritenlisteID) ON Blogeinträge.NUTZER TO 'katrin'@'localhost';
Query OK, 0 rows affected (0,00 sec)

Des Weiteren wird im nächsten GRANT-Befehl Katrin das Recht an der SELECT-Operation auf die komplette Tabelle FAVORITENLISTEenthaltenBLOGEINTRAG zugewiesen.

mysql> GRANT SELECT ON Blogeinträge.FAVORITENLISTEenthaltenBLOGEINTRAG TO 'katrin'@'localhost';
Query OK, 0 rows affected (0,00 sec)

Im Anschluss daran erfolgt eine weitere GRANT-Anweisung, laut der Katrin als Redakteur sowohl die SELECT-, als auch die UPDATE– und DELETE-Operation auf die Spalten Titel, Text und Benutzername der Tabelle BLOGEINTRAG vornehmen darf.

mysql> GRANT SELECT, INSERT, UPDATE (Titel, Text, Benutzername) ON Blogeinträge.BLOGEINTRAG TO 'katrin'@'localhost';
Query OK, 0 rows affected (0,00 sec)

In den folgenden Shell-Snippets zeige ich dir noch, wie du die Rechte im Fall des Nutzers Natascha so umsetzen würdest, wie ich es zu Beginn des Anwendungsszenarios geschildert habe. Da sich Natascha und Michael jeweils in der Rolle des Nutzers rechtlich auf derselben Ebene befinden, solltest du bei der Nachbildung dieses Leitfadens die auf den Nutzer Natascha gesetzten Rechte im Nachgang ebenso auf den Nutzer Michael festlegen, um dieselben Outputs zu erzielen, wie ich sie im folgenden Teil des Tutorials präsentieren werde.

mysql> GRANT SELECT (Benutzername, EMailAdresse, FavoritenlisteID) ON Blogeinträge.NUTZER TO 'natascha'@'localhost';
Query OK, 0 rows affected (0,00 sec)

mysql> GRANT SELECT ON Blogeinträge.REDAKTEUR TO 'natascha'@'localhost';
Query OK, 0 rows affected (0,00 sec)

mysql> GRANT SELECT ON Blogeinträge.BLOGEINTRAG TO 'natascha'@'localhost';
Query OK, 0 rows affected (0,00 sec)

mysql> GRANT ALL PRIVILEGES ON Blogeinträge.FAVORITENLISTEenthaltenBLOGEINTRAG TO 'natascha'@'localhost';
Query OK, 0 rows affected (0,00 sec)

Nachdem du die Rechte pro Nutzer individuell festgelegt hast, kannst du dir den Gesamtkontext der Rechtevergabe, so wie er durch dich implementiert wurde, via SELECT-Statement ausgeben lassen. Hierzu musst du aber zunächst die Datenbank wechseln, da du dich noch in der Datenbank Blogeinträge befindest. Also wechselst du mittels dem USE-Command in die MySQL-Datenbank.

mysql> USE mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

Über die Ausführung des folgenden Kommandos kannst du dir die Attributwerte der tables_priv-Systemtabelle ausgeben lassen. Hieraus lassen sich die Tabellenrechte in Relation zu den Spaltenrechten ablesen. Angewandt auf die erste Zeile würdest du daraus verstehen, dass dem Redakteur Katrin auf Tabellenebene für die Tabelle BLOGEINTRAG sowohl die SELECT– als auch die INSERT-Operation erlaubt sind. Im Hinblick auf die Spaltenebene ist hingegen lediglich die UPDATE-Operation zulässig.

mysql> SELECT * from tables_priv;
+-----------+---------------+---------------+------------------------------------+----------------------+---------------------+----------------------------------------------------------------------------------------------+-------------+
| Host      | Db            | User          | Table_name                         | Grantor              | Timestamp           | Table_priv                                                                                   | Column_priv |
+-----------+---------------+---------------+------------------------------------+----------------------+---------------------+----------------------------------------------------------------------------------------------+-------------+
| localhost | Blogeinträge  | katrin        | BLOGEINTRAG                        | [email protected]       | 0000-00-00 00:00:00 | Select,Insert                                                                                | Update      |
| localhost | Blogeinträge  | katrin        | FAVORITENLISTEenthaltenBLOGEINTRAG | [email protected]       | 0000-00-00 00:00:00 | Select                                                                                       |             |
| localhost | Blogeinträge  | michael       | NUTZER                             | [email protected]       | 0000-00-00 00:00:00 |                                                                                              | Select      |
| localhost | Blogeinträge  | natascha      | FAVORITENLISTEenthaltenBLOGEINTRAG | [email protected]       | 0000-00-00 00:00:00 | Select                                                                                       |             |
| localhost | Blogeinträge  | natascha      | BLOGEINTRAG                        | [email protected]       | 0000-00-00 00:00:00 | Select                                                                                       |             |
| localhost | Blogeinträge  | katrin        | NUTZER                             | [email protected]       | 0000-00-00 00:00:00 |                                                                                              | Select      |
| localhost | Blogeinträge  | katrin        | REDAKTEUR                          | [email protected]       | 0000-00-00 00:00:00 | Select,Insert,Update,Delete,Create,Drop,References,Index,Alter,Create View,Show view,Trigger |             |
| localhost | Blogeinträge  | natascha      | REDAKTEUR                          | [email protected]       | 0000-00-00 00:00:00 | Select                                                                                       |             |
| localhost | Blogeinträge  | natascha      | NUTZER                             | [email protected]       | 0000-00-00 00:00:00 |                                                                                              | Select      |
| localhost | Blogeinträge  | michael       | FAVORITENLISTEenthaltenBLOGEINTRAG | [email protected]       | 0000-00-00 00:00:00 | Select                                                                                       |             |
| localhost | Blogeinträge  | michael       | BLOGEINTRAG                        | [email protected]       | 0000-00-00 00:00:00 | Select                                                                                       |             |
| localhost | Blogeinträge  | michael       | REDAKTEUR                          | [email protected]       | 0000-00-00 00:00:00 | Select                                                                                       |             |
+-----------+---------------+---------------+------------------------------------+----------------------+---------------------+----------------------------------------------------------------------------------------------+-------------+
12 rows in set (0,01 sec)

Und über die Ausführung des darauffolgenden Kommandos kannst du dir die Attributwerte der columns_priv-Systemtabelle ausgeben lassen. Hierbei erkennst du dann weiter verfeinert, dass Katrin nach der Implementierung der Rechte in der Tabelle BLOGEINTRAG lediglich auf die Spalten Benutzername, Text und Titel die UPDATE-Operation ausführen darf, was letztlich das wiedergibt, was vorgesehen ist: nämlich dass die UPDATE-Operation für die restlichen Spalten der Tabelle (nämlich für die Spalten BlogeintragID, Erstellungsdatum und Änderungsdatum) für Katrin nicht erlaubt sein soll, sondern lediglich die SELECT– und die INSERT-Operation.

mysql> SELECT * from columns_priv;
+-----------+---------------+----------+-------------+------------------+---------------------+-------------+
| Host      | Db            | User     | Table_name  | Column_name      | Timestamp           | Column_priv |
+-----------+---------------+----------+-------------+------------------+---------------------+-------------+
| localhost | Blogeinträge  | katrin   | BLOGEINTRAG | Benutzername     | 0000-00-00 00:00:00 | Update      |
| localhost | Blogeinträge  | katrin   | BLOGEINTRAG | Text             | 0000-00-00 00:00:00 | Update      |
| localhost | Blogeinträge  | katrin   | BLOGEINTRAG | Titel            | 0000-00-00 00:00:00 | Update      |
| localhost | Blogeinträge  | katrin   | NUTZER      | FavoritenlisteID | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | katrin   | NUTZER      | EMailAdresse     | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | katrin   | NUTZER      | Benutzername     | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | natascha | NUTZER      | FavoritenlisteID | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | natascha | NUTZER      | EMailAdresse     | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | natascha | NUTZER      | Benutzername     | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | michael  | NUTZER      | FavoritenlisteID | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | michael  | NUTZER      | EMailAdresse     | 0000-00-00 00:00:00 | Select      |
| localhost | Blogeinträge  | michael  | NUTZER      | Benutzername     | 0000-00-00 00:00:00 | Select      |
+-----------+---------------+----------+-------------+------------------+---------------------+-------------+
12 rows in set (0,00 sec)

In den folgenden drei Shell-Snippets zeige ich dir, wie du dir ausgehend vom jeweiligen Benutzer-Account anzeigen lassen kannst, auf welche Tabellen der betreffende Nutzer Zugriff hat. Hierzu wird wieder der SHOW TABLES-Command genutzt, den ich schon unter dem Account von Jens verwendet habe, um mir seinen Zugriff auf alle Tabellen ausgeben zu lassen.

mysql -u katrin -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> SHOW TABLES;
+------------------------------------+
| Tables_in_Blogeinträge             |
+------------------------------------+
| BLOGEINTRAG                        |
| FAVORITENLISTEenthaltenBLOGEINTRAG |
| NUTZER                             |
| REDAKTEUR                          |
+------------------------------------+
4 rows in set (0,00 sec)
mysql -u natascha -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> SHOW TABLES;
+------------------------------------+
| Tables_in_Blogeinträge             |
+------------------------------------+
| BLOGEINTRAG                        |
| FAVORITENLISTEenthaltenBLOGEINTRAG |
| FAVORITENLISTE                     |
| NUTZER                             |
| REDAKTEUR                          |
+------------------------------------+
5 rows in set (0,00 sec)
mysql -u michael -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> SHOW TABLES;
+------------------------------------+
| Tables_in_Blogeinträge             |
+------------------------------------+
| BLOGEINTRAG                        |
| FAVORITENLISTEenthaltenBLOGEINTRAG |
| FAVORITENLISTE                     |
| NUTZER                             |
| REDAKTEUR                          |
+------------------------------------+
5 rows in set (0,00 sec)

Tabellen nach Inhalten durchsuchen, mit Inhalten befüllen, updaten und löschen

Als nächstes werde ich dir zeigen, wie du die bisher implementierten Tabellen mit Inhalten befüllst oder bereits bestehende Inhalte updatest oder löscht. Wie du weißt, kann lediglich der Chefredakteur Jens Inhalte in allen Tabellen via INSERT-Operation einfügen und lediglich der Redakteur Katrin kann in der Tabelle BLOGEINTRAG die INSERT-Operation durchführen. Zunächst wechselst du in den Account des Chefredakteurs Jens.

mysql -u jens -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

Dann befüllst du die Tabellen FAVORITENLISTE und NUTZER mit Inhalten. Die hierzu notwendige INSERT-Operation hat die Syntax, in der der Command INSERT INTO gefolgt wird von dem Datenbanknamen getrennt durch einen Punkt vom Tabellennamen. Hier kann allerdings auch lediglich der Tabellenname stehen. Also anstatt INSERT INTO Blogeinträge.FAVORITENLISTE könnte im ersten INSERT-Beispiel unten auch einfach nur INSERT INTO FAVORITENLISTE stehen, da du dich bereits in der Datenbank Blogeinträge befindest. Darauf folgt im Command VALUES, wo die zu befüllenden Attributwerte in Klammerung gelistet eingetragen werden. Hierbei ist es wichtig, auf die Reihenfolge der einzutragenden Attributwerte zu achten: diese muss der Reihenfolge entsprechen, in der die Spalten in einer Tabelle aufeinander folgen.

mysql> INSERT INTO Blogeinträge.FAVORITENLISTE VALUES(1001);
Query OK, 1 row affected (0,03 sec)

mysql> INSERT INTO Blogeinträge.FAVORITENLISTE VALUES(1002);
Query OK, 1 row affected (0,03 sec)

mysql> INSERT INTO Blogeinträge.FAVORITENLISTE VALUES(1003);
Query OK, 1 row affected (0,00 sec)

mysql> INSERT INTO Blogeinträge.FAVORITENLISTE VALUES(1004);
Query OK, 1 row affected (0,01 sec)

mysql> INSERT INTO Blogeinträge.NUTZER VALUES('jens', 'jensmu[email protected]', 'm', '1984-05-30', 'ferrari', 1001);
Query OK, 1 row affected (0,04 sec)

mysql> INSERT INTO Blogeinträge.NUTZER VALUES('katrin', '[email protected]', 'w', '1990-01-16', 'darkeyes', 1002);
Query OK, 1 row affected (0,03 sec)

mysql> INSERT INTO Blogeinträge.NUTZER VALUES('natascha', '[email protected]', 'w', '1987-08-22', 'starwish', 1003);
Query OK, 1 row affected (0,01 sec)

mysql> INSERT INTO Blogeinträge.NUTZER VALUES('michael', '[email protected]', 'm', '1989-03-14', 'infotech', 1004);
Query OK, 1 row affected (0,00 sec)

Um dir zu zeigen, dass Katrin fähig ist, die Tabelle BLOGEINTRAG mit Inhalten zu füllen, werde ich die hierzu notwendige Operation von ihrem Account aus ausführen, jedoch wäre Jens als Chefredakteur hierzu natürlich auch in der Lage.

mysql -u katrin -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> INSERT INTO Blogeinträge.REDAKTEUR VALUES('katrin', 'Katrin', 'Loos', 'Hi, mein Name ist Katrin und ich bin seit ...');
Query OK, 1 row affected (0,01 sec)

mysql> INSERT INTO Blogeinträge.REDAKTEUR VALUES('jens', 'Jens', 'Müller', 'Hey, ich freue mich auf dieser Plattform als ...');
Query OK, 1 row affected (0,03 sec)

Für die Befüllung mit Inhalten der Tabellen CHEFREDAKTEUR, BLOGEINTRAG und FAVORITENLISTEenthaltenBLOGEINTRAG wechsele ich wieder in den Account von Jens, da Katrin – wie bereits bekannt – für das Hinzufügen von Inhalten in Tabellen bis auf die Tabelle BLOGEINTRAG die Rechte fehlen.

mysql -u jens -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> INSERT INTO Blogeinträge.CHEFREDAKTEUR VALUES('jens', '+49 178 3339990');
Query OK, 1 row affected (0,01 sec)

mysql> INSERT INTO Blogeinträge.BLOGEINTRAG VALUES(2001, '2018-02-20', NULL, 'Test-Headline', 'In diesem Blogeintrag möchte ich Euch zeigen ...', 'katrin');
Query OK, 1 row affected (0,01 sec)

mysql> INSERT INTO Blogeinträge.BLOGEINTRAG VALUES(2002, '2018-02-20', '2018-02-24', 'Test-Headline', 'Heute werde ich über ...', 'jens');
Query OK, 1 row affected (0,03 sec)

mysql> INSERT INTO Blogeinträge.FAVORITENLISTEenthaltenBLOGEINTRAG VALUES(2001, 1003);
Query OK, 1 row affected (0,03 sec)

mysql> INSERT INTO Blogeinträge.FAVORITENLISTEenthaltenBLOGEINTRAG VALUES(2001, 1004);
Query OK, 1 row affected (0,01 sec)

mysql> INSERT INTO Blogeinträge.FAVORITENLISTEenthaltenBLOGEINTRAG VALUES(2002, 1002);
Query OK, 1 row affected (0,03 sec)

Nachdem du nun alle Tabellen mit Inhalten befüllt hast, sehen sie so aus, wie ich dir zu Beginn des Anwendungsszenarios gezeigt habe. Zum Ende dieses Tutorials möchte ich dir nun noch jeweils ein Beispiel für eine SELECT-, sowie eine UPDATE– und eine DELETE-Operation zeigen. Das Beispiel für die SELECT-Operation zeige ich dir ausgehend von den Benutzerrechten, die Natascha als Nutzer hat und die ebenso auf ein Beispiel von Michaels Account aus anwendbar wären. Das jeweilige Beispiel für die UPDATE– und DELETE-Operation zeige ich dir ausgehend von den Rechten, die Katrin als Redakteur besitzt. Zunächst loggst du dich unter Nataschas Account in MySQL ein und wechselst mit dem USE-Command in die Datenbank Blogeinträge.

mysql -u natascha -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

Wenn du nun versuchst, die Einträge zum Benutzernamen und dem dazugehörigen Geburtsdatum aus der Tabelle NUTZER zu selektieren, wird dir eine Fehlermeldung ausgegeben, in der du darauf hingewiesen wirst, dass die Spalte Geburtsdatum nicht erkannt wird, wie du im unteren Beispiel erkennst.

SELECT Benutzername, Geburtsdatum FROM REDAKTEUR;
ERROR 1054 (42S22): Unknown column 'Geburtsdatum' in 'field list'

Selektierst du hingegen die Spalteninhalte zu den Spalten Benutzername, EMailAdresse und FavoritenlisteID aus der Tabelle NUTZER, erhältst du entsprechenden Output, wie er im Beispiel darunter zu sehen ist.

SELECT Benutzername, EMailAdresse, FavoritenlisteID FROM NUTZER;
+--------------+---------------------------------+------------------+
| Benutzername | EMailAdresse                    | FavoritenlisteID |
+--------------+---------------------------------+------------------+
| jens         | [email protected]      |             1001 |
| katrin       | [email protected]      |             1002 |
| michael      | [email protected] |             1004 |
| natascha     | [email protected]               |             1003 |
+--------------+---------------------------------+------------------+
4 rows in set (0,00 sec)

Möchtest du dir als Nutzer Natascha lediglich Informationen anzeigen lassen, die dich selber betreffen, dann schränke das SELECT-Statement mit der WHERE-Bedingung ein, indem du z.B. die Bedingung anhand des Benutzernamens setzen kannst und somit die Treffermenge einschränkst, wie ich es dir im Beispiel unten verdeutliche.

SELECT Benutzername, EMailAdresse, FavoritenlisteID FROM NUTZER;
+--------------+---------------------------------+------------------+
| Benutzername | EMailAdresse                    | FavoritenlisteID |
+--------------+---------------------------------+------------------+
| natascha     | [email protected]               |             1003 |
+--------------+---------------------------------+------------------+
4 rows in set (0,00 sec)

Um nun das jeweilige Beispiel zur UPDATE– und DELETE-Operation unter Katrins Rechten nachzuvollziehen, loggst du dich unter ihrem Account ein und wechselst wieder in die Datenbank Blogeinträge.

mysql -u katrin -p
password: *********

mysql> USE Blogeinträge;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

Die Syntax der UPDATE-Operation setzt voraus, dass nach dem UPDATE der Name der Tabelle gesetzt werden muss oder der Name der Tabelle gefolgt von einem Punkt und der betreffenden Spalte. Dann wird mittels SET der neue Wert gesetzt und die bekannte WHERE-Bedingung dient auch bei dieser Operation zur Einschränkung der Treffermenge. Sollen mehr als ein Wert neu gesetzt werden, kann dies über die booleschen Operatoren AND oder OR erfolgen. Wenn du hier nun versuchst das Änderungsdatum zu ändern, wird dir die Fehlermeldung ausgegeben, die dich darüber in Kenntnis setzt, dass du keinen Zugriff auf das Ändern von Werten in der Spalte Änderungsdatum besitzt, wie du dem Beispiel unten entnimmst.

UPDATE BLOGEINTRAG SET Änderungsdatum = '2018-04-01' WHERE Titel = 'Test-Headline' AND Benutzername = 'katrin';
ERROR 1143 (42000): UPDATE command denied to user 'katrin'@'localhost' for column 'Änderungsdatum' in table 'BLOGEINTRAG'

Wenn du hingegen den Titel eines bestimmten Blogeintrags änderst, wie im Beispiel unten, wird der UPDATE-Command durchgeführt, weil der Redakteur eben UPDATE-Rechte an der Spalte Titel der Tabelle BLOGEINTRAG hat. Hättest du im Beispiel unten ohne WHERE-Bedingung gearbeitet, würde der Titel in allen Zeilen der Tabelle in ‘Hallo Welt!’ geändert werden.

UPDATE BLOGEINTRAG Titel SET Titel = 'Hallo Welt!' WHERE Titel = 'Test-Headline' AND Benutzername = 'katrin';
Query OK, 1 row affected (0,03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Das Ergebnis deiner UPDATE-Operation kannst du dir im Nachgang via SELECT-Operation ausgeben lassen, wie ich es dir z.B. unten zeige.

SELECT Titel FROM BLOGEINTRAG WHERE Benutzername = 'katrin';
+-------------+
| Titel       |
+-------------+
| Hallo Welt! |
+-------------+
1 row in set (0,01 sec)

Im letzten Beispiel, in dem ich mit dir eine DELETE-Operation durchführe, gehen wir davon aus, dass in der Tabelle REDAKTEUR zwischenzeitlich ein neuer Redakteur hinzugefügt wurde, nämlich der Redakteur mit dem Benutzernamen Sabine, wie in der Tabelle unten aufgeführt ist. Dieser neu hinzugefügte Redakteur soll nun aber wieder aus der Tabelle REDAKTEUR entfernt werden, weil Frau Stein nunmehr doch nicht mehr in dem betreffenden Blogsystem als Redakteur tätig sein möchte. Frau Stein könnte als Redakteur die Löschung auch selber durchführen, aber in meinem Beispiel lasse ich dies Katrin tun.

Tabelle REDAKTEUR in Datenbank Blogeinträge

Die Syntax der DELETE-Operation sieht vor, dass nach dem DELETE FROM die betreffende Tabelle angetriggert wird und mit der WHERE-Bedingung hier – anders als wie im Fall der SELECT– oder UPDATE-Operation – die WHERE-Bedingung essentiell ist und nicht lediglich zur Wahl steht, um die Treffermenge einzuschränken.

mysql> DELETE FROM REDAKTEUR WHERE Benutzername = 'sabine';
Query OK, 1 row affected (0,03 sec)

Auch in diesem Beispiel lassen wir uns zur Prüfung das Ergebnis der DELETE-Operation ausgeben, indem wir uns alle Benutzernamen anzeigen lassen, die sich nun noch in der Tabelle REDAKTEUR befinden, wie du im Beispiel darunter siehst.

mysql> SELECT Benutzername FROM REDAKTEUR;
+--------------+
| Benutzername |
+--------------+
| jens         |
| katrin       |
+--------------+
2 rows in set (0,00 sec)

Wie dir aus der Beschreibung des Anwendungsszenarios bekannt ist, ist jeder Redakteur zwangsläufig auch ein Nutzer. Wenn Frau Stein also komplett aus der Datenbank entfernt werden soll, dann müsste final eine DELETE-Operation in der Tabelle NUTZER hierzu stattfinden, was du in der Rolle, bzw. unter dem Account des Chefredakteurs Jens umsetzen kannst, um die Tabelle NUTZER in dem Zustand zu haben, wie im Bild zu Beginn des Anwendungsszenarios gezeigt.

Fazit

Nachdem wir nun zusammen eine Datenbank erstellt, aufgebaut und Rechte pro Nutzer individuell zugeteilt haben, hast du ein Gefühl dafür bekommen, wie flexibel und steuerbar die Vergabe von Rechten in MySQL ist und bist in der Lage, die Rechte pro Nutzer in bestimmten Datenbanken fein abzustimmen und somit einen gewissen Grad an Datenkontrolle zu gewährleisten. Mir hat es Freude gemacht, dich durch das Anwendungsszenario zu führen und ich wünsche dir viel Spaß bei der Umsetzung der gelernten Inhalte.

Zurück zur Tutorial Übersicht Back to Tutorial Overview

InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten

InfluxDB unter Ubuntu installieren und einrichten

Wir haben dir bereits in unserem Tutorial zu MySQL Datenbank erstellen und löschen und PostgreSQL 10 auf Ubuntu 16.04 / 14.04 installieren gezeigt, wie du objektrelationale SQL-Datenbanken auf deinem Ubuntu-Server installierst und einrichtest. Ebendies haben wir dir auch für objektrelationale NO-SQL Datenbanken wie MongoDB, Redis und RethinkDB in unseren Tutorials MongoDB auf Ubuntu installieren, Apache Cassandra auf Ubuntu installieren, Redis auf Ubuntu 16.04 LTS installieren und RethinkDB auf Ubuntu installieren nahe gebracht. In diesem Tutorial geht es nun um ein Open Source-Produkt, das an das Konzept einer Datenbank angelehnt ist, sich aber von den bisher durch uns vorgestellten Modellen der SQL- und NO-SQL-Datenbanken abhebt. Ich werde dich in den folgenden Kapiteln mit InfluxDB vertraut machen. Solltest du mit der Installation, dem Einrichten und/oder der Nutzung von InfluxDb bereits betraut sein, können für dich weiterführend die Tutorials InfluxDB – Monitoring mit dem TICK-Stack oder InfluxDB – Monitoring mit dem TIG-Stack interessant und hilfreich sein, da es auch direkt an das in diesem Tutorial beschriebene Anwendungsszenario anknüpft.

Neu! – Autoscale MySQL-as-a-Service von Tech4Hosting

Alle, die sich nicht mehr mit Datenbank-Administration auseinandersetzen wollen, können jetzt auch die neuen Platform Services von Tech4Hosting nutzen.

Der Vorteil der Platform Services bei Tech4Hosting: Wir kümmern uns um die sichere Konfiguration, den zuverlässigen Betrieb und die Installation von Sicherheitsupdates deiner PaaS-Dienste. In deinem Tech4Hosting Panel kannst du ab sofort mit den Datenbanken PostgreSQL, MySQL und redis starten.
Probiere es einfach mal aus!

Mehr Infos zu PaaS bei Tech4Hosting und wie PaaS funktioniert gibt es in unserem
Getting started mit PaaS bei Tech4Hosting
Platform Services von Tech4Hosting.

Zu InfluxDB

Mit InfluxDB wird eine komplette Open Source-Plattform angeboten, die für Metriken, Ereignisse und andere zeitbasierte Daten von Menschen, Sensoren oder Maschinen und deren Verarbeitung, bzw. Auswertung entwickelt wurde. In Echtzeit können Daten gesammelt, gespeichert, visualisiert und Erkenntnisse in Aktionen umgesetzt werden. Es handelt sich sozusagen um eine moderne Zeitreihen-Plattform. InfluxDB differenziert sich somit vom Modell einer SQL- oder NoSQL-Datenbank, da dieses Produkt als Plattform fungiert und nicht auf einen SQL- oder NoSQL-Speicher beschränkt ist. Da sich Compute-Infrastruktur und -Architekturen als Konsequenz neuer Anforderungen und Bedürfnisse weiterentwickeln, genügen bestehende Technologien meist nicht, um die damit verbundenen neuen Anforderungen zu erfüllen (Big Data und das Aufkommen von HDFS und Hadoop). Und da die bisherige Technologie der Datenspeicherung in SQL- und NoSQL-Speichern diesen nicht gerecht wurde, wurde InfluxDB entwickelt. InfluxDB bietet für die Speicherung von Zeitreihendaten in einer Zeitreihen-Datenbank eine zweckmäßige und moderne Zeitreihen-Plattform. Die Transparenz und Kontrolle von Zeit gehören zum Zeitalter der Digitalisierung und Instrumentierung, in der Echtzeitverarbeitung datengesteuerten Organisationen Einblicke und Wettbewerbsvorteile verschaffen können. Als eine End-to-End-Plattform kann InfluxDB in der Cloud oder per Download bereitgestellt werden, elegant und einfach zu bedienen, frei von externen Abhängigkeiten, aber offen und flexibel genug für komplexe Implementierungen. Die Analyse der Daten erfolgt über eine SQL-ähnliche Abfragesprache.
Man kann seine Daten sogar mit dem integrierten Open-Source-Projekt Chronograf grafisch darstellen und visualisieren und eine somit eine Untersuchung im Sinne von Daten-Plotting durchführen. Hierzu wirst du im vorletzten Kapitel dieses Tutorials mehr erfahren. Darüber hinaus unterstützt InfluxDB andere Visualisierungswerkzeuge wie Grafana.

Anwendungsszenario

Um dir ein Gefühl für die Arbeit mit der Datenbank-Plattform InfluxDB zu geben, werde ich mit dir einen Real-Live Case simulieren, bei dem wir uns im Anschluss die in eine angelegte Datenbank integrierten Datenpunkte visuell analysiert plotten lassen werden. Hierzu nehme ich mit dir die Perspektive eines Unternehmens ein, das Wert darauf legt, seine über den Online-Shop stattfindenden Verkaufsaktivitäten als Messung in Relation zur Zeit, sowie den Tatsachen, wie alt die Person ist (INTEGER) und letztlich eingekauft wurde oder nicht (Boolean TRUE/FALSE) als Messwerten und schließlich zu demographischen Daten wie dem Geschlecht und dem Standort sowohl seiner bereits existierenden Kunden als auch potentieller Kunden zu betrachten. Aus den sich aus Besucher-Tracking-Zeitreihen ergebenden Datenpunkten können möglicherweise interessante Informationen ermittelt und auf Basis dieser Informationen zukünftige Online-Marketingstrategien (z.B. Newsletter, Social-Media) und Usability-Maßnahmen entwickelt und/oder optimiert werden. Das Projekt soll sozusagen helfen, die Psychologie des Online-Shoppings zu verstehen, indem Einkaufsphasen und die dahinter stehenden Kunden in bestimmten Kontexten erkannt werden. Es ist – wie schon erwähnt – ein an die Realität angelehntes Fallbeispiel, dass dir lediglich zur Orientierung dienen soll. InfluxDB kann natürlich nicht nur für gewerbliche Zwecke sehr hilfreich sein, sondern auch für private oder auf Bildung ausgelegte Projekte jeglicher Art genutzt werden, um Zeitreihen basierte Zusammenhänge von Datenmengen wiederauffindbar, bewachbar, analysierbar, auswertbar und visualisierbar zu machen.
Zur Simulation des Szenarios werde ich die Datenpunkte mittels der aus der SQL-Datenbanksprache bekannten INSERT-Operation sozusagen als Indexer in die betreffende Messung implementieren. Mit Ausblick auf einen Real-Life Case darfst du dir vorstellen, dass die pro Datenpunkt enthaltenen Informationen direkt auf der Website getrackt und über eine im Hintergrund agierende Software automatisiert an die Datenbank kommuniziert wurden. Wobei die persönlichen Informationen zu Geschlecht und Alter über eine für den Besucher unumgängliche Interface-Abfrage auf der Website abgefangen wurden. Ich beschränke mein Zeitreihen-Szenario auf ein Zeitfenster, das Datenpunkte zum 17.04.2018 im Zeitraum 13:00 bis 13:15 enthält und diese im Epoch-Zeitformat auf Minuten bestimmt getrackt wurden.

Voraussetzungen

Die Nutzung von InfluxDB setzt das Vorhandensein der Netzwerkports 8086 und 8088 auf deinem System voraus, wobei der TCP-Port 8086 für die Client-Server-Kommunikation über die HTTP-API von InfluxDB verwendet wird und der TCP-Port 8088 für den RPC-Dienst zum Sichern und Wiederherstellen.
Neben diesen beiden Ports bietet InfluxDB mehrere Plugins, die möglicherweise benutzerdefinierte Ports erfordern. Es ist möglich alle Port-Zuordnungen über die Konfigurationsdatei zu ändern. Die Port-Zuordnungen befinden sich bei Standardinstallationen in der Datei /etc/influxdb/influxdb.conf. Informationen darüber, wie du diese Datei editieren kannst, findest du im Kapitel InfluxDB konfigurieren.
Die unten stehende Tabelle bietet dir einen guten Überblick über mögliche Ports.

Port

Bedeutung

8086

Der Standardport, auf dem der HTTP-Dienst InfluxDB ausgeführt wird. Du kannst diesen Port in der Konfigurationsdatei konfigurieren, indem du bind-address = „127.0.0.1:8086“ setzt.

Umgebungsvariable: INFLUXDB_HTTP_BIND_ADDRESS

8088

Der Standardport, auf dem der RPC-Dienst zum Sichern und Wiederherstellen ausgeführt wird. Du kannst diesen Port in der Konfigurationsdatei konfigurieren, indem du bind-address = „127.0.0.1:8088“ setzt.

Umgebungsvariable: INFLUXDB_HTTP_BIND_ADDRESS

2003

Der Standardport, auf dem der Graphite-Dienst ausgeführt wird.

Du kannst diesen Port in der Konfigurationsdatei konfigurieren, indem du bind-address = „127.0.0.1:2003“ setzt.

Umgebungsvariable: INFLUXDB_GRAPHITE_0_BIND_ADDRESS

4242

Der Standardport, auf dem der OpenTSDB-Dienst ausgeführt wird.

Du kannst diesen Port in der Konfigurationsdatei konfigurieren, indem du bind-address = „127.0.0.1:4242“ setzt.

Umgebungsvariable: INFLUXDB_OPENTSDB_BIND_ADDRESS

8089

Der Standardport, auf dem der UDP-Dienst ausgeführt wird.

Du kannst diesen Port in der Konfigurationsdatei konfigurieren, indem du bind-address = „127.0.0.1:8089“ setzt.

Umgebungsvariable: INFLUXDB_UDP_BIND_ADDRESS

25826

Der Standardport, auf dem der Collect-Dienst ausgeführt wird.

Du kannst diesen Port in der Konfigurationsdatei konfigurieren, indem du bind-address = „127.0.0.1:25826“ setzt.

Umgebungsvariable: INFLUXDB_COLLECTD_BIND_ADDRESS

 

aktivierte Ports

 

deaktivierte Ports

Bei InfluxDB dienen Zeitstempel zur Koordination und zur Zuordnung von Daten, wobei die lokale Zeit eines Hosts in UTC genutzt wird. Um eine Ungenauigkeit der Zeitstempel der in INfluxDB geschriebenen Daten zu vermeiden, ist es nötig, die Zeit zwischen Hosts mittels Verwendung des Network Time Protocol (NTP) zu synchronisieren.

InfluxDB installieren

Zunächst musst du das InfluxDB-Repository mit den folgenden drei Befehlen hinzufügen.


> curl -sL https://repos.influxdata.com/influxdb.key | apt-key add -

> source /etc/lsb-release

> echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | tee /etc/apt/sources.list.d/influxdb.list

Sowohl für Ubuntu-Versionen unterhalb Ubuntu 15.04+ als auch die darüber liegenden Versionen, müsstest du für die Installation von InfluxDB das unten stehende Kommando im Terminal ausführen.


> apt-get update && sudo apt-get install influxdb

Nach der Installation ist es noch notwendig, dass du InfluxDB startest. Der hierfür zu verwendende Command unterscheidet sich bei Ubuntu-Versionen unterhalb Ubuntu 15.04+ von denen, deren Version darüber liegt. Im Fall von Ubuntu-Versionen unterhalb Ubuntu 15.04+ wäre für den Start die Kommandozeile richtig, wie sie im Code-Block unten zu sehen ist.


> service influxdb start

Mit Ubuntu-Versionen ab Ubuntu 15.04+ allerdings wird das Hintergrundprogramm systemd im Kommando berücksichtigt, das den Start von InfluxDB umsetzt. Somit sollte das Kommando für den Start von InfluxDB so aussehen, wie im unten eingeblendeten Code-Snippet demonstriert.


> systemctl start influxdb

InfluxDB konfigurieren

Für die Einstellung jeder Konfigurationsdatei stellt das System interne Standardeinstellungen bereit. Via dem unten gezeigten Command kannst du dir die Einstellungen im nano-Editor ansehen und bei Bedarf editieren.


> nano /etc/influxdb/influxdb.conf

Die meisten Einstellungen in der lokalen Konfigurationsdatei /etc/influxdb/influxdb.conf sind auskommentiert. Alle auskommentierten Einstellungen werden durch die internen Standardeinstellungen bestimmt. Alle unkommentierten Einstellungen in der lokalen Konfigurationsdatei überschreiben die internen Standardeinstellungen. Beachte, dass die lokale Konfigurationsdatei nicht bereits alle Konfigurationseinstellungen enthalten muss.

Bevor du mit InfluxDB arbeiten kannst, also z.B. um (eine) Datenbank(en) anzulegen, zu löschen oder zu editieren oder Daten zu analysieren, musst du InfluxDB einmalig mit deiner Konfigurationsdatei starten.
Hierbei gibt es zwei Möglichkeiten:

1. Richte den Prozess mit der Option -config auf die richtige Konfigurationsdatei aus.


> influxd -config /etc/influxdb/influxdb.conf


 8888888           .d888 888                   8888888b.  888888b.
   888            d88P"  888                   888  "Y88b 888  "88b
   888            888    888                   888    888 888  .88P
   888   88888b.  888888 888 888  888 888  888 888    888 8888888K.
   888   888 "88b 888    888 888  888  Y8bd8P' 888    888 888  "Y88b
   888   888  888 888    888 888  888   X88K   888    888 888    888
   888   888  888 888    888 Y88b 888 .d8""8b. 888  .d88P 888   d88P
 8888888 888  888 888    888  "Y88888 888  888 8888888P"  8888888P"

2018-04-04T23:03:51.641110Z	info	InfluxDB starting	{"log_id": "07GjHMMG000", "version": "1.5.1", "branch": "1.5", "commit": "cdae4ccde4c67c3390d8ae8a1a06bd3b4cdce5c5"}
2018-04-04T23:03:51.641142Z	info	Go runtime	{"log_id": "07GjHMMG000", "version": "go1.9.2", "maxprocs": 4}
run: open server: listen: listen tcp 127.0.0.1:8088: bind: address already in use

2. Setze die Umgebungsvariable INFLUXDB_CONFIG_PATH in Relation zu dem Pfad deiner Konfigurationsdatei und starte den Prozess.


> echo $INFLUXDB_CONFIG_PATH /etc/influxdb/influxdb.conf

> influxd


 8888888           .d888 888                   8888888b.  888888b.
   888            d88P"  888                   888  "Y88b 888  "88b
   888            888    888                   888    888 888  .88P
   888   88888b.  888888 888 888  888 888  888 888    888 8888888K.
   888   888 "88b 888    888 888  888  Y8bd8P' 888    888 888  "Y88b
   888   888  888 888    888 888  888   X88K   888    888 888    888
   888   888  888 888    888 Y88b 888 .d8""8b. 888  .d88P 888   d88P
 8888888 888  888 888    888  "Y88888 888  888 8888888P"  8888888P"

2018-04-04T23:43:31.184743Z	info	InfluxDB starting	{"log_id": "07GlYaS0000", "version": "1.5.1", "branch": "1.5", "commit": "cdae4ccde4c67c3390d8ae8a1a06bd3b4cdce5c5"}
2018-04-04T23:43:31.184777Z	info	Go runtime	{"log_id": "07GlYaS0000", "version": "go1.9.2", "maxprocs": 4}
run: open server: listen: listen tcp 127.0.0.1:8088: bind: address already in use

InfluxDB funktioniert so, dass zunächst die Konfiguration über die Option -config überprüft wird und im Anschluss daran die über die Umgebungsvariable.
Des Weiteren musst du sicherstellen, dass die Verzeichnisse, in denen Daten und das Write Ahead-Protokoll (WAL) gespeichert sind, für dich schreibbar sind, bevor du den InfluxDB-Dienst ausführst. Sprich, du musst du prüfen, ob diese Verzeichnisse existieren. Für den Fall, dass die Daten- und WAL-Verzeichnisse nicht beschreibbar sind, wird der InfluxdDB-Service nämlich nicht gestartet. Beide sollten im Verzeichnis /var/lib/influxdb liegen. Im Terminal kannst du dir die darin befindlichen Verzeichnisse mit den beiden folgenden Kommandos anzeigen lassen und somit deren Beschreibbarkeit garantieren.


> cd /var/lib/influxdb

> ls

In InfluxDB eine Datenbank anlegen, nutzen oder löschen

Um mit InfluxDB zu arbeiten, kannst du die influx-Befehlszeilenschnittstelle (CLI) nutzen, die in allen InfluxDB-Paketen enthalten ist und eine leichte und einfache Möglichkeit bietet, mit der Datenbank zu interagieren. Die CLI kommuniziert direkt mit InfluxDB, indem standardmäßig Anfragen an die InfluxDB-HTTP-API über Port 8086 gestellt werden. Daher stellt Influx standardmäßig eine Verbindung zu Port 8086 und localhost her. Wenn du diese Standardwerte ändern musst, führe den Command influx –help im Terminal aus.
Schließlich kannst du die CLI über den influx-Command – wie ich es dir im Code-Block unten zeige – starten und somit eine Verbindung zur lokalen InfluxDB-Instanz herstellen. Am daraufhin generierten Output kannst du erkennen, dass der korrekte Port 8086 angetriggert worden ist und auch die Version der InfluxDB wird dir angezeigt.
In meinem Beispiel nutze ich zusätzlich zum influx-Command das Argument -precision. Dieses gibt das Format/die Genauigkeit von zurückgegebenen Zeitstempeln an. Im obigen Beispiel teilt das Attribut rfc3339 InfluxDB mit, dass Zeitstempel im RFC3339-Format zurückgegeben werden sollen, was wiederum dem Format YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ entspricht.


> influx -precision rfc3339
Connected to http://localhost:8086 version 1.5.x
InfluxDB shell version: 1.5.x

Solltest du Zeitstempel im Format Unix-Epoch bevorzugen, dann sollte hingegen nach -precision ein Element aus der Liste [h, m, s, ms, u, ns] folgen. Zum Beispiel bekommst du Epoch in Stunden, wenn den Command so angibst, wie im Code-Snippet unten veranschaulicht.


> influx -precision s
Connected to http://localhost:8086 version 1.5.x
InfluxDB shell version: 1.5.x

Mittels dem EXIT-Command kannst du die CLI wieder verlassen oder auch jede andere Datenbank, die du in InfluxDB erzeugt hast.
Um eine Datenbank anzulegen, nutzt du den CREATE DATABASE-Command, wie ich dir im Code-Snippet unten veranschauliche, in dem ich die Datenbank OnlineMarketDevelopment anlege.


> CREATE DATABASE OnlineMarketDevelopment

Mittels dem SHOW DATABASES-Command ist es dir möglich, die alle existierenden Datenbanken ausgeben zu lassen.


> SHOW DATABASES
name: databases
name
----
_internal
OnlineMarketDevelopment

Um eine Datenbank hingegen zu löschen, wird der DROP DATABASE-Command genutzt. Hätte ich in der Zwischenzeit noch zusätzlich die Datenbank HumanResources angelegt und würde diese wieder löschen wollen, würde mein Command so aussehen.


> DROP DATABASE HumanResources

Wenn du schließlich eine spezielle Datenbank mit Inhalten füllen, nach Inhalten durchsuchen oder nach Inhalten analysieren willst, dann musst du explizit mit dem USE-Command in die betreffende Datenbank wechseln. Solange du dann nicht den EXIT-Command ausführst, werden alle Operationen lediglich auf die in meinem Beispiel gezeigte Datenbank OnlineMarketDevelopment ausgeübt.


> USE OnlineMarketDevelopment
Using database OnlineMarketDevelopment

Als Hinweis ist noch wichtig, dass du InfluxDB nicht nur über die CLI nutzen kannst, sondern auch direkt über rohe HTTP-Anfragen mittels der curl-Applikation. Im Terminal würde der Befehl für eine Anfrage über einen POST-Request im Endpunkt /query resultieren und dann dem Schema folgen, wie ich es dir im Code-Block unten präsentiere, wobei nach q= jedes Datenbank-Kommando – bis auf den USE-Command ausgeführt werden kann, das ich bereits in den oben gezeigten Code-Snippets über die CLI durchgeführt habe und XXX sozusagen als Platzhalter zu interpretieren ist.


> curl -i -XPOST http://localhost:8086/query --data-urlencode "q=XXX"

Angewendet auf den DROP-Command, würde die Kommandozeile als rohe HTTP-Anfrage dann so aussehen, wie du dem Code-BLock unten entnimmst.


> curl -i -XPOST http://localhost:8086/query --data-urlencode "q=DROP DATABASE HumanResources"

HTTP/1.1 200 OK
Content-Type: application/json
Request-Id: c53a00b6-3caa-11e8-8018-000000000000
X-Influxdb-Build: OSS
X-Influxdb-Version: 1.5.1
X-Request-Id: c53a00b6-3caa-11e8-8018-000000000000
Date: Tue, 10 Apr 2018 10:34:38 GMT
Transfer-Encoding: chunked

{"results":[{"statement_id":0}]}

In InfluxDB eine Datenbank mit Inhalten füllen und nach Inhalten durchsuchen

Nachdem wir gemeinsam die Datenbank OnlineMarketDevelopment erstellt und uns mittels dem USE-Command Zugang zu dieser verschafft haben, ist InfluxDB bereit, Anfragen und Schreibvorgänge in dieser zu akzeptieren.
Den Datenspeicher in InfluxDB darfst du dir so vorstellen, dass die Daten nach Zeitreihen gegliedert sind, sodass sie eine zeitabhängige Folge von Datenpunkten bilden. Die Datenpunkte wiederum beziehen sich auf eine Messung. Im Sinne des von mir vorgestellten Anwendungsszenarios könnte das z.B. die Messung mit der Bezeichnung SalesActivity sein. Zeitreihen können null bis viele Datenpunkte haben, wobei jeder Datenpunkt für eine Stichprobe der Metrik steht. Datenpunkte bestehen aus der Zeit (ein Punkt ist zu verstehen als ein Zeitstempel), mindestens einem Feld-Schlüssel-Wert-Paar (dem hinter der Messung SalesActivity stehenden Werten selbst, z. B. age=52i und buying=FALSE) und Null oder vielen Tag-Schlüssel-Wert-Paaren, die Metadaten zum Messwert enthalten (z. B. gender=“male“ region=“EMEA“ und dc=“koeln“). EMEA als Wert des Feld-Schlüssels region stünde dann für den Wirtschaftsraum Europa, Naher Osten und Afrika.
Im Hinblick auf die Integration in der Datenbank-Plattform kann man sich eine Messung konzeptionell als eine SQL-Tabelle vorstellen, bei der der Primärindex, bzw. Primärschlüssel immer die Zeit in Form des Zeitstempels ist. Tags und Felder sind als Spalten in der Tabelle zu verstehen. Tags werden indiziert und Felder nicht. Nullwerte werden nicht gespeichert.
Punkte werden in InfluxDB unter Verwendung des Leitungsprotokolls geschrieben. Das Format gleicht dem, das du dem im Code-Block unten integrierten Muster entnimmst, wobei die in ()-Klammern stehenden Bezeichnungen als Platzhalter zu interpretieren sind und die []-Klammern lediglich zur Wahrung der Übersichtlichkeit innerhalb der Syntax dienen. Es ist aus dem Muster im Code-Snippet unten gut ersichtlich wie die Tag-Schlüssel-Wert-Paare von den Feld-Schlüssel-Wert-Paaren bei der Zuordnung zur Messung kenntlich gemacht werden. Wenn nach der Messung ein Komma folgt, dann ist mindestens ein Tag vorhanden. Solltest du allerdings kein(e) Tag-Schlüssel-Wert-Paar(e) verwenden, dann folgt nach der Messung – lediglich getrennt durch ein Leerzeichen – unmittelbar das/die Feld-Schlüssel-Wert-Paar(e). Allgemein folgt das erste Feld-Schlüssel-Wert-Paar nie auf ein Komma. Sowohl die Tag-Schlüssel-Wert-Paare als auch die Feld-Schlüssel-Wert-Paare werden – sobald es sich um mehr als eins handelt – durch Komma gelistet. Hier musst du darauf achten, dass dazwischen keine Leerzeichen stehen, da es ansonsten zu einer Fehlermeldung kommt.


*Messung*[,(Tag-Schlüssel)=(Tag-Wert),...] (Feld-Schlüssel)=(Feld-Wert)[,(Feld2-Schlüssel)=(Feld2-Wert),...][Unix-Nanosekunden-Zeitstempel]

In der Tabelle unten findest du alle Parameter dieser Syntax gelistet im Zusammenhang mit deren Bedarf, deren Bedeutung und Datentyp.

Element der Syntax

optional vs. erforderlich

Bedeutung

Datentyp

Messung

erforderlich

Name der Messung. Entspricht konzeptionell einem Namen, den man einer SQL-Tabelle geben würde.

Beim INSERT eines Datensatzes wird – gemäß der Syntax – eine Messung pro Datenpunkt akzeptiert.

String

Tag-Sammlung

optional

Alle Tag-Schlüssel-Wert-Paare des Datenpunktes.

Sowohl Schlüssel als auch Werte werden jeweils als String integriert.

Feld-Sammlung

erforderlich

> Ein Datenpunkt muss mindestens einem Feld zugeordnet werden können.

Alle Feld-Schlüssel-Wert-Paare des Datenpunktes.

Feld-Schlüssel werden jeweils als String eingebunden und Feld-Werte jeweils als String, Integer, Float oder Boolean.

Zeitstempel

optional

> Falls dieser nicht beim INSERT des Datensatzes gesetzt wird und somit nicht im Datenpunkt enthalten ist, verwendet InfluxDB den lokalen Nanosekunden-Zeitstempel des Servers in UTC.

Beim INSERT eines Datensatzes wird – gemäß der Syntax – ein Zeitstempel pro Datenpunkt akzeptiert.

Unix-Nanosekunden-Zeitstempel

Wenn du den Datentyp Boolean für bestimmte Feld-Werte nutzen möchtest, dann beachte, dass sowohl TRUE als auch FALSE in InfluxDB auf unterschiedliche Weise interpretiert werden können. Die unten stehende Tabelle gibt dir einen schnellen Überblick zu den Möglichkeiten der Boolean-Syntax. Hieraus entnimmst du, dass beim Schreiben von Datenpunkten (via INSERT-Operation) jeweils zwei Schreibweisen mehr für die beiden Boolean-Werte genutzt werden können als beim Lesen von Datenpunkten (z.B. via SELECT-Statement). Diese beiden jeweils für TRUE und FALSE zusätzlich nutzbaren Schreibweisen werden beim Lesen von Datenpunkten zwar als entsprechender Boolean-Wert interpretiert, aber sind lediglich über die in der Spalte ganz rechts aufgeführten Schreibweisen erreichbar.

Boolean

akzeptierte Schreibweisen in InfluxDB bei INSERT-Operationen

akzeptierte Schreibweisen in InfluxDB bei SELECT-Operationen

TRUE

t, T, true, True oder TRUE

true, True oder TRUE

FALSE

f, F, false, False, FALSE

false, False, FALSE

Die bereits aus SQL bekannte INSERT-Operation wird auch bei InfluxDB genutzt, um in eine Messung bzw. in eine konzeptionelle SQL-Tabelle Datenpunkte einzubinden. Dem unten eingeblendeten Code-Snippet kannst du nachempfinden, wie solch ein INSERT angewendet auf die Messung SalesActivity aussehen kann. In dem von mir über die CLI durchgeführten INSERT-BeIspiel setze ich den Zeitstempel des Datenpunktes selbst, nämlich im Epoch-Format in Sekunden. Wenn man den jeweils zu einem integrierten Datenpunkt gehörenden Zeitstempel nicht implementiert, wird er in InfluxDB automatisch auf Basis der aktuellen Zeit gesetzt. Im Hinblick auf Zahlen, also Zahlen, die dem Datentyp INTEGER angehören, solltest du berücksichtigen, dass bei ihrer Implementierung ein i suffigiert werden muss, da sie ansonsten als Gleitkommazahl interpretiert werden. Diese Konvention gilt allerdings nur für ganze Zahlen. Gleitkommazahlen, also Zahlen, die dem Datentyp FLOAT angehören, sind davon nicht betroffen und werden in der Datenbank direkt als solche erkannt. In der Datenbank sind die Werte für ganze Zahlen dann als ganze Zahlen gespeichert, ohne das nachfolgende i. Es spielt – wie gesagt – lediglich bei der Implementierung eine Rolle. Im Code-Snippet unten heißt es dann für das Feld age nicht age=52, sondern age=52i. Zudem solltest du die Konvention beibehalten, dass du in einem INSERT alle als Datentyp STRING vorgesehenen Werte in Anführungszeichen setzt, um sie explizit als solche von anderen Datentypen differenzierbar zu machen. Würdest du dies nicht tun, also wären alle Werte nicht in Anführungszeichen gesetzt, würde auch zwangsläufig der Feld-Wert in age=52i als String „52i“ erkannt werden und nicht als Zahl 52i. Folglich müsste der komplette INSERT so aussehen, wie im Code-Block unten demonstriert.


> INSERT SalesActivity,region="EMEA",dc="koeln",gender="male" age=52i,buying=FALSE 1523962800

Auch das Schreiben von Daten – also auch die INSERT-Operation ist via rohen HTTP-Anfragen möglich. Hierbei mündet der POST-Request allerdings nicht im Endpunkt /query, sondern im Endpunkt /write. Und hier wird der in der CLI anwendbare USE-Command nicht ausgeführt, sondern bereits direkt im Anschluss an den Endpunkt /write via ?db= angetriggert. In der HTTP-Anfrage unten könnte ich den Zeitstempel auch selbst setzen, aber ich tue dies nicht, sodass er automatisch in InfluxDB vergeben wird.


> curl -i -XPOST 'http://localhost:8086/write?db=OnlineMarketDevelopment' --data-binary 'SalesActivity,region="EMEA",dc="koeln",gender="male" age=52i,buying=FALSE'

HTTP/1.1 200 Ok
Content-Type: application/json
Request-Id: 3afe35d0-3c14-11e8-8048-000000000000
X-Influxdb-Build: OSS
X-Influxdb-Version: 1.5.1
X-Request-Id: 3afe35d0-3c14-11e8-8048-000000000000
Date: Mon, 09 Apr 2018 16:37:02 GMT

Über die CLI kannst du dir dann mittels dem SELECT-Statement Datensätze wiedergeben lassen. Es funktioniert genauso, wie bei einer SQL-Abfrage. Nach dem SELECT werden die Spalten gelistet, deren Inhalte gefunden werden sollen, mittels dem FROM wird die Verortung der Spalten angetriggert, was konzeptionell der betreffenden SQL-Tabelle entsprechen würde und in InfluxDB der betreffenden Messung SalesActivity. Wäre die Messung SalesActivity bereits mit vielen Datenpunkten gefüllt, könntest du zusätzlich noch die WHERE-Bedingung einsetzen, um die Treffermenge zu spezifizieren.


> SELECT "region", "gender", "age", "dc", "buying" FROM "SalesActivity"
name: SalesActivity
time       region gender age dc      buying
----       ------ ------ --- --      ------
1523962800 "EMEA" "male" 52  "koeln" false

Würdest du für das SELECT die rohe HTTP-Anfrage nutzen, sähe das Kommando so aus, wie unten im Code-Block zu entnehmen. Nun stellst du eine GET-Request an den /query-Endpunkt, legst den URL-Parameter db als Zieldatenbank fest, und bettest deine Anfrage in q= ein.


curl -GET 'http://localhost:8086/query?pretty=true' --data-urlencode 'db=OnlineMarketDevelopment' --data-urlencode 'q=SELECT "region", "gender", "age", "dc", "buying" FROM "SalesActivity"'
{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "SalesActivity",
                    "columns": [
                        "time",
                        "region",
                        "gender",
                        "age",
                        "dc",
                        "buying"
                    ],
                    "values": [
                        [
                            "2018-04-17T13:00:00Z",
                            ""EMEA"",
                            ""male"",
                            52,
                            ""koeln"",
                            false
                        ],
                    ]
                }
            ]
        }
    ]
}

Wie du bereits weißt, werden Zeitstempel in InfluxDB standardmäßig in RFC3339 UTC zurückgegeben und haben eine Genauigkeit im Nanosekundenbereich. Wenn du Zeitstempel im Format Unix-Epoch verwenden möchtest, dann binde zusätzlich in deine Anfrage den Parameter epoch=”x” gefolgt von –data-urlencode ein, wobei x ein Platzhalter ist, den du mit einem Element aus der Liste [h, m, s, ms, u, ns] festlegen musst. Zum Beispiel bekommst du Epoch in Sekunden, wenn dein Command so aussieht, wie im Code-Snippet unten präsentiert.


curl -GET 'http://localhost:8086/query?pretty=true' --data-urlencode 'db=OnlineMarketDevelopment' --data-urlencode 'epoch=s' --data-urlencode 'q=SELECT "region", "gender", "age", "dc", "buying" FROM "SalesActivity"'
{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "SalesActivity",
                    "columns": [
                        "time",
                        "region",
                        "gender",
                        "age",
                        "dc",
                        "buying"
                    ],
                    "values": [
                        [
                            1523962800,
                            ""EMEA"",
                            ""male"",
                            52,
                            ""koeln"",
                            false
                        ]
                    ]
                }
            ]
        }
    ]
}

Nachdem ich dir im Kontext des zu Beginn des Tutorials vorgestellten Anwendungsszenarios gezeigt habe, wie du eine Datenbank in InfluxDB erstellst und diese mit Messungen und dazugehörenden Datenpunkten befüllst, widme ich mich nun schließlich dem Teil des Anwendungsszenarios, in dem es um die visuelle Aufbereitung und dem Monitoring integrierter Datensätze geht. Hierzu werde ich Chronograf verwenden, das wiederum – neben InfluxDB – Bestandteil eines Stacks ist. Die beschriebene Fortsetzung des Anwendungsszenarios wird dir – wie bereits zu Beginn des Tutorials erwähnt – in unserem Tutorial zum Thema InfluxDB – Monitoring mit dem TICK-Stack bereitgestellt. Grafana ist ein weiteres Tool zum Plotten und Monitoring deiner Daten. Auch hierzu biete ich dir ein Tutorial an, in dem ich das eingeführte Anwendungsszenario umsetze, nämlich im Tutorial InfluxDB – Monitoring mit dem TIG-Stack.

Fazit

Du hast nun einen Einblick bekommen, wie sich Zeitreihen basierte Datenspeicherung und -auswertung mittels InfluxDB umsetzen und mit den damit in Verbindung stehenden Stack-Komponenten managen lässt. Dieses Tutorial hat dir sowohl eine solide Basis für das Verständnis über die Datenbank-Plattform InfluxDB sowie deren Installation und Einrichtung geschaffen, als auch einen Ausblick auf die Nutzung ihrer Features geboten. Du bist fähig, die gelernten Inhalte anzuwenden, im besten Fall für spannende Projekte – sei es für den Beruf, für die Schule, Lehre, Universität oder private Zwecke – auszuweiten und in die Möglichkeiten, die dir InfluxDB bietet, hineinzuwachsen. Ich wünsche dir gutes Gelingen und vor allem aber auch viel Spaß bei der Arbeit mit InfluxDB.

Aus unserer Rubrik zu Open Source Datenbanken und Datenbank-Plattformen auch noch interessant und hilfreich:

Zurück zur Tutorial Übersicht Back to Tutorial Overview

InfluxDB – Monitoring mit dem TICK-Stack

InfluxDB – Monitoring mit dem TICK-Stack

Als Fortsetzung zum Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten und des darin begonnenen Anwendungsszenarios, werde ich dir in diesem Tutorial Chronograf als eine Möglichkeit der Analyse, Aufbereitung und dem Management von in InfluxDB gespeicherten Messungen vorstellen und das erwähnte Anwendungsszenario dahingehend fortführen, dass ich die in der Datenbank namens OnlineMarketDevelopment als Teil der Messung namens SalesActivity eingebundenen Datenpunkte in Chronograf plotten lasse.
Wie bereits im oben genannten Tutorial angeschnitten, bietet das integrierte Open-Source-Projekt Chronograf eine Komponente für die Benutzeroberfläche zum Management, zur Überwachung und graphischen Aufbereitung von in InfluxDB enthaltenen Messungen. Integriert bedeutet, dass sowohl InfluxDB als auch Chronograf Komponenten eines Stacks sind, dem sogenannten TICK-Stack. Zu diesem Stack gehören noch die Bestandteile Telegraf und Kapacitor. Telegraf bildet die Schnittstelle, um Daten an InfluxDB zu sammeln und zu senden. Mit InfluxDB lassen sich Daten somit nicht lediglich wiederauffindbar aufbewahren, sondern sind via Telegraf auch jederzeit an Chronograf übertragbar. Kapacitor regelt als Komponente der Datenverarbeitung die Kommunikation/Benachrichtigung an Chronograf und den Hintergrund. Letztlich fungiert Chronograf dann auf Basis von Telegraf, InfluxDB und Kapacitor als infrastrukturelles Monitoring-Tool, zur Datenvisualisierung, sowie zum Management von Benachrichtigungen und der Datenbank.
Zunächst müssen diese vier Komponenten heruntergeladen, installiert und konfiguriert worden sein, damit du deine Infrastruktur nutzen kannst. Da wir zusammen InfluxDB bereits im Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten erfolgreich installiert und konfiguriert haben, widme ich mich nun den übrigen drei Bestandteilen des Stacks.

Kapacitor installieren und einrichten

Zunächst downloaden und installieren wir Kapacitor unter Ubuntu 16.04 mit den beiden unten stehenden Kommandos im Terminal.

> wget https://dl.influxdata.com/kapacitor/releases/kapacitor_1.4.0_amd64.deb

> dpkg -i kapacitor_1.4.0_amd64.deb

Um Kapacitor einmalig zu starten, ist noch der unten eingeblendete Command notwendig.

> systemctl start kapacitor

Du kannst sicherstellen, ob Kapacitor funktioniert indem du das Kommando nutzt, dass ich dir im unten eingeblendeten Code-Snippet zeige. Wenn deine Anfrage erfolgreich ausfällt, dann lautet das Output folglich so, wie du unten im Code-Block erkennen kannst.

> kapacitor list tasks
ID Type      Status    Executing Databases and Retention Policies

Andernfalls erhältst du folgendes Output.

> kapacitor list tasks
Get http://localhost:9092/kapacitor/v1/tasks?dot-view=attributes&fields=type&fields=status&fields=executing&fields=dbrps&limit=100&offset=0&pattern=&replay-id=&script-format=formatted: dial tcp [::1]:9092: getsockopt: connection refused

Telegraf installieren und einrichten

Nun downloadest und installierst du Telegraf, indem du die beiden unten stehenden Kommandos jeweils im Terminal veranlasst.

> wget https://dl.influxdata.com/telegraf/releases/telegraf_1.4.3-1_amd64.deb

> dpkg -i telegraf_1.4.3-1_amd64.deb

Wie im Fall von Kapacitor, musst du auch Telegraf mittels dem unten stehenden Kommando starten, wobei die Konfigurationsdatei telegraf.conf generiert werden sollte, die dann wiederum im Verzeichnis /etc/telegraf liegen würde.

> systemctl start telegraf

Um auch die Funktionalität von Telegraf zu gewährleisten, solltest du an zwei Stellen in der Konfigurationsdatei die Einträge prüfen. In meinem Beispiel werde ich das mit dem nano-Editor tun, und zwar indem ich die besagte Datei mit dem unten verdeutlichten Kommando öffne.

> nano /etc/telegraf/telegraf.conf

Die beiden unten eingeblendeten Code-Blöcke zeigen dir jeweils die Stellen, deren Inhalte du in der Konfigurationsdatei abgleichen solltest. Der erste Code-Block betrifft die Output-Sektion und der zweite die Input-Sektion.

[[outputs.influxdb]]
  ## The full HTTP or UDP endpoint URL for your InfluxDB instance.
  ## Multiple urls can be specified as part of the same cluster,
  ## this means that only ONE of the urls will be written to each interval.
  # urls = ["udp://localhost:8089"] # UDP endpoint example
  urls = ["http://localhost:8086"] # required
  ## The target database for metrics (telegraf will create it if not exists).
  database = "telegraf" # required

  ## Retention policy to write to. Empty string writes to the default rp.
  retention_policy = ""
  ## Write consistency (clusters only), can be: "any", "one", "quorum", "all"
  write_consistency = "any"

  ## Write timeout (for the InfluxDB client), formatted as a string.
  ## If not provided, will default to 5s. 0s means no timeout (not recommended).
  timeout = "5s"
  # username = "telegraf"
  # password = "metricsmetricsmetricsmetrics"
  ## Set the user agent for HTTP POSTs (can be useful for log differentiation)
  # user_agent = "telegraf"
  ## Set UDP payload size, defaults to InfluxDB UDP Client default (512 bytes)
  # udp_payload = 512
# Read metrics about cpu usage
[[inputs.cpu]]
  ## Whether to report per-cpu stats or not
  percpu = true
  ## Whether to report total system cpu stats or not
  totalcpu = true
  ## If true, collect raw CPU time metrics.
  collect_cpu_time = false


# Read metrics about disk usage by mount point
[[inputs.disk]]
  ## By default, telegraf gather stats for all mountpoints.
  ## Setting mountpoints will restrict the stats to the specified mountpoints.
  # mount_points = ["/"]

  ## Ignore some mountpoints by filesystem type. For example (dev)tmpfs (usually
  ## present on /run, /var/run, /dev/shm or /dev).
  ignore_fs = ["tmpfs", "devtmpfs"]


# Read metrics about disk IO by device
[[inputs.diskio]]
  ## By default, telegraf will gather stats for all devices including
  ## disk partitions.
  ## Setting devices will restrict the stats to the specified devices.
  # devices = ["sda", "sdb"]
  ## Uncomment the following line if you need disk serial numbers.
  # skip_serial_number = false


# Get kernel statistics from /proc/stat
[[inputs.kernel]]
  # no configuration


# Read metrics about memory usage
[[inputs.mem]]
  # no configuration


# Get the number of processes and group them by status
[[inputs.processes]]
  # no configuration


# Read metrics about swap memory usage
[[inputs.swap]]
  # no configuration


# Read metrics about system load & uptime
[[inputs.system]]
  # no configuration

Letztlich solltest du dann noch einen Test durchführen, um sicherzustellen, dass die Systemstatistiken an InfluxDb kommuniziert wurden. Dies prüfst du, indem du das folgende Kommando im Terminal ausführst. Daraufhin solltest du ein umfangreiches JSON-Output sehen, wenn alles korrekt ist. Ansonsten wäre das Output leer.

> curl "http://localhost:8086/query?q=select+*+from+telegraf..cpu"

Chronograf installieren und einrichten

Schließlich downloadest und installierst du Chronograf, indem du im Terminal die beiden unten gezeigten Kommandos ausführst.

> wget https://dl.influxdata.com/chronograf/releases/chronograf_1.4.0.0_amd64.deb

> dpkg -i chronograf_1.4.0.0_amd64.deb

Anschließend musst du Chronograf einmalig via dem folgenden Command einmalig starten.

> systemctl start chronograf

Als nächstes solltest du nun Chronograf im Browser aufrufen können, indem du http://localhost:8888 nutzt, wobei du localhost mit der IP-Adresse deines Servers austauscht. Wie dir der Screenshot unten verbildlicht, gelangst du daraufhin auf die Willkommensseite von Chronograf. Hier hast du die Möglichkeit Chronograf mit deiner InfluxDB Instanz in Verbindung zu setzen. Stelle zunächst sicher, dass der Connection String den Port 8086 antriggert und auch hier localhost durch die IP-Adresse deines Servers ersetzt wird. Für den Namen des Connection String kannst du eine Bezeichnung wählen, die du für sinnvoll hältst. Per default ist der Datenbankname von Telegraf “telegraf”. Nachdem du einen Nutzernamen eingetragen und ein Passwort festgelegt hast, bestätigst du dies mit Klick auf den Button Add Source.

Chronograf einrichten

Danach wirst du dann auf die Plattform von Chronograf weitergeleitet. Wenn du den zweiten Punkt in der zur linken Seite eingeblendeten Navigationsleiste anklickst, gelangst du auf die Host List-Seite, wie im folgenden Screenshot präsentiert.

Host Liste in Chronograf

Hier kannst du mit Klick auf den betreffenden Hostnamen die Seite aufrufen, auf der grafisch aufbereitete Informationen über den Grad und Verlauf deiner CPU-Nutzung und andere Systemprozesse bereitgestellt werden, wie dir der Screenshot unten zeigt.

CPU-Auslastung in Chronograf

Final musst du noch Chronograf mit Kapacitor in Verbindung setzen. Dies ist möglich über den Punkt Konfiguration. Um dies umzusetzen, klickst du den letzten Punkt in der zur linken Seite eingeblendeten Navigationsleiste. Hiernach bist du auf der Konfigurationsseite, auf der du erkennst, dass Chronograf bereits mit InfluxDB in Relation gesetzt ist. Dies wird dir über den grün gekennzeichneten Button Connected signalisiert. Durch Klick auf den Connected-Button kannst du jederzeit zwischen dem Status „verbunden“ oder „nicht verbunden“ switchen. Wenn du nicht verbunden bist, dann ist der betreffende Button grau gekennzeichnet. Diese Optionalität bietet sich vor allem an, wenn du mehr als eine Quelle in der Liste hast und die Verbindung von einer Quelle lösen möchtest, um eine andere Quelle zu nutzen.

Konfiguration in Chronograf hinzufügen

Des Weiteren entnimmst du dem Screenshot oben den oben rechts auf der Seite platzierten + Add Config-Button. Über Betätigung dieses Buttons wirst du zu einem Web-Interface weitergeleitet, in dem du zunächst die Details deiner neuen Verbindung eintragen kannst. Dem Screenshot unten entnimmst du, dass der angetriggerte Port für die Verbindung mit Kapacitor der Port 9092 sein sollte.

Kapacitor Konfiguration in Chronograf einrichten

Nachdem du der Verbindung einen dir als sinnvoll erscheinenden Namen gegeben hast, die dir bereits bekannten Informationen zu Nutzername und Passwort eingetragen hast und dies mit Betätigung des Buttons Connect bestätigt hast, erscheint zur rechten Seite ein weiteres Interface-Frame, in dem du Informationen zu den Benachrichtigungs-Endpunkten setzen kannst. Der Screenshot unten reflektiert, dass du dich auf der linken Seite dieses neuen Interface-Frames durch die Liste aller möglichen Event-Handler navigieren kannst. Den Endpunkt zu konfigurieren ist letztlich optional und es steht dir frei dies zu tun oder nicht. Wenn du den Endpunkt konfiguriert hast, kann Chronograf Benachrichtigungen an einen von dir gewählten Event-Handler senden und dich up to date halten. Besonders hilfreich kann die Nutzung dieses Dienstes sein, um Warnmeldungen an bestimmte URLs sowie an Anwendungen wie Slack oder HipChat zu senden. Voraussetzung ist, dass du selbst bei solch einer Anwendung registriert bist. Wie du beim Vergleichen der beiden unten präsentierten Screenshots erkennst, können für unterschiedliche Event-Handler (Alerta im 1. Screenshot und Slack im 2. Screenshot) unterschiedliche und spezifische Daten erforderlich sein, um die Verbindung herzustellen. Bestimmte erforderliche Daten sind von der betreffenden Anwendung einzuholen, z.B. wenn es sich um einen Token, eine URL oder eine Umgebung handelt.

Alerta als Endpunkt in Chronograf konfigurieren

Slack als Endpunkt in Chronograf konfigurieren

InfluxDB mit Chronograf nutzen

Nun kommen wir zu dem Teil, in dem ich das im Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten geschilderte Anwendungsszenario durchführe, um mir die Datenpunkte visuell aufbereitet in Chronograf plotten zu lassen. Hierzu starte ich die influx-Befehlszeilenschnittstelle (CLI) über den Command, den du im Code-Block unten siehst. Ich möchte hierbei, dass die Datenpunkte, die ich gleich in die Datenbank OnlineMarketDevelopment zur Messung SalesActivity hinzufüge, den Zeitstempel im Format Unix-Epoch in Sekunden haben.

> influx -precision s
Connected to http://localhost:8086 version 1.5.x
InfluxDB shell version: 1.5.x

Als nächstes wechsle ich in die zuvor angelegte Datenbank OnlineMarketDevelopment. über das folgende Kommando. Solltest du diese Datenbank noch nicht angelegt haben, dann tue dies, bevor du das unten stehende Kommando im Terminal eingibst.

> USE OnlineMarketDevelopment
Using database OnlineMarketDevelopment

Daraufhin werde ich alle INSERT-Operationen für die Messung SalesActivity durchführen, die du der rechten Spalte in der unten stehenden Tabelle entnimmst. Wie bereits im Anwendungsszenario vermerkt, beziehen sich die indexierten Datenpunkte auf einen Zeitraum von 15 Minuten, genau genommen auf den Zeitraum von 13:00 bis 13:15 am 17.04.2018. Zur Übersichtlichkeit für dich habe ich in der linken Spalte jeweils den dazugehörigen Zeitstempel dokumentiert.

Datum: 17.04.2018
Uhrzeit via INSERT-Operation im Epoch-Format indexierte(r) Datenpunkt(e)
13:00 INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=52i,buying=FALSE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“dortmund“,gender=“male“ age=25i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“female“ age=19i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=33i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“female“ age=22i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=30i,buying=FALSE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=39i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=18i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=21i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“female“ age=45i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“borken“,gender=“female“ age=23i,buying=TRUE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=50i,buying=FALSE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“niederkassel“,gender=“female“ age=28i,buying=FALSE 1523962800

 

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“male“ age=37i,buying=TRUE 1523962800

13:02 INSERT SalesActivity,region=“EMEA“,dc=“oberhausen“,gender=“female“ age=31i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=27i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=53i,buying=FALSE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“male“ age=25i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=28i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“duesseldorf“,gender=“male“ age=26i,buying=TRUE 1523962920

13:03 INSERT SalesActivity,region=“EMEA“,dc=“duesseldorf“,gender=“female“ age=42i,buying=FALSE 1523962980

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“female“ age=26i,buying=FALSE 1523962980

INSERT SalesActivity,region=“EMEA“,dc=“bottrop“,gender=“male“ age=53i,buying=FALSE 1523962980

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=21i,buying=FALSE 1523962980

13:07 INSERT SalesActivity,region=“EMEA“,dc=“dormagen“,gender=“male“ age=18i,buying=TRUE 1523963220

INSERT SalesActivity,region=“EMEA“,dc=“bocholt“,gender=“male“ age=24i,buying=TRUE 1523963220

13:08 INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=40i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=56i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“frechen“,gender=“female“ age=47i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“male“ age=39i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“female“ age=51i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“bonn“,gender=“female“ age=31i,buying=TRUE 1523963280

13:11 INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=20i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“koenigswinter“,gender=“female“ age=25i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“dortmund“,gender=“male“ age=33i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=30i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“male“ age=29i,buying=TRUE 1523963460

13:13 INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“female“ age=28i,buying=TRUE 1523963580

INSERT SalesActivity,region=“EMEA“,dc=“bornheim“,gender=“female“ age=21i,buying=TRUE 152396358

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=35i,buying=TRUE 1523963580

13:14 INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=60i,buying=FALSE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“bonn“,gender=“male“ age=53i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“female“ age=57i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“female“ age=44i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“female“ age=48i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=41i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“male“ age=48i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“female“ age=55i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“female“ age=18i,buying=TRUE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=27i,buying=TRUE 1523963640

13:15 INSERT SalesActivity,region=“EMEA“,dc=“dinslaken“,gender=“female“ age=26i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=23i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“female“ age=19i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“bad_honnef“,gender=“female“ age=51i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“bonn“,gender=“male“ age=19i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“oberhausen“,gender=“male“ age=34i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“female“ age=38i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=21i,buying=TRUE 152396370

INSERT SalesActivity,region=“EMEA“,dc=“niederkasse“l,gender=“male“ age=28i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“male“ age=32i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=36i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“oberhausen“,gender=“male“ age=46i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“female“ age=31i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“duesseldorf“,gender=“male“ age=25i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“male“ age=21i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“bochum“,gender=“male“ age=27i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“female“ age=33i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=40i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“male“ age=18i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“schwerte“,gender=“male“ age=68i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“female“ age=39i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“dormagen“,gender=“male“ age=20i,buying=FALSE 1523963700

Mit Chronograf ist es möglich, vordefinierte Dashboards zu nutzen oder benutzerdefinierte Dashboards zu erstellen, um in InfluxDB gespeicherte Messungen visualisieren zu lassen und die Infrastruktur zu überwachen.
Neben dem Dashboard gibt es den Data Explorer, den du – wie im Screenshot unten zu erkennen – im dritten Punkt in der zur linken Seite eingeblendeten Navigationsleiste findest. Hier ist es dir möglich, Ergebnismengen bestimmter Messungen via SELECT-Statement ausgeben zu lassen oder neue Datenpunkte in bestimmte Messungen einer Datenbank zu integrieren, upzudaten oder zu löschen.
Ein SELECT-Statement wiederum kannst du dir entweder automatisch generieren lassen und es dann bei Bedarf weiter verfeinern oder direkt selbst erstellen. Dieses wird im hierfür vorgesehenen Editor-Feld eingebunden, dass du im Data Explorer oben findest.
Wenn du für die Generierung deiner Query den Builder, bzw. den Abfrage-Generator verwenden möchtest, klickst du aus der unterhalb des Query-Editor-Feldes verfügbaren Liste von Datenbanken die betreffende Datenbank an. In meinem Beispiel wäre das die Datenbank OnlineMarketDevelopment. Der Screenshot unten zeigt, dass das Menü dann nach rechts erweitert wird, wobei du die betreffende Messung auswählen und anhand der unter der Messung gelisteten Tags das GROUP BY-Statement über Auswahl definieren kannst. Letztlich kannst du dann ganz rechts über die Check-Box(en) das/die Feld(er) auswählen, das/die die zur Messung gehörenden Werte beinhaltet.
Nachdem das SELECT-Statement generiert wurde, wird dir über die Meldung unten im Query-Editor-Feld signalisiert, ob sie erfolgreich ausfiel oder nicht. Ist sie das nicht, dann ähnelt die Meldung farblich einer Warnung. Fällt sie positiv aus, dann erscheint sie in grüner Farbe und ganz unten im Tab Graph wird automatisch der zur Query gehörende Graph geplottet.
Chronograf verwendet per default die Funktion MEAN() im SELECT-Statement und die Datenpunkte werden in automatisch generierte Zeitintervalle (:Intervall) gruppiert angezeigt. Es werden per default die Datenpunkte ermittelt, die im Zeitraum der letzten Stunde erhoben wurden (WHERE time > :dashboardTime: oder WHERE time > now() – 1h). Diese Standardfunktionen und -parameter können mithilfe der im Menü des Abfrage-Generators bereitgestellten Buttons oder durch manuelle Bearbeitung der Abfrage konfiguriert werden. So lässt sich z.B. über den auf der rechten Seite im Menü platzierten blauen Function-Button die Funktion MEAN() in die Funktion COUNT() ändern, wenn du eher eine Zählung zusammengehörender Datenpunkte anstrebst. Im Screenshot unten kannst du dies gut nachvollziehen. Hier habe ich den Klick auf den Function-Button simuliert, um zu zeigen, dass darunter dann eine Auswahl an nutzbaren Funktionen eingeblendet wird. Hier habe ich dann die COUNT-Funktion ausgewählt. Mit Klick auf den Apply-Button würde die MEAN-Funktion automatisch durch die COUNT-Funktion ersetzt werden.

Query im Data-Explorer von Chronograf automatisiert generieren lassen

Schließlich habe ich mich dazu entschieden die Query selber zu schreiben. Hierzu habe ich das SELECT-Statement, das du im Code-Snippet unten siehst, in das Editor-Feld implementiert.

SELECT COUNT("buying") AS "count_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "time" <= '2018-04-17T13:00:00Z' AND "time" <= '2018-04-17T13:15:00Z' GROUP BY time(1m)

Die aktuelle Treffermenge wird dir – wie oben bereits erwähnt – bei erfolgreich ausfallender Query sofort im Fenster unten über den Tab Graph visuell – also geplottet – wiedergeben. Dies wird dir im Screenshot unten präsentiert. Dort erkennst du, dass neben dem Tab Graph noch die beiden Tabs Table und .csv existieren. Im Tab Table kannst du dir die Ergebnisse in der Tabellenansicht anzeigen lassen oder sie dir über den Tab .csv als weiter verarbeitbare CSV-Datei herunterladen.

Query im Data Explorer von Chronograf - 1 min. Intervall

Ich kann das oben erstellte SELECT-Statement anpassen, was ich in zum Vorzeigen auch gemacht habe, indem ich formuliert habe GROUP BY time(5m). Dies entnimmst du dem unten eingeblendeten Code-Block. Auch könnte ich den Zeitrahmen der Datenerhebung erweitern, wenn ich z.B. Datenpunkte indexiert hätte, die am 17.04.2018 über das Zeitfenster von 13:00 bis 13:15 hinausgingen. Analog könnte ich mir auch weniger Datenpunkte ausgeben lassen, als indexiert worden sind. So könnte ich mir z.B. lediglich die Ergebnisse zum Zeitrahmen von 13:00 bis 13:10 ausgeben, bzw. plotten lassen. Da ich vor 13:00 Uhr für die Messung SalesActivity keine Datenpunkte indexiert habe, genügt es, wenn ich in der Query die WHERE-Bedingung formulieren würde als WHERE time <= ‚2018-04-17T13:10:00Z‘. Du kannst die Query nach Bedarf um Bedingungen erweitern und modellieren.

SELECT COUNT("buying") AS "count_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "time" <= '2018-04-17T13:00:00Z' AND "time" <= '2018-04-17T13:15:00Z' GROUP BY time(5m)

Der Screenshot unten verdeutlicht dir, wie sich das SELECT-Statement im oben befindlichen Code-Block – also das Umformulieren von GROUP BY time(1m) in GROUP BY time(5m) – auf das Plotten der Ergebnisse auswirkt.

Query im Data Explorer von Chronograf - 5 min. Intervall

Um schließlich ein Dashboard zu erstellen, wählst du – wie dir der Screenshot unten verbildlicht – den 4. Navigationspunkt in Chronograf und klickst den Button + Create Dashboard.

Leere Dashboard-Seite in Chronograf

Daraufhin wirst du zum Hauptfenster des neu erstellten Dashboards weitergeleitet. Jedes Dashboard-Item im Dashboard basiert auf einer Query, bzw. der Ergebnismenge, die aus einem SELECT-Statement hervorgeht.

Dashboard Item zu Dashboard in Chronograf adden

In der oberen Hälfte des Screenshots befindet sich das neu erstellte Dashboard-Item. Es ist noch leer und enthält lediglich den Titel links oben eingeblendet, den du jederzeit mittels Doppelklick nach Bedarf editieren kannst. Über Betätigung des Buttons + Add a Query, würde dir ein Editor zur Eingabe einer Query eingeblendet werden. In der zweiten Hälfte des Screenshots oben erkennst du zwei Tabs, nämlich den Tab Queries und den Tab Visualization. Der Editor zur Definition der Query würde im Tab Queries auffindbar sein. Du befindest dich dann sozusagen im Query-Editor-Modus. Wenn du den Tab Visualization betätigst, hast du die Möglichkeit, den Diagrammtyp für die Visualisierung deiner Messung auszuwählen und/oder jederzeit nach Bedarf zu ändern. Dir wird eine Reihe von Diagrammtypen zur Wahl angeboten, was dir der Screenshot unten verbildlicht.

Visualisierungstyp für Dashboard-Item in Chronograf waehlen

Im Queries-Modus wird dir – wie beim Data Explorer – ein Query-Editor-Feld zur Verfügung gestellt. Auch hier kannst du dir die Query automatisch generieren lassen oder diese selber schreiben. Die Query, mit der ich das Dashboard-Item fülle, entspricht der ersten Query, die ich im Data Explorer erstellt habe.
Sobald deine Query erfolgreich ausfällt, erkennst du – wie dir der Screenshot unten verdeutlicht – im Preview-Fenster des Dashboard-Items oben die dazugehörende Visualisierung. Dir fällt darin auch auf, dass ich dem Dashboard-Item zusätzlich noch den Namen Sum of recognized activity (buying & no buying) gegeben habe. Dies habe ich getan, indem ich den Untitled Cell-Platzhalter oben links im Preview-Fenster des Dashboard-Items via Klick darauf angetriggert und ihn dann editiert habe.

Dashbord-Item in Chronograf via Query mit Daten füllen

Nun fixiere ich meine Ergebnisse, indem ich sie durch Klick auf den grünen Button bestätige, in dem ein Häkchen zu sehen ist. Dies führt dann dazu, dass mein erstelltes und editiertes Dashboard-Item im Dashboard fixiert hinterlegt ist, was dir der Screenshot unten nahe bringt. Oben rechts in der Leiste des im Dashboard fixierten Dashboard-Items erkennst du kleine Werkzeug-Items, mit denen du das Dashboard-Item entweder updaten, bzw. weiter editieren kannst, oder herunterladen oder gar löschen kannst.

Dashboard ohne Titel in Chronograf

Es ist nicht nur möglich Dashboard-Items eine Bezeichnung zu geben, sondern auch dem Dashboard selbst. Ich benenne das Dashboard Customer activity in Online-Shop, indem ich oben links den Platzhalter Name This Dashboard anklicke und meine favorisierte Bezeichnung dort in das Feld rein schreibe. Das Ergebnis bemerkst du im Screenshot unten. Über den blauen + Add Cell-Button rechts neben der Dashboard-Headline ist es dir möglich weitere Dashboard-Items zu erstellen.

Dashboard mit Titel in Chronograf

Wenn du schließlich erneut den 4. Navigationspunkt in Chronograf klickst, erscheint auf der Dashboard-Seite die Gesamtübersicht aller existierenden Dashboards in Form einer Listung, wie im Screenshot unten präsentiert. Via Klick auf den verlinkten Namen eines Dashboards, gelangst du wieder zurück auf die Hauptseite des betreffenden Dashboards, in dem sich alle hierzu gehörenden Dashboard-Items befinden. Sobald du die Zeile, in der der Name des Dashboards steht, mit dem Mauszeiger anvisierst, erscheint ganz links ein roter Delete-Button, der dir ermöglicht, das komplette Dashboard jederzeit zu löschen. Via Klick auf den Button + Create Dashboard ist es dir möglich, ein neues Dashboard zu erstellen. Es können beliebig viele Dashboards nebenher existieren.

Gesamtuebersicht der Dashboards in Chronograf

Ich möchte nun aber zunächst zu meinem bestehenden Dashboard mit der Bezeichnung Customer activity in Online-Shop fünf weitere Dashboard-Items anlegen, um mehr Kontrolle über und Vergleichbarkeit der erhobenen Daten auf einen Blick verfügbar zu haben. Hierzu navigiere ich mich zurück in das Dashboard Customer activity in Online-Shop, indem ich dessen Namen in der Dashboard-Liste anklicke. Die fünf unten aufgeführten Code-Snippets geben dir Aufschluss, mit welcher Query ich das jeweilige Dashboard Item in Chronograf erzeugen werde, wobei ich über jedem der fünf Code-Blöcke einen Hinweis auf die von mir in Chronograf gewählte Bezeichnung des Dashboard-Items voranführe.

SELECT-Statement zur Erstellung des Dashboard-Items Sum of recognized activity (buying):

SELECT COUNT("buying") AS "count_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "time" <= '2018-04-17T13:15:00Z' AND "buying"=TRUE GROUP BY time(1m)

SELECT-Statement zur Erstellung des Dashboard-Items Sum of recognized activity (buying) | age <= 35:

SELECT COUNT("buying") AS "count_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "time" <= '2018-04-17T13:15:00Z' AND "buying"=TRUE AND "age" <= 35 GROUP BY time(1m)

SELECT-Statement zur Erstellung des Dashboard-Items Sum of recognized activity (no buying) | age <= 35:

SELECT COUNT("buying") AS "count_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "time" <= '2018-04-17T13:15:00Z' AND "buying"=FALSE AND "age" <= 35 GROUP BY time(1m)

SELECT-Statement zur Erstellung des Dashboard-Items Sum of recognized activity (buying) | age > 35:

SELECT COUNT("buying") AS "count_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "time" <= '2018-04-17T13:15:00Z' AND "buying"=TRUE AND "age" > 35 GROUP BY time(1m)

SELECT-Statement zur Erstellung des Dashboard-Items Sum of recognized activity (no buying) | age > 35:

SELECT COUNT("buying") AS "count_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "time" <= '2018-04-17T13:15:00Z' AND "buying"=TRUE AND "age" > 35 GROUP BY time(1m)

Dem Screenshot unten entnimmst du schließlich, wie das Dashboard Customer activity in Online-Shop nach der Implementierung der fünf weiteren Dashboard-Items aussieht. Je nach Umfang deiner Zeitreihen-Erhebung und deinem Belieben, kannst du den geplotteten Zeitraum im jeweiligen Dashboard-Item jederzeit in der dazugehörigen Query anpassen. Sobald du mit dem Mauszeiger die oben in einem Dashboard-Item befindliche Leiste anvisierst, in der auch die Werkzeug-Icons und die Headline zu finden sind, ist es dir zudem möglich, das betreffende Item via Drag & Drop im Dashboard umzuplatzieren.

Dashboard in Chronograf mit mehreren Dashboard-Items

FAZIT

Dieses Tutorial hat dir – direkt anknüpfend an das Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten – Verständnis über InfluxDB im Kontext einer managebaren Benutzeroberfläche gegeben. Du hast die zu InfluxDB gehörenden Stack-Komponenten kennengelernt und weißt nun, wie du diese auf deinem Ubuntu-Server installieren, einrichten und nutzen kannst. Ich wünsche dir viel Freude bei der Umsetzung der gelernten Inhalte.

Zurück zur Tutorial Übersicht Back to Tutorial Overview

PostgreSQL 10 Master/Slave-Replikation

Header Master/Slave-Replikation auf PostgreSQL

In diesem Tutorial zeige ich dir, wie du mit dem Datenbankmanagementsystem PostgreSQL 10.4 eine asynchrone Replikation einrichtest. PostgreSQL ist ein Open-Source Datenbank-Server mit mehr als 15 Jahre aktiver Entwicklungszeit. Es ist eine leistungsstarke Datenbank mit großem Funktionsumfang, der auch große Loads keine Probleme bereiten. Einige der neuen Features, die du bei PostgreSQL 10 findest, sind:

  • Logische Replikation
  • Quorum Commit für synchrone Replikation
  • SCRAM-SHA-256 authentication
  • Volltext Suche für JSON and JSONB & mehr

Ziel der Replikation ist es, die Verfügbarkeit und Datensicherheit deiner Datenbank zu erhöhen. Die Einrichtung werden wir auf Ubuntu 16.04 Hosts und innerhalb von einem privaten Netzwerk durchführen. Bei Datenbanken ist es generell Best Practice, diese innerhalb von privaten Netzwerken zu betreiben und nicht direkt über das Internet zugänglich zu machen. Bedenke bitte auch, dass es sich hier um eine asynchrone Replikation handelt. Unter einigen Umständen kann es bei der asynchronen Replikation zu Datenverlust kommen. In der Regel wird die asynchrone Replikation genutzt, um einen extra Layer an Sicherheit für die Daten hinzuzufügen. Wer seine Daten um jeden Preis schützen muss, der sollte auf eine synchrone Konfiguration zurückgreifen. Bei der synchronen Replikation muss die Transaktion auf mindestens zwei Servern durchgeführt worden sein, bevor der Master dem Client einen success meldet.

In deinem Tech4Hosting Panel kannst du das Server-Setup auch ohne große Erfahrung in kurzer Zeit mit unseren Templates nachbauen. Teste Tech4Hosting einfach mal aus und überzeuge dich von den Features und der Einfachheit des Tech4Hosting Panels.


 

Vorbereitungen

Für das folgende Tutorial benötigst du 2 Ubuntu 16.04 Server.

Master IP: 1.0.0.1 – read/write
Slave IP: 1.0.0.2 – read only

Wenn du dem Tutorial bei Tech4Hosting folgst, dann erstelle zunächst die beiden Server mit Ubuntu Template. Zur Installation von Postgres kannst du beiden Servern erst einmal eine öffentliche IP vergeben und die Server danach in ein privates Netzwerk verlegen.

Mehr zur Installation von Postgres 10 auf Ubuntu gibts hier:

PostgreSQL 10 auf Ubuntu 16.04 / 14.04 installieren

Neu! – Autoscale MySQL-as-a-Service von Tech4Hosting

Alle, die sich nicht mehr mit Datenbank-Administration auseinandersetzen wollen, können jetzt auch die neuen Platform Services von Tech4Hosting nutzen.

Der Vorteil der Platform Services bei Tech4Hosting: Wir kümmern uns um die sichere Konfiguration, den zuverlässigen Betrieb und die Installation von Sicherheitsupdates deiner PaaS-Dienste. In deinem Tech4Hosting Panel kannst du ab sofort mit den Datenbanken PostgreSQL, MySQL und redis starten.
Probiere es einfach mal aus!

Mehr Infos zu PaaS bei Tech4Hosting und wie PaaS funktioniert gibt es in unserem
Getting started mit PaaS bei Tech4Hosting
Platform Services von Tech4Hosting.

Postgres Master Konfiguration

Nach der Installation von Postgres wechselst du in den default Postgres Superuser-Account und loggst dich mit diesem im PostgreSQL-Terminal an.

Hier erstellst du eine neue Role für die Replikation.

CREATE ROLE pgrep WITH REPLICATION LOGIN ;

Dann setzt du die Passwort Verschlüsselung auf scram-sha-256.

postgres=# set password_encryption = 'scram-sha-256 ;

Und noch das Passwort für die Role setzen.

password pgrep

Postgres Replication Log

postgresql.conf anpassen

Stoppe zunächst den PostgreSQL Service mit:

systemctl stop postgresql

In der postgresql.conf Datei passt du den Postgres Master Server für die Replikation an. Wähle einen Editor deiner Wahl zum edieren (vim, nano etc.). Die Datei liegt unter /etc/postgresql/10/main.

Die nachfolgenden Zeilen müssen innerhalb der Datei auskommentiert und mit den entsprechenden Werten versehen werden.

Stelle sicher, das der PostgreSQL Server auf deinem Interface lauscht, durch eintragen der internen IP des Master Hosts.

listen_addresses = '10.0.0.1'

Danach müssen die Write-Ahead Log Einstellungen angepasst werden.

wal_level = replica
archive_mode = on
archive_command = 'rsync -a %p [email protected]:/var/lib/postgresql/10/main/archive/%f'

Die archive_command Variable ist dafür da den XLOG von der Datenbankinstanz an einem bestimmten Ort zu archivieren. Der Vorteil hier ist, du kannst dein beliebiges Shell-Skript verwenden. Optionen sind z.B. die Daten an einen FTP-Server zu schicken, an einen Cloud-Storage-Provider oder einfach auf einen anderen Server. Eine beliebte Methode ist rsync zu verwenden (wie im Beispiel oben).

Hinweis: Damit die rsync Methode im obigen Beispiel funktioniert, musst du noch die IP des Standby-Host und SSH-Access für rsync anpassen.

Dann geht es weiter mit den Einstellungen für die Replikation.

max_wal_senders = 3
wal_keep_segments = 64

Bei wal_keep_segments setzt du die minimale Nummer an Log Segmenten, die auf dem Master gespeichert werden sollen. Beachte, dass ein Segment 16mb groß ist und du im Fall der Fälle genug extra Speicher auf dem Master Host bereit hältst.

Anschließend speicherst du die Datei ab.

Weil der Archiv Mode aktiviert wurde, muss jetzt noch ein neues Verzeichnis für die Archivierung im PGDATA Verzeichnis angelegt werden. Mit den folgenden Befehlen erstellst du das Verzeichnis, vergibst die notwendige Berechtigung und änderst den Owner zu User postgres.

mkdir -p /var/lib/postgresql/10/main/archive/
chmod 700 /var/lib/postgresql/10/main/archive/
chown -R postgres:postgres /var/lib/postgresql/10/main/archive/

 

pg_hba.conf anpassen

Nachfolgend wird noch die PostgreSQL Client Authentication angepasst, die Datei liegt unter /etc/postgresql/10/main/pg_hba.conf.

# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
#local   all             all                                     peer
# IPv4 local connections:
host    all             all             0.0.0.0/0               md5     
# IPv6 local connections:
host    all             all             ::0/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
hostssl   replication     pgrep         10.0.0.2/32             scram-sha-256

In der untersten Zeile wurde die Role, IP-Adresse für den Slave Host und die Authentifizierungsmethode definiert. Danach speicherst du ab und verlässt die Datei.

Postgres Slave Konfiguration

Nachdem der Master fertig konfiguriert wurde, wechselst du auf deinen Slave Host.

Stoppe zunächst den PostgreSQL Service.

systemctl stop postgresql

Optional kannst du jetzt auf deinem Slave dieselben Einstellungen an postgresql.conf und pg_hba.conf vornehmen wie auf dem Master (so kann dein Slave auch als Master agieren, falls Failover eingerichtet wurde).

Ändere dann folgende Zeile in der postgresql.conf wie folgt ab:

hot_standby = on

und speicher das ganze.

Jetzt wechselst du in dein PGDATA Verzeichnis.

cd /var/lib/postgresql/10/

Anschließend benennst du das vorhandene main/ Verzeichnis auf dem Slave um.

mv main/ main-backup
chmod 700 main/

Im nächsten Schritt kopierst du dann das main Verzeichnis vom Master auf deinen Slave via pg_basebackup Befehl. Nach der Eingabe wirst du nach deinem Passwort für den User pgrep gefragt.

pg_basebackup -h 10.0.0.1 -D /var/lib/postgresql/10/main/ -P -U pgrep --wal-method=stream

Wechsle in dein neues main/ Verzeichnis

 cd main/

und erstelle eine neue Datei mit dem Namen recovery.conf.

vim recovery.conf

Kopiere nun folgende Konfiguration in die Datei:


standby_mode          = 'on'
primary_conninfo      = 'host=10.0.0.1 port=5432 user=pgrep password=[dein-passwort]'
trigger_file = '/tmp/MasterNow'
#restore_command = '[dein-restore-kommando]'

In der ersten Zeile wird definiert, dass der Slave im standby Modus startet. Unter “primary_conninfo” werden die Parameter für die Verbindung zum Master festgelegt. Und die Zeile “trigger_file” spezifiziert, dass der Slave als Master einspringt, wenn ein Trigger-File existiert (für dieses Failover-Feature brauchst du zusätzliche Software wie z.B. repmgr).

Replikation testen

Nach Anpassen der Konfiguration von Master und Slave müssen die Systeme neu gestartet werden.
Führe also eine reboot auf Master und Slave durch.

reboot now

Zu guter Letzt kannst du den PostgreSQL Service auf Master und Slave starten.

Postgres Replication - Log File

Ein Blick in die log Datei verrät dir, ob alles so geklappt hat, wie es soll.

Und auf dem Master Server kannst du dir mit folgendem Befehl (im psql-Terminal) deinen pgrep User anschauen:

select * from pg_stat_activity where username = ‘pgrep’ ;

Postgres active Replication User

Fazit

In diesem Tutorial hast du gelernt, wie man mit Postgres eine Datenbank Replikation einrichtet. Postgres ist ein mächtiges Datenbanksystem, mit dem du wegen seiner umfangreichen Funktionalitäten lange Freude haben wirst. Das Studieren der Postgres Dokumentation ist daher unumgänglich. Auf dem Gebiet der Datenbank Replikation zählen vor allem auch Erfahrungswerte, deswegen heißt es einfach dranbleiben bis zum Replication Pro!

Bei mehr Lust auf Datenbank Themen, einfach mal in folgende Tutorials schauen ?

MongoDB auf Ubuntu installieren

Apache Cassandra auf Ubuntu installieren

InfluxDB 1.5 unter Ubuntu 16.04 installieren und einrichten

Zurück zur Tutorial Übersicht Back to Tutorial Overview

InfluxDB – Monitoring mit dem TIG-Stack

influxdata & TIG-Stack Header

Als Fortsetzung zum Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten und des darin begonnenen Anwendungsszenarios, werde ich dir in diesem Tutorial Grafana als eine Möglichkeit der Analyse, Aufbereitung und des Managements von in InfluxDB gespeicherten Messungen vorstellen. Ich werde das erwähnte Anwendungsszenario dahingehend fortführen, dass ich die in der Datenbank namens OnlineMarketDevelopment als Teil der Messung namens SalesActivity eingebundenen Datenpunkte in Grafana plotten lasse. Wie bereits im oben genannten Tutorial angeschnitten, bietet das integrierte Open-Source-Projekt Grafana eine Komponente für die Benutzeroberfläche zum Management, zur Überwachung und graphischen Aufbereitung von in InfluxDB enthaltenen Messungen. Integriert bedeutet, dass sowohl InfluxDB als auch Grafana Komponenten eines Stacks sind, dem sogenannten TIG-Stack. Im Tutorial zum Thema InfluxDB – Monitoring mit dem TICK-Stack habe ich dir bereits vorgeführt, wie du die einzelnen Komponenten des TICK-Stacks installierst, einrichtest und Chronograf im Kontext dieses Stacks nutzt. Grafana stellt neben Chronograf eine weitere Option als Monitoring-Plattform dar.
Der TIG-Stack setzt sich aus den drei Komponenten Telegraf, InfluxDB und schließlich Grafana zusammen. Wie im Fall des TICK-Stacks, bildet Telegraf auch beim TIG-Stack die Schnittstelle, um in InfluxDB gespeicherte Daten an die Monitoring-Plattform – in diesem Fall Grafana – zu senden. Analog zum TICK-Stack lassen sich auch beim TIG-Stack mit InfluxDB Daten somit nicht lediglich wiederauffindbar aufbewahren, sondern sind via Telegraf auch jederzeit an die Monitoring-Plattform übertragbar. Letztlich fungiert Grafana dann auf Basis von Telegraf und InfluxDB als infrastrukturelles Monitoring-Tool.
Zunächst müssen diese drei Komponenten heruntergeladen, installiert und konfiguriert worden sein, damit du diese Infrastruktur nutzen kannst. Da wir zusammen InfluxDB bereits im Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten erfolgreich installiert und konfiguriert haben und du im Tutorial InfluxDB – Monitoring mit dem TICK-Stack u.a. eine Anleitung dazu bekommen hast, wie du Telegraf auf deinem Server installierst und einrichtest, widme ich mich nun direkt dem letzten Bestandteil des TIG-Stacks.

Grafana installieren und einrichten

Um Grafana herunterzuladen und zu installieren, musst du die drei Kommandos in deinem Terminal ausführen, die du im Code-Snippet unten erkennst. Die Version – in diesem Fall ist es 5.0.4 – ist hierbei austauschbar.


> wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.4_amd64.deb

> apt-get install -y adduser libfontconfig

> dpkg -i grafana_5.0.4_amd64.deb

Daraufhin ist es notwendig, dass die im folgenden Code-Block eingeblendeten Kommandos durchführst, sodass Grafana startet. Hiermit stellst du dann auch sicher, dass Grafana nach dem Neustart automatisch starten wird.


> /bin/systemctl enable grafana-server

> /bin/systemctl start grafana-server

> /bin/systemctl daemon-reload

Als nächstes zeige ich dir, wie du Grafana konfigurierst. Hierzu rufst du in deinem Browser http://localhost:3000 auf, da Grafana unter dem Port 3000 verfügbar ist, wobei du localhost mit der IP-Adresse deines Servers austauscht.
Dadurch gelangst du – wie im Screenshot unten zu sehen – auf die Login-Seite von Grafana, über die du dir mittels default-Nutzerdaten Zugang zu der Monitoring-Plattform verschaffen kannst. Der default-Benutzername ist admin und auch das default-Passwort lautet admin.

Login-Seite von Grafana ohne Sign-Up-Button

Auf der Login-Seite wäre eigentlich auch der Button für die Registrierung zu finden. Damit er allerdings auch sicht- und nutzbar ist, müsste man in der Konfigurationsdatei von Grafana eine Anpassung vornehmen. Solltest du dich also unter einem neuen Nutzer registrieren wollen, müsstest du zunächst via dem unten eingeblendeten Kommando die Konfigurationsdatei von Grafana in einem Editor öffnen. In meinem Beispiel tue ich dies mit dem nano-Editor.


> nano /etc/grafana/grafana.ini

In der Konfigurationsdatei scrollst du dich dann bis zur [users]-Sequenz, wie im Screenshot unten demonstriert. Dort findest du im Abschnitt disable user signup / registration den Parameter allow_sign_up. Im Screenshot unten ist die betreffende Zeile gelb markiert. Zum einen musst du dessen Wert auf true setzen, wenn er per default auf false steht. Zudem musst du das Semikolon entfernen, dass sich vor dem Parameter befindet, da es dazu führt, dass die Zeile als Kommentar interpretiert wird.

Auszug aus der Konfigurationsdatei von Grafana

Mit Betätigung der Kombination aus den Tasten Strg und O leitest du das Speichern deiner Änderungen in der Konfigurationsdatei ein und bestätigst deren daraufhin in einem weißen Balken eingeblendeten Dateinamen mit der Enter-Taste. Anschließend verlässt du den nano-Editor via Betätigung der Kombination aus den Tasten Strg und X.
Um die Änderungen schließlich zu aktivieren, musst du Grafana via dem unten gezeigten Command neu starten.


> systemctl restart grafana-server

Über Ausführung des folgenden Kommandos kannst du dir den Status des Servers wiedergeben lassen, um sicherzustellen, dass alles geregelt läuft. Das Output liefert dir dann im positiven Fall einen Report darüber, dass Grafana aktiv ist.


> systemctl status grafana-server

Sobald du dann den Browser neu lädst, erkennst du den Sign Up-Button für die Registrierung.

Login-Seite von Grafana mit Sign-Up-Button

Sobald du eingeloggt bist, befindest du dich auf dem Home-Dashboard von Grafana, was dir der folgende Screenshot präsentiert. Mit Klick auf das verlinkte Icon Add data source, wirst du zu der Seite weitergeleitet, auf der du die erste Verbindung zu einer Datenbank herstellen und somit die kommunizierende Schnittstelle zwischen Grafana und einer Datenbank definieren kannst.

Home Dashboard von Grafana nach Installation

Wie du gut im Screenshot unten erkennst, kannst du auf der betreffenden Seite zum einen festlegen, zu welcher Datenbank die Verbindung gesetzt werden soll und welchem Kontext die Datenbank zuzuordnen ist.
Gemäß dem im Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten eingeleiteten Anwendungsszenario heißt meine Datenbank in diesem Beispiel OnlineMarketDevelopment und ist vom Typ InfluxDB. Bei der Typzuweisung wird dir eine mögliche Auswahl an Typen, mit denen Grafana nutzbar ist, über eine Dropdown-Liste, bereitgestellt. Des Weiteren kannst du die HTTP Settings definieren. Im Feld für die URL trägst du die URL http://localhost:8086 ein, da der HTTP-Dienst von InfluxDB unter dem Port 8086 verfügbar ist, wobei du localhost mit der IP-Adresse deines Servers austauscht. Du hast zusätzlich über eine Dropdown-Liste die Möglichkeit deine HTTP-Settings als proxy oder direct zu bestimmen. Wenn deine Wahl auf proxy fällt, dann wird die Anfrage durch das Backend von Grafana vertreten. Solltest du dich hingegen für direct entscheiden, dann wird die URL direkt vom Browser verwendet. In meinem Beispiel entscheide ich ich mich den Zugang über die Option direct handzuhaben.

Verbindung zu einer Datenbank in Grafana einrichten

Zudem hast die Möglichkeit die Art und Weise für die HTTP-Authentifizierung via Checkmark-Boxen einzustellen.
Schließlich gibst du Informationen zur Schnittstelle, die die Kommunikation zwischen InfluxDB und Grafana herstellt, und letztlich kannst du dann noch die Höhe und die Einheit für die automatische Gruppierung nach Zeitintervall für die Datenerhebung festlegen, z.B. stünde 1s für ein Intervall von einer Sekunde, 10m für eines von zehn Minuten, 1h für eines von einer Stunde usw. Du bestätigst dann die Konfiguration mit Klick auf den grünen Button und dir wird bei erfolgreicher Einrichtung eine Meldung eingeblendet, die dir den Hinweis gibt, dass deine Datenbank mit Grafana arbeitet. Du kannst bereits existierende Datenbankenressoucen jederzeit editieren und/oder auch neue hinzufügen. Dies ist die auf der Configuration-Seite möglich. Der Screenshot unten verbildlicht dir, dass du diese Seite via dem vierten Menüpunkt in Grafana erreichst.

Configuration-Menüpunkt in Grafana mitsamt Unterpunkten

Der angeklickte Menüpunkt gibt dir via Fly-Out-Menü Aufschluss über die zu Inhalte, die die Configuration-Seite beinhaltet und die dann auch auf der Seite selbst im Nachhinein via Tabs aufrufbar sind, wie dir der Screenshot unten demonstriert.

Übersicht über verbundene Datenbank-Ressourcen in Grafana

Im Tab Data Sources sind dir die bestehenden Datenbankquellen aufgelistet. Durch Klick auf ein Item in dieser Liste, ist es dir möglich die Informationen, mit denen du das Item konfiguriert hast, zu ändern oder das Item gar zu löschen. Mit Klick auf + Add data source kannst du eine neue Datenbankquelle hinzufügen. Über den Tab Users kannst du Nutzer hinzufügen und über den Tab Teams kannst du Teams definieren. Im Tab Plugins wird dir eine Liste integrierbarer Plugins zur Verfügung gestellt, aus der du frei wählen kannst. Der Tab Preferences dient zur Modifizierung der Bezeichnung deines Profils, sowie von Einstellungen, die das Aussehen deiner Monitoring-Plattform (hell/dunkel), die Art deines Home-Dashboards sowie die Zeitzone betreffen. Im Tab API Keys werden dir schließlich alle deine existierenden API-Keys gelistet aufgeführt und hier kannst du dem Panel auch neue API-Keys hinzufügen.

InfluxDB mit Grafana nutzen

In Grafana werden Dashboards angeboten, um die via Queries aus bestimmten in InfluxDB enthaltenen Datenbanken ermittelten Informationen übersichtlich und wiederauffindbar darstellen zu lassen. Wie du im Screenshot unten siehst, kannst du über Fly-Out-Menü des Create-Menüpunktes in diverse Aktionen treten, um ein Dashboard oder einen Dashboard-Ordner anzulegen oder ein Dashboard zu importieren. Der Import eines Dashboards ist entweder über Copy&Paste dessen URL oder ID in ein hierfür vorgesehenes Feld möglich oder indem du den Inhalt dessen zugehöriges JSON in ein Editor-Feld überträgst oder indem du direkt eine JSON-Datei hochlädst und somit ein Dashboard generierst.

Create-Menüpunkt in Grafana mitsamt Unterpunkten

Nachdem ich gemäß dem im Tutorial InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten geschilderten Anwendungsszenario als Indexer die Messung SalesActivity in der Datenbank OnlineMarketDevelopment mit Datenpunkten befüllt habe, möchte ich diese in Grafana monitoren und werde hierzu beispielhaft ein Dashboard erstellen. Sobald ich den Untermenüpunkt Dashboard von Menüpunkt Create geklickt habe, lande ich auf der Seite, auf der man neue Dashboards generieren lassen kann. Der Screenshot unten führt dir die unterschiedlichen Arten der Visualisierung vor Auge, die zur Verfügung gestellt werden. Ich werde in diesem Beispiel den Graph als visuelles Medium meines Dashboards wählen.

Neues Dashboard in Grafana erstellen

Wie bereits in der Skizzierung des Anwendungsszenarios vermerkt, beziehen sich die von mir in die in InfluxDB enthaltene Datenbank OnlineMarketDevelopment implementierten Datenpunkte auf einen Zeitraum von 15 Minuten, genau genommen auf den Zeitraum von 13:00 bis 13:15 am 17.04.2018. Der rechten Spalte entnimmst du alle zur Simulation des Anwendunsszenarios durchgeführten INSERT-Operationen für die Messung SalesActivity. Zur Übersichtlichkeit für dich habe ich in der linken Spalte jeweils den dazugehörigen Zeitstempel dokumentiert.

Datum:

17.04.2018

Uhrzeit

via INSERT-Operation im Epoch-Format indexierte(r) Datenpunkt(e)

13:00

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=52i,buying=FALSE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“dortmund“,gender=“male“ age=25i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“female“ age=19i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=33i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“female“ age=22i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=30i,buying=FALSE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=39i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=18i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=21i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“female“ age=45i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“borken“,gender=“female“ age=23i,buying=TRUE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=50i,buying=FALSE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“niederkassel“,gender=“female“ age=28i,buying=FALSE 1523962800

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“male“ age=37i,buying=TRUE 1523962800

13:02

INSERT SalesActivity,region=“EMEA“,dc=“oberhausen“,gender=“female“ age=31i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=27i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=53i,buying=FALSE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“male“ age=25i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=28i,buying=TRUE 1523962920

INSERT SalesActivity,region=“EMEA“,dc=“duesseldorf“,gender=“male“ age=26i,buying=TRUE 1523962920

13:03

INSERT SalesActivity,region=“EMEA“,dc=“duesseldorf“,gender=“female“ age=42i,buying=FALSE 1523962980

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“female“ age=26i,buying=FALSE 1523962980

INSERT SalesActivity,region=“EMEA“,dc=“bottrop“,gender=“male“ age=53i,buying=FALSE 1523962980

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=21i,buying=FALSE 1523962980

13:07

INSERT SalesActivity,region=“EMEA“,dc=“dormagen“,gender=“male“ age=18i,buying=TRUE 1523963220

INSERT SalesActivity,region=“EMEA“,dc=“bocholt“,gender=“male“ age=24i,buying=TRUE 1523963220

13:08

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=40i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=56i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“frechen“,gender=“female“ age=47i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“male“ age=39i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“female“ age=51i,buying=FALSE 1523963280

INSERT SalesActivity,region=“EMEA“,dc=“bonn“,gender=“female“ age=31i,buying=TRUE 1523963280

13:11

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=20i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“koenigswinter“,gender=“female“ age=25i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“dortmund“,gender=“male“ age=33i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=30i,buying=TRUE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“male“ age=29i,buying=TRUE 1523963460

13:13

INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“female“ age=28i,buying=TRUE 1523963580

INSERT SalesActivity,region=“EMEA“,dc=“bornheim“,gender=“female“ age=21i,buying=TRUE 152396358

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=35i,buying=TRUE 1523963580

13:14

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“male“ age=60i,buying=FALSE 1523963460

INSERT SalesActivity,region=“EMEA“,dc=“bonn“,gender=“male“ age=53i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“female“ age=57i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“female“ age=44i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“female“ age=48i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“male“ age=41i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“male“ age=48i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“female“ age=55i,buying=FALSE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“female“ age=18i,buying=TRUE 1523963640

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=27i,buying=TRUE 1523963640

13:15

INSERT SalesActivity,region=“EMEA“,dc=“dinslaken“,gender=“female“ age=26i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=23i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“female“ age=19i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“bad_honnef“,gender=“female“ age=51i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“bonn“,gender=“male“ age=19i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“oberhausen“,gender=“male“ age=34i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“aachen“,gender=“female“ age=38i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“male“ age=21i,buying=TRUE 152396370

INSERT SalesActivity,region=“EMEA“,dc=“niederkasse“l,gender=“male“ age=28i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“male“ age=32i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=36i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“oberhausen“,gender=“male“ age=46i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“wuppertal“,gender=“female“ age=31i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“duesseldorf“,gender=“male“ age=25i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“leverkusen“,gender=“male“ age=21i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“bochum“,gender=“male“ age=27i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“essen“,gender=“female“ age=33i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“koeln“,gender=“female“ age=40i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“duisburg“,gender=“male“ age=18i,buying=TRUE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“schwerte“,gender=“male“ age=68i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“herne“,gender=“female“ age=39i,buying=FALSE 1523963700

INSERT SalesActivity,region=“EMEA“,dc=“dormagen“,gender=“male“ age=20i,buying=FALSE 1523963700

Nachdem ich den im Screenshot oben ersichtlichen Graph-Button geklickt habe, wird ein zunächst noch leeres Graph-Dashboard generiert. Im Screenshot unten zeige ich dir, dass per Klick auf den Titel des Dashboards ein Fly-Out-Menü erscheint, dass dir unterschiedliche Optionen bietet, um mit dem Dashboard zu interagieren. Um es mit Informationen zu füllen, musst du Edit klicken. Im unten eingeblendeten Screenshot befinde ich mich gerade in der Edit-Option. Neben dem Editieren, kannst du dir das Dashboard über Klick auf View einfach nur ansehen, bzw. in den View-Modus wechseln. Mittels Klick auf Share kannst du das Dashboard teilen. Über den weiterführenden Menüpunkt More werden dir dann noch Möglichkeiten zum Export des Dashboards in das Format CSV oder der Übertragung des Dashboards in das Format JSON angeboten.

Neu erstelltes leeres Dashboard in Grafana

In der im Tab Metrics befindlichen Dropdown-Liste von Data Source kann ich die Datenbank wählen, aus der ich Informationen monitoren möchte. Mit Klick auf den darunter befindlichen Add Query-Button wird schließlich eine Schaltfläche zum generieren einer Query eingeblendet, wie dir der Screenshot unten demonstriert.

Grafana-Dashboard im Edit-Modus mit Schaltflächen

Über darin enthaltene Buttons kann ich die Parameter meiner Query festlegen und muss diese nicht in einen Editor schreiben.
In meinem Beispiel bevorzuge ich es aber die Anfrage selber zu schreiben. Hierzu klicke ich den Toggle Edit Mode-Button ganz rechts neben der Schaltfläche. In den daraufhin eingeblendeten Editor habe ich nun meine Query eingetragen, was gut im Screenshot unten zu erkennen ist. Du entnimmst aus der Query, dass ich den Zeitraum der Datenpunkte, die ich erhoben habe und plotten lassen möchte, nicht mittels der WHERE-Bedingung definiert, sondern lediglich den Intervall auf eine Stunde via dem GROUP BY-Statement festgelegt habe. Trotzdem ist das Zeitfenster definiert, nämlich – wie du der rechten oberen Hälfte des Screenshots entnimmst – über die Quick ranges-Auswahl aus dem Panel, dass via Klick auf den darüber liegenden Button eingeblendet wurde. Alternativ dazu kannst du auch die auf der linken Seite des Panels befindliche Schaltfläche nutzen, um ein individuelles Zeitfenster zu spezifizieren. Ich habe mich entschieden die unter Quick ranges angebotene Previous week als Zeitrahmen zu wählen, da es sich gut für das 1-stündige Intervall anbietet. Unterhalb des geplotteten Graphen siehst du die dazugehörige Legende. Diese kann im Tab Legend via Checkmark-Box generiert werden und dort hast du auch die Möglichkeit, zu bestimmen, ob Werte wie z.B. Minimum, Maximum oder Durchschnitt unterhalb des Graphen abgebildet werden sollen. Wenn du auf die Legende unterhalb des Graphen klickst, wird dir eine Farbpalette eingeblendet, aus der du dann eine vorgeschlagene Farbe für den Graphen auswählen oder nach Bedarf sogar selber eine Farbe definieren kannst.

Modifizierung einer Query in Grafana im Editor im Edit-Modus via Quick ranges Item "Previous-week"

Durch erneutes Klicken auf den Button über dem Panel wird es wieder ausgeblendet und der hierüber definierte Zeitrahmen bleibt solange aktiv bis er entweder in der Query im Editor überschrieben wird oder im Panel selbst neu gestaltet wird. Mittels dem $timeFilter-Parameter kannst du das Zeitfenster in der Query auch selber definieren, wie ich dir im folgenden Code-Snippet unten vorführe. Für die korrekte Syntax des hinter dem Parameter stehenden Wertes kannst du dich am eben erwähnten Panel orientieren. Wenn man dort nämlich ein Item aus den Quick ranges anklickt, wird in den Eingabefeldern auf der linken Seite des Panels die analog hierzu lautende Syntax generiert. Demnach würde der Wert now-1w/w den Zeitrahmen der vorherigen Woche wiedergeben.


SELECT COUNT("buying") AS "counts_buying_+_no_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "buying" = TRUE AND $timeFilter = now-1w/w GROUP BY time(1h)

Der Screenshot unten wiederum zeigt einen Ausschnitt meiner Arbeit im erzeugten Graph-Dashboard, wo ich das Zeitfenster der geplotteten Datenpunkte individuell über die auf der linken Seite des eingeblendeten Panels zur Verfügung gestellten Schaltfläche festgesetzt habe. Analog meiner Datenerhebung, habe ich den Zeitrahmen für den 17.04.2018 definiert, beginnend mit 13:00 und endend mit 13:15. Hierbei habe ich das über GROUP BY Intervall in der Query auf eine Minute gesetzt.

Modifizierung einer Query in Grafana im Editor im Edit-Modus via definiertem Custom range

Im Code-Block unten ist dieselbe Query, wie du sie auch oben im Screenshot findest, zum Nachvollziehen enthalten.


SELECT COUNT("buying") AS "counts_buying_+_no_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" GROUP BY time(1h)

Unten im Screenshot präsentiere ich dir, wie du das Design eines Graphen im Tab Design managen kannst. Hier hast du u.a. die Möglichkeit dir den Graph entweder als Linien- oder Bar-Graph darstellen zu lassen, eine Markierung der Datenpunkte einzubinden, die Linienstärke des Graphen zu bestimmen, sowie festzulegen, ob der Graph transparent oder in einem bestimmten Grad farblich gefüllt sein soll.

Design von Dashboard-Graphen in Grafana im Display-Tab definieren

Grafana ist eine fortschrittliche Monitoring-Plattform, es lassen sich mehrere Queries gleichzeitig plotten. Um dir dies zu demonstrieren, werde ich im Tab Metrics über den Button Add Query jeweils drei neue Editor-Felder generieren, in die ich jeweils eines der Queries einbinde, die sich in den folgenden drei Code-Snippets befinden.


SELECT COUNT("buying") AS "counts_buying" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "buying" = TRUE GROUP BY time(1m)

SELECT COUNT("buying") AS "counts_buying | age 

SELECT COUNT("buying") AS "counts_buying | age > 35" FROM "OnlineMarketDevelopment"."autogen"."SalesActivity" WHERE "buying" = TRUE AND "age" > 35 GROUP BY time(1m)

Der Screenshot unten demonstriert dir das Endergebnis meines im Kontext der vier Queries durchgeführten Monitorings. Der Graph der ersten Query gibt das Total aller Aktivitäten der Besucher des Online-Shops pro Datenpunkt wieder, worunter sowohl die Besucher zählen, die einen Einkauf getätigt haben, als auch solche, die den Online Shop lediglich durchstöbert haben. Der Graph der zweiten Query wiederum plottet lediglich die Anzahl an getätigten Einkäufen. Mittels der dritten und vierten Query wird ebenfalls die Anzahl an Einkäufen geplottet, jedoch jeweils in Abhängigkeit eines in der betreffenden Query via WHERE-Bedingung angefragten Altersgruppe.

Im Graph-Dashboard von Grafana mehrere Queries nebenher plotten lassen

Mouseover-Effekt in Graph-Dashboard von Grafana

Wenn du mit dem Mauszeiger über die Datenpunkte der geplotteten Graphen fährst, wird dir hierzu als MouseOver-Effekt eine kleine Datenübersicht eingeblendet, wie dir der Screenshot oben zeigt.
Mit Klick auf das Speichern-Icon oben links in der Werkzeugleiste kannst du das erstellte Dashboard-Item zunächst speichern und im Nachhinein jederzeit darauf zugreifen, um es zu editieren oder zu löschen. Im daraufhin erscheinenden Speichern-Interface wirst du nach dem Namen des Dashboards gefragt und musst entweder via DropDown-Liste einen bereits existierenden Dashboard-Ordner wählen oder einen neuen anlegen. Nachdem das Speichern abgeschlossen ist, befindet sich das Dashboard-Item im Dashboard, was der Screenshot unten verbildlicht. Mittels dem ersten Button oben links in der Werkzeugleiste ist es dir möglich dem Dashboard neue Items hinzuzufügen. Via Zahnrad-Icon gelangst du zu den Einstellungen des Dashboard-Items.

Dashboard-Item in Dashboard von Grafana

Für Graph(en) in einem Dashboard-Item ist es möglich eine Benachrichtigungsregel zu formulieren. Ich zeige dir am Beispiel des oben im Screenshot ersichtlichen Dashboard-Items, wie dies funktioniert. Zunächst musst du hierfür wieder in den Edit-Modus des betreffenden Dashboard-Items wechseln, indem du den Titel anklickst und in dem daraufhin eingeblendeten Fly-Out-Menü Edit auswählst.
Wenn du dich dann in der Tab-Leiste unterhalb der geplotteten Graphen in den Tab Alert navigierst, siehst du direkt darunter auf der linken Seite den Button Create Alert. Nachdem du den Button betätigt hast, wird eine Schaltfläche generiert, über die du eine Benachrichtigungsregel mit einer oder mehreren Bedingungen für den/die geplotteten Graphen erstellen kannst. Im Screenshot unten erkennst du, dass du zunächst den Namen für die Konfiguration der Benachrichtigungsregel eintragen sowie den Intervall der Evaluation festlegen kannst. Darunter hast du dann die Möglichkeit über die zur Verfügung gestellten Schaltflächen die Bedingungen für Benachrichtigungen zu definieren.

Benachrichtigungregel für Graph-Dashboard in Grafana einrichten

Wenn du in das Feld klickst, dass nach dem Schlüsselwort WHEN folgt, kannst du aus einer DropDown-Liste eine Aggregationsfunktion wählen. Z.B. lässt sich mit Aggregationsfunktion avg() steuern, wie die Werte für jede Serie auf einen Wert reduziert werden sollen, der mit dem Schwellenwert verglichen werden kann.
Im nächsten Feld wird definiert, welche Abfrage auf den Metrics-Tab ausgeführt werden soll. Hierbei hast du die Option alle in der query-Klammerung stehenden Parameter anzupassen. Bei Klick auf jeden der drei Parameter aktivierst du eine DropDown-Liste aus vorgeschlagenen Werten. Der erste Parameter nimmt Bezug auf die betreffende Query aus der im Metrics-Tab einer der Graphen geplottet wird. Mit den folgenden beiden Parametern lässt sich der Zeitbereich fixieren. 5m als Wert für den zweite und now() als Wert für den dritten Parameter würde den Zeitrahmen vor 5 Minuten bis jetzt festlegen. Im Anschluss daran wird der Schwellenwert bestimmt. Im hierfür vorgesehenen Eingabefeld kannst du einen Schwellenwert eintragen. Via der vor dem Schwellenwert befindlichen Schaltfläche wird der Typ des Schwellenwerts zugeordnet, indem auf die Schaltfläche geklickt und in der dadurch generierten DropDown-Liste ein vorgeschlagener Typ gewählt wird. Unter der erstellten Bedingung befindet sich ein +-Icon, mit dem du beliebig viele neue Schaltflächen für Bedingungen generieren kannst. Im folgenden Screenshot habe ich für jeden der vier via Query im Metrics-Tab geplotteten Graphen eine Bedingung gesetzt,nämlich für Query A, B, C und D. Für jeden der vier Queries ist das Zeitfenster auf 10 Minuten definiert und die Benachrichtigung soll für jeden der Queries jeweils dann passieren, wenn der Schwellenwert über dem Wert 10 liegt. In Relation habe ich diese vier Benachrichtigungsregeln gesetzt via dem booleschen OR-Operator. Mit Klick auf die Schaltfläche ist es möglich den OR-Operator in einen AND-Operator zu wandeln, je nachdem wie die Logik Sinn macht. Es wäre auch möglich zu ein und derselben Query – z.B. Query A – mehr als eine Bedingung zu erzeugen.

Mehrere Benachrichtigungsregeln für Graph-Dashboard in Grafana

Parallel zum Erstellen von Benachrichtigungsregeln ist es möglich Benachrichtigungskanäle einzurichten. Hierzu navigierst du dich über das Fly-Out-Menü des Alerting-Menüpunktes im links befindlichen Grafana-Menü zum Punkt Notification Channels. Dann kannst du über den daraufhin eingeblendeten Add channel-Button ein neues Channel-Item generieren.
Der Screenshot unten präsentiert das Interface, in dem du den Benachrichtigungskanal einrichten und jederzeit auch im Nachhinein editieren kannst.

Item für Benachrichtigungskanal in Grafana editieren

Unter anderem kannst du dort den Typ des Benachrichtigungskanals bestimmen, indem du im Typ-Feld die DropDown-Liste aktivierst und einen aller möglichen Event-Handler wählst. Dieser wird definiert, damit Grafana Benachrichtigungen an den von dir gewählten Event-Handler senden und dich up to date halten kann. Besonders hilfreich kann die Nutzung dieses Dienstes sein, um Warnmeldungen an bestimmte E-Mails sowie an Anwendungen wie Slack oder HipChat zu senden oder an eine Liste von E-Mailadressen. Voraussetzung ist, dass du selbst oder der User, für den du diesen Benachrichtigungskanal einrichtest, bei solch einer Anwendung registriert bist. Für unterschiedliche Event-Handler können unterschiedliche und spezifische Daten erforderlich sein, um die Verbindung herzustellen. Diese Daten werden in der zweiten Hälfte unten im Interface eingetragen. Bestimmte erforderliche Daten sind von der betreffenden Anwendung einzuholen, z.B. wenn es sich um einen Token, eine URL oder Ähnliches handelt.

Fazit

Du hast Grafana als fortgeschrittene Monitoring-Plattform kennen gelernt und im besten Fall bist du neugierig geworden deine Projekte hiermit umzusetzen. Ich wünsche dir viel Erfolg und vor allem Freude bei der Arbeit mit Grafana.

Zurück zur Tutorial Übersicht Back to Tutorial Overview

Neo4j unter Ubuntu 16.04/18.04 installieren und einrichten

neo4j unter Ubuntu installieren und einrichten

In unseren Tutorials zu den Themen MySQL Datenbank erstellen und löschen, PostgreSQL 10 auf Ubuntu 16.04 / 14.04 installieren, MongoDB auf Ubuntu installieren, Apache Cassandra auf Ubuntu installieren, Redis auf Ubuntu 16.04 LTS installieren und RethinkDB auf Ubuntu installieren stellen wir dir Basisinformationen zu SQL- und NoSQL-Datenbanken bereit und machen dich u.a. damit vertraut, wie du diese installieren und konfigurieren kannst. Mit unserem Tutorial zum Thema InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten stellen wir eine neue Form von Datenbank vor, die das Konzept Datenbank im Sinne einer NoSQL-Datenbank-Plattform für Zeitreihen basierte Datenerhebungen weiter denkt und die Analyse von gespeicherten Informationen via Monitoring und Graph-Plotting fortschrittlicher werden lässt. Nun, in diesem folgenden Tutorial geht es auch um eine Graph orientierte Datenbank-Plattform, nämlich Neo4j.

Neu! – Autoscale MySQL-as-a-Service von Tech4Hosting

Alle, die sich nicht mehr mit Datenbank-Administration auseinandersetzen wollen, können jetzt auch die neuen Platform Services von Tech4Hosting nutzen.

Der Vorteil der Platform Services bei Tech4Hosting: Wir kümmern uns um die sichere Konfiguration, den zuverlässigen Betrieb und die Installation von Sicherheitsupdates deiner PaaS-Dienste. In deinem Tech4Hosting Panel kannst du ab sofort mit den Datenbanken PostgreSQL, MySQL und redis starten.
Probiere es einfach mal aus!

Mehr Infos zu PaaS bei Tech4Hosting und wie PaaS funktioniert gibt es in unserem
Getting started mit PaaS bei Tech4Hosting
Platform Services von Tech4Hosting.

Zu Neo4j

Bei Neo4j handelt es sich – wie in der Einleitung erwähnt – um eine Diagramm-Datenbank, die als Art Plattform fungiert. Neo4j ermöglicht es Daten zu verbinden und Beziehungen visuell aufbereitet im Kontext eines skalierbaren und zuverlässigen Datenbanksystems zu erkennen. Neo4j bietet seinen Service als Online-Datenbankverwaltungssystem mit Operationen zum Erstellen, Lesen, Aktualisieren und Löschen (CRUD) an. Mit all diesen Operationen kann an einem Graphdaten-Modell gearbeitet werden. Dabei wird mit einer herstellerneutralen und offenen Abfragesprache mit eigener Syntax agiert, die von der geläufigen SQL-Abfragesprache abweicht. Mit der Datenbanksprache Cypher können Muster von Knoten und Beziehungen in Graph-Datasets verglichen werden.

Wie SQL ist Cypher eine deklarative Abfragesprache, mit der Benutzer angeben können, welche Aktionen sie für ihre Diagrammdaten ausführen möchten (z. B. Übereinstimmung, Einfügen, Aktualisieren oder Löschen), ohne dass sie diese genau beschreiben oder programmieren müssen.

Das Datenmodell für eine Graphdatenbank ist wesentlich einfacher und aussagekräftiger als das von relationalen oder anderen NoSQL-Datenbanken.

Anwendungsszenario

In Neo4j besteht ein Graph aus zwei Elementen, nämlich einem Knoten und einer Beziehung. Jeder Knoten repräsentiert hierbei eine Entität (eine Person, ein Ort, eine Sache, eine Kategorie oder einen anderen Typ von Datenelement), und jede Beziehung stellt dar, wie Knoten miteinander verknüpft sind. Einem Knoten kann eine beliebige Menge von Eigenschaften zugewiesen werden. Eine Eigenschaft setzt sich hierbei aus je einem Paar aus Bezeichnung der Eigenschaft und Wert der Eigenschaft zusammen. Zum Beispiel könnte ein Knoten der Entität “Person” die Eigenschaften besitzen, die sich aus dem Namen der Person und ihrer Herkunft zusammensetzen. “Name” und “Herkunft” könnten dann jeweils Bezeichnungen der zwei Eigenschaften sein mit je einem dahinter stehenden Wert pro Knoten. Jeder Knoten einer Entität ist Element der betreffenden Entität. Elemente ein und derselben Entität lassen sich über Label gruppieren, indem für jedes Mitglied der Entität ein Label angewendet wird. So müsste jedes neue Element der Entität Person mit dem Label “Person” gekennzeichnet werden, damit die Zugehörigkeit in der Datenbank eindeutig ist.

Mit dem Graph basierten Datenbankkonzept von Neo4j lassen sich alle denkbaren Arten von Szenarien modellieren – von einem Straßensystem über ein Netzwerk von Bekanntschaften bis hin zur Demographie einer Population. Schlicht alles, was durch Beziehungen definiert werden kann, lässt sich in einem Graphen abbilden.
Für dieses Tutorial habe ich mir ein eigenes Szenario ausgedacht. Ich möchte ein Netzwerk zwischen zwei Universitäten kreieren. In diesem Netzwerk soll zum einen transportiert werden, welche Studiengänge die betreffende Universität anbietet und zum anderen soll visuell ersichtlich werden, welche Studiengänge ähnliche Studieninhalte haben.

Voraussetzung

Neo4j wird in Java implementiert, was das Vorhandensein eines Java Runtime Environment (JRE) bedingt. Hierzu werde ich einen Teil dieses Tutorials zur Installation und Einrichtung von Java unter Ubuntu widmen.

Java installieren und einrichten

Bevor du Neo4j installierst, musst du die Java-Laufzeit-Umgebung (JRE) auf deinem Server installieren. Zunächst führst du mittels dem folgenden Kommando ein Update durch.


apt-get update

apt-get upgrade

Danach installierst du dann die Software, die erforderlich ist, um Java-Anwendungen auszuführen. Für vergangene Versionen würdest du einfach die Versionsnummer im unten eingeblendeten Kommando austauschen.


apt-get install openjdk-8-jre

Als nächstes installierst du via dem unten gezeigten Kommando das „IcedTea“-Java-Plugin, das nötig ist, um Java in Webseiten zu verwenden. Das besagte Plugin funktioniert mit Firefox, Chromium Chrome, Konqueror und Epiphany.


apt-get install icedtea-8-plugin

Die Installation von Java auf dem Server reicht nicht aus. Zusätzlich ist es notwendig die Umgebungsvariable zu setzen, die via $JAVA_HOME erreichbar ist.
Um zu prüfen, ob diese bereits gesetzt ist und vielleicht angepasst werden muss oder gar fehlt, führen wir das folgende Kommando aus. Wenn du kein Output erhälst, ist die Umgebungsvariable nicht gesetzt.


echo $JAVA_HOME

Um die Umgebungsvariable schließlich zu definieren, ist die Information über den Pfad wichtig, unter dem die Java JRE installiert wurde.

Der folgende Befehl


which java

oder der Befehl unterhalb


whereis java

können dir dazu dienen, dies herauszufinden. Beide werden dir als Output den jre-Pfad in /usr/bin/java wiedergeben. Hierbei handelt es sich dann aber nicht um die aktuelle jre-Datei, sondern um eine Art symbolischem Link, der weiterführend Aufschluss zum Standort bzw. zum Pfad der aktuellen jre-Datei geben kann. Diese Information in Kombination mit dem Kommando-Präfix readlink -f liefert dir als Output dann letztlich den korrekten Pfad.


readlink -f /usr/bin/java

Mit Hilfe der beiden im Code-Snippet unten präsentierten Kommentare setze ich letztlich die Umgebungsvariable. In meinem Beispiel ist der Pfad, unter dem Java JRE installiert wurde /usr/lib/jvm/java-8-openjdk-amd64/jre/bin.


JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre/bin

PATH=$JAVA_HOME/bin:$PATH

Neo4j installieren und einrichten

Bevor du Neo4j installierst, musst du den Repository-Schlüssel dem Repository hinzufügen. Hierzu führst du das folgende Kommando im Terminal aus.


wget --no-check-certificate -O - https://debian.neo4j.org/neotechnology.gpg.key | apt-key add -

Daraufhin bindest du das Repository via dem folgenden Kommando in die Liste der apt-Quellen ein.


echo 'deb http://debian.neo4j.org/repo stable/' > /etc/apt/sources.list.d/neo4j.list

Hiernach führst du mittels der unten aufgeführten Kommandozeile ein Update des Repositories durch und installierst Neo4j.


apt-get update && apt-get install neo4j

Danach sollte der Server automatisch gestartet sein und auch über den Server-Boot neu gestartet werden. Bevor du Neo4j allerdings auch nutzen kannst, musst du in der Konfigurationsdatei ein paar Anpassungen vornehmen, die darauf hinauslaufen, dass du drei als Kommentar kenntlich gemachte Zeilen auskommentierst. In der Konfigurationsdatei werden Kommentare mit einer vorstehenden Raute kenntlich gemacht, also mit #. Um eine Zeile wieder einzukommentieren, musst du die jeweilige Raute entfernen. Hierfür öffnest du die Konfigurationsdatei im nano-Editor, indem du den untenstehenden Befehl ausführst.


nano /etc/neo4j/neo4j.conf

Im nano-Editor suchst du dann nach den Zeilen Code, die im Snippet unten zu sehen sind. Durch Entfernen der davorstehenden Raute machst du diese drei Inhalte wieder lesbar. Im Anschluss daran leitest du das Speichern deiner Updates mit der Tastenkombination aus Strg und O ein und bestätigst den daraufhin in einem weißen Balken eingeblendeten Dateinamen mit der Taste Enter.


#dbms.connectors.default_listen_address=0.0.0.0 

#dbms.connector.https.enabled=true 

#dbms.connector.https.listen_address=:7473

#dbms.connector.bolt.listen_address=:7687

Schließlich startest du dann noch den Service von Neo4j mit dem unten aufgeführten Kommando.


service neo4j start

Getting started mit Neo4j Browser

Sobald du die Installation und die Anpassungen in der Konfigurationsdatei abgeschlossen hast, sollte es dir möglich sein, den Datenbank-Server zu erreichen, indem du die URL http://localhost:7474/browser/ in deinem Browser aufrufst, wobei du localhost mit der IP-Adresse deines Servers austauschen musst.

Sollte Neo4j Browser danach nicht abrufbar sein, dann führe in deiner Konsole die beiden unten eingeblendeten Befehle aus und versuche es im Anschluss erneut via URL in deinem Browser.


service neo4j stop

service neo4j start

Neo4j Browser ist ein Kommando-gesteuerter Client, der wie eine webbasierte Shell-Umgebung funktioniert. Hier kannst du u.a. Graph-Abfragen mit der Datenbanksprache Cypher schreiben und ausführen, oder dir die Tabellen eines bestimmten Abfrageergebnisses exportieren lassen oder die REST API von Neo4j praktisch erkunden.

Nach erfolgreicher Umsetzung, wirst du auf die Anmeldeseite von Neo4j weitergeleitet, was du dem Screenshot unten entnehmen kannst. Hier wirst du neben dem Host nach dem Usernamen und dem Passwort gefragt. Der Host ist bolt://localhost:7687. Auch hier musst du localhost mit der IP-Adresse deines Servers austauschen, falls dies nicht per default schon beim Aufrufen der Seite im Browser korrekt für das betreffende Eingabefeld generiert wurde. Auch ist bereits ein default-Username generiert worden, wie du erkennst. Es ist dir noch nicht möglich, dich mit einem von dir gewählten Passwort anzumelden. Zunächst musst du ein Passwort erstellen. Hierzu meldest du dich erst einmal unter dem default-Username und dem default-Passwort in der Datenbank-Plattform an. Das default-Passwort entspricht dem default-Username. In beiden Fällen ist es neo4j.

Anmeldeseite zur Nutzung des Neo4j Browser

Daraufhin gelangst du auf eine Seite, auf der du die Möglichkeit hast, dein Passwort zu erstellen und dieses durch erneute Eingabe sicherzustellen.

Passwort auf der Anmeldeseite zur Nutzung des Neo4j Browser neu setzen

Mit Klick auf den Change password-Button bestätigst du das Passwort und gelangst auf die Hauptseite von Neo4j.

Hauptseite im Neo4j Browser

Durch Klick auf den grünen Neo4j Browser Sync-Button oder den obersten Menüpunkt (rotes Cloud-Icon) in der unteren Hälfte der links eingeblendeten Menüleiste, wird direkt neben der Menüleiste eine Schaltfläche eingeblendet, in der du eine Checkmark-Box ankreuzen und im Anschluss daran den Sign in/Register-Button betätigen kannst, um die Neo4j Browser-Synchronisation durchzuführen.

Schaltfläche für die Neo4j Browser Synchronisation

Wenn diese aktiv ist, ist das Cloud-Icon in der Menüleiste bei MouseOver-Effekt oder bei Betätigung nicht mehr rot, sondern grün und du kannst Neo4j Browser im vollen Umfang nutzen. Du kannst das Cloud-Icon jederzeit klicken, um die Einstellungen dahingehend zu ändern, dass du nach Belieben die Browser-Synchronisation ausschaltest oder einschaltest. Hierzu bietet der Sign-Out-Button in der eingeblendeten Schaltfläche direkt neben der Menüleiste analog zum Sign in/Register-Button die Möglichkeit. Ist die Browser-Synchronisation aktiv, ist es dir jederzeit möglich lokale Daten zu löschen, indem du den Clear local data-Button nutzt.

Aktivierte Neo4j Browser Synchronisation

Wenn du das ebenfalls in der Menüleiste befindliche Zahnrad-Icon betätigst, wird eine Schaltfläche eingeblendet, in der du die Browser-Settings ändern kannst.

Neo4j Browser Settings

Wie dir der Screenshot unten präsentiert, bietet dir der letzte Menüpunkt in der Menüleiste formale Informationen zu Neo4j, wie über die Lizenz und über die auf deinem Server laufende Version.

About Neo4j

Der dritte Menüpunkt (Dokument-Icon) in der oberen Hälfte der Menüleiste bietet dir in der ausgeklappten Schaltfläche eine Reihe von unterstützenden Links, die dir den Einstieg in die Nutzung von Neo4j und die Datenbanksprache Cypher erleichtern. Die Links sind grob in zwei Arten zu unterscheiden. Wie dir der Screenshot unten vor Auge führt, gibt es dort Links, vor denen ein Pfeil- oder Fragezeichen-Icon platziert ist, und welche, bei denen dies nicht der Fall ist. Bei letzteren handelt es sich um externe Links, die sich in der Sparte Useful Resources befinden und zu weiterführenden Informationen und Handbüchern führen. Hierfür öffnet sich dann ein neues Browser-Fenster.
Bei der ersteren Kategorie von genannten Links handelt es sich eher um Button-Typen, die bei Betätigung ein Kommando in die von Neo4j mitgelieferte Kommandozeile generieren. Wenn du daraufhin in die Kommandozeile klickst und die Enter-Taste betätigst, lässt sich das generierte Kommando ausführen. Hinter dem jeweiligen generierten Kommando steht dann ein in Neo4j integriertes Tutorial, dass dir das hinter dem angeklickten Button stehende Thema Step-by-Step nahe bringt. So kannst du z.B. Graph-Szenarien anhand einer vorgegebenen Anleitung nachsimulieren oder beispielhaft Queries auf Basis der Sprache Cypher nachempfinden und ein Gefühl dafür bekommen, welche Art von Projekt geeignet ist und wie du dieses mit Neo4j umsetzen kannst.
Im Screenshot unten habe ich beispielhaft den Button Basic graph concepts angeklickt und damit das Kommando :play concepts in der Kommandozeile generiert.

Documents-Schaltfläche im Neo4j Browser

Daraufhin wird – wie im Screenshot unten abgebildet – das Tutorial Graph Fundamentals eingeblendet, das Step-by-Step durchgearbeitet werden kann.

Generierung eines Tutorials Neo4j im Browser über die Documents-Schaltfläche

Die Kommandozeile dient quasi als Editor und ist die primäre Schnittstelle zum Eingeben und Ausführen von Befehlen. Hier gibst du schließlich dann auch Cypher-Abfragen ein, um mit Diagrammdaten zu arbeiten. Du kannst die Kommandozeile entweder für die einzeilige Bearbeitung nutzen, wenn sich dein Anliegen mittels kurzen Abfragen oder Befehlen umsetzen lässt. Oder du nutzt die Kommandozeile zur mehrzeiligen Bearbeitung, indem du mit der Tastenkombination Shift+Enter Zeilen hinzufügst. Eine Abfrage führst du dann mit der Tastenkombination Strg+Enter aus. Vergangene Abfragen lassen sich jederzeit wieder abrufen, da diese in der unterhalb der Kommandozeile befindlichen Historie behalten lassen, solange du diese nicht löscht.

Einen Graphen erstellen

Da sich ein Graph aus Knoten und Beziehungen zusammensetzt, müssen diese zunächst via Kommandozeile angelegt werden, um sich den Graphen im Neo4j Browser schließlich ausgeben lassen zu können. Hierzu dient das aus SQL bekannte CREATE-Statement, wobei die Syntax letztlich durch Cypher definiert ist.

Wie die Syntax des CREATE-Statements in Cypher aussieht, entnimmst du dem Code-Snippet unten.


CREATE (identifier:label {property1:value1, property2:value2 ...})

Da ein Graph erst aus mindestens einer Beziehung heraus entstehen kann und letztlich eine Beziehung im Graphen mindestens zwei in einer Relation zueinander stehende Knoten bedingt, müssen via CREATE-Statement mindestens zwei Identifier ein und demselben Label zugeordnet werden und entsprechend die Beziehung zwischen den Elementen via spezieller Syntax definiert werden.

Anstelle jedes neue Element und jede neue Beziehung zwischen Elementen via CREATE-Statement zu implementieren, ist es möglich, eine Reihe von Elementen eines Labels und deren Beziehungen zueinander in einem einzelnen CREATE-Statement an die Datenbasis weiterzureichen.

Die Syntax eines vollständigen CREATE-Statements würde dem Inhalt gleichen, der dir im folgenden Code-Block präsentiert wird. Die Syntax sieht es vor, dass für jedes neue Element einer Entität, eine selbst gewählte Identifier-Bezeichnung gewählt und der hinter der Entität stehenden Label-Bezeichnung zugewiesen wird. Bei allen Elementen des Labels ist die Bezeichnung des Labels dieselbe, lediglich die Identifier-Bezeichnung ändert sich, damit die Elemente in der Datenbasis differenzierbar sind. Jedem Element kann eine beliebige Anzahl an Eigenschaften mittels Property-Value-Paaren zugeschrieben werden. Im Code-Block unten habe ich beispielhaft fünf Elemente implementiert, die teilweise jeweils über eine unterschiedliche Anzahl an Property-Value-Paaren verfügen. Unterhalb der Syntax zur Definition der Elemente eines Labels entnimmst du die Syntax, die notwendig ist, um Relationen zwischen den Elementen herzustellen. Hierbei sind pro Relation, die beiden an der betreffenden Relation teilnehmenden Identifier, in runde Klammern gesetzt und der Name der Relation befindet sich in eckigen Klammern und wird mit einem Doppelpunkt eingeleitet. Eine Relation kann variabel mit einer zusätzlichen Menge an Attribut-Wert-Paaren versehen werden.

Schließlich dient das RETURN-Statement, um sich die implementierten Informationen ausgeben zu lassen.


CREATE (identifier1:label {property1:value1, property2:value2}),
(identifier2:label {property1:value1}),
(identifier3:label {property1:value1, property2:value2}),
(identifier4:label {property1:value1, property2:value2, property3:value3}),
(identifier5:label {property1:value1, property2:value2}),

(identifier1)-[:RELATION {attribute1:value1}]->(identifier2),
(identifier1)-[:RELATION]->(identifier3),
(identifier2)-[:RELATION]->(identifier3),
(identifier2)-[:RELATION]->(identifier4),
(identifier3)-[:RELATION]->(identifier2),
(identifier3)-[:RELATION]->(identifier5),
(identifier4)-[:RELATION]->(identifier5)

RETURN identifier1, identifier2, identifier3, identifier4, identifier5

Eine Query wird mittels dem Stichwort MATCH eingeleitet. MATCH fungiert analog dem aus SQL bekannten SELECT. Der folgenden Code-Snippet verdeutlicht dir, wie sich die Syntax hierbei zusammensetzt. Nach dem Stichwort MATCH wird im Sinne eines pattern ausgedrückt, was gesucht wird. Nach dem Stichwort WHERE wird im Sinne von conditions eine oder mehrer Bedingung gesetzt, falls notwendig. Somit ist der WHERE-Bestandteil der Anfrage wie auch die WHERE-Klausel beim SQL-SELECT-Statement variabel. Wie im Code-Snippet oben, dient auch bei einer Query das RETURN dazu, eine Reihe von Elementen anzusprechen, auf die sich die Ausgabe der Ergebnisse beziehen soll. Hier werden ebenfalls die Identifier aufgerufen. Wenn man einen Identifier in Kombination in Bezug auf bestimmte Properties ausgeben lassen möchte und nicht mit allen seinen Eigenschaften, ruft man bei RETURN den betreffenden Identifier in Kombination mit der entsprechenden Property – getrennt mit einem Punkt – auf. Mit Bezug auf den unten eingeblendeten Code-Snippet würde dies im expressions-Platzhalter passieren.


MATCH pattern WHERE conditions RETURN expressions

Das im Code-Snippet oben integrierte pattern kann entweder ein Element z.B. nach dem Schema (identifier:label) enthalten oder eine komplette Relation z.B. nach dem Schema (identifier:label)-[:RELATION]->(identifier:label).
Im conditions-Platzhalter können dann eine oder mehrere Bedingung(en) nach dem Schema identifier.property = value gesetzt werden, um die Ergebnismenge der Query zu spezifizieren. Mittels den Booleschen Operatoren lassen sich mehrere Bedingungen dann je nach erforderlicher Logik miteinander verbinden.

Die Syntax von Cypher beinhaltet neben dem CREATE– und MATCH-Statement die Nutzung weiterer Statements. Hierzu bietet der Neo4j Browser, Tutorials, deren Kommandos via Klick auf die im Screenshot gehighlighteten Buttons in die Kommandozeile generiert werden und via Betätigung der Enter-Taste aufgerufen werden können.

Generierung von Tutorials zum Thema Syntax von Anfragen im Neo4j Browser über die Documents-Schaltfläche

Anknüpfend an das im Kapitel Anwendungsszenario beschriebene Szenario, werde ich dieses nun in den Neo4j Browser implementieren.
Der Graph soll via der Relation PROVIDES zeigen, welche Studiengänge die betreffende Universität anbietet und mittels einer weiteren Relation, nämlich der Relation IS_SIMILAR_WITH, soll demonstriert werden, welche Studiengänge ähnliche Inhalte haben. Der Graph bildet zwei Entitäten/Labels ab, bzw. Elemente dieser zwei Entitäten. Zum einen gibt es Elemente der Entität University und zum anderen gibt es Elemente der Entität StudiesCourse.
Der unten abgebildete Code-Block reflektiert, wie das CREATE-Statement für mein Beispiel zum Anwendungsszenario aussieht. Den Code kannst du via Copy&Paste in die Kommandozeile des Neo4j Browsers implementieren und mit der Tastenkombination Strg+Enter ausführen.


CREATE
(university_cologne:University {name: "University of Cologne", location: "Cologne"}),
(university_dusseldorf:University {name: "Heinrich Heine University", location: "Dusseldorf"}),

(ancient_culture:StudiesCourse {name: "Ancient Culture"}),
(ancient_languages_culture:StudiesCourse {name: "Ancient languages and cultures"}),
(archeology:StudiesCourse {name: "Archeology"}),
(art:StudiesCourse {name: "Art"}),
(art_history:StudiesCourse {name: "Art History"}),
(biochemistry:StudiesCourse {name: "Biochemistry"}),
(biology:StudiesCourse {name: "Biology"}),
(chemistry:StudiesCourse {name: "Chemistry"}),
(china_studies:StudiesCourse {name: "China Studies"}),
(communication_media_studies:StudiesCourse {name: "Communication and media studies"}),
(computer_linguistics:StudiesCourse {name: "Computer Linguistics"}),
(computer_science:StudiesCourse {name: "Computer Science"}),
(earth_sciences:StudiesCourse {name: "Earth Sciences"}),
(economics:StudiesCourse {name: "Economics"}),
(educational_sciences:StudiesCourse {name: "Educational Sciences"}),
(english_studies:StudiesCourse {name: "English Studies"}),
(ethnology:StudiesCourse {name: "Ethnology"}),
(geography:StudiesCourse {name: "Geography"}),
(german_languages_literature:StudiesCourse {name: "German Languages and Literature"}),
(history:StudiesCourse {name: "History"}),
(information_processing:StudiesCourse {name: "Information Processing"}),
(information_science:StudiesCourse {name: "Information Science"}),
(intermedia:StudiesCourse {name: "Intermedia"}),
(japanese_culture_pp:StudiesCourse {name: "Japanese Culture in Past and Present"}),
(japanese_studies:StudiesCourse {name: "Japanese Studies"}),
(law:StudiesCourse {name: "Law"}),
(linguistics:StudiesCourse {name: "Linguistics"}),
(literary_translation:StudiesCourse {name: "Literary Translation"}),
(mathematics:StudiesCourse {name: "Mathematics"}),
(media_culture_studies:StudiesCourse {name: "Media and Culture Studies"}),
(media_studies:StudiesCourse {name: "Media Studies"}),
(medicine:StudiesCourse {name: "Medicine"}),
(pedagogy:StudiesCourse {name: "Pedagogy"}),
(pharmacy:StudiesCourse {name: "Pharmacy"}),
(philosophy:StudiesCourse {name: "Philosophy"}),
(physics:StudiesCourse {name: "Physics"}),
(political_economy:StudiesCourse {name: "Political Economy"}),
(political_science:StudiesCourse {name: "Political Science"}),
(politics:StudiesCourse {name: "Politics"}),
(psychology:StudiesCourse {name: "Psychology"}),
(romance_languages_literature:StudiesCourse {name: "Romance Languages and Literature"}),
(yiddish_cll:StudiesCourse {name: "Yiddish Culture, Language and Literature"}),
(social_sciences_ssdg:StudiesCourse {name: "Social Sciences – Social Structures and Democratic Governance"}),
(sociology:StudiesCourse {name: "Sociology"}),

(university_dusseldorf)-[:PROVIDES]->(ancient_culture),
(university_dusseldorf)-[:PROVIDES]->(art_history),
(university_dusseldorf)-[:PROVIDES]->(biochemistry),
(university_dusseldorf)-[:PROVIDES]->(biology),
(university_dusseldorf)-[:PROVIDES]->(chemistry),
(university_dusseldorf)-[:PROVIDES]->(communication_media_studies),
(university_dusseldorf)-[:PROVIDES]->(computer_linguistics),
(university_dusseldorf)-[:PROVIDES]->(computer_science),
(university_dusseldorf)-[:PROVIDES]->(economics),
(university_dusseldorf)-[:PROVIDES]->(german_languages_literature),
(university_dusseldorf)-[:PROVIDES]->(history),
(university_dusseldorf)-[:PROVIDES]->(information_science),
(university_dusseldorf)-[:PROVIDES]->(japanese_studies),
(university_dusseldorf)-[:PROVIDES]->(law),
(university_dusseldorf)-[:PROVIDES]->(linguistics),
(university_dusseldorf)-[:PROVIDES]->(literary_translation),
(university_dusseldorf)-[:PROVIDES]->(mathematics),
(university_dusseldorf)-[:PROVIDES]->(media_culture_studies),
(university_dusseldorf)-[:PROVIDES]->(medicine),
(university_dusseldorf)-[:PROVIDES]->(pharmacy),
(university_dusseldorf)-[:PROVIDES]->(philosophy),
(university_dusseldorf)-[:PROVIDES]->(physics),
(university_dusseldorf)-[:PROVIDES]->(political_economy),
(university_dusseldorf)-[:PROVIDES]->(political_science),
(university_dusseldorf)-[:PROVIDES]->(psychology),
(university_dusseldorf)-[:PROVIDES]->(romance_languages_literature),
(university_dusseldorf)-[:PROVIDES]->(yiddish_cll),
(university_dusseldorf)-[:PROVIDES]->(social_sciences_ssdg),
(university_dusseldorf)-[:PROVIDES]->(sociology),

(university_cologne)-[:PROVIDES]->(ancient_languages_culture),
(university_cologne)-[:PROVIDES]->(archeology),
(university_cologne)-[:PROVIDES]->(art),
(university_cologne)-[:PROVIDES]->(art_history),
(university_cologne)-[:PROVIDES]->(biochemistry),
(university_cologne)-[:PROVIDES]->(biology),
(university_cologne)-[:PROVIDES]->(chemistry),
(university_cologne)-[:PROVIDES]->(china_studies),
(university_cologne)-[:PROVIDES]->(earth_sciences),
(university_cologne)-[:PROVIDES]->(economics),
(university_cologne)-[:PROVIDES]->(educational_sciences),
(university_cologne)-[:PROVIDES]->(english_studies),
(university_cologne)-[:PROVIDES]->(ethnology),
(university_cologne)-[:PROVIDES]->(geography),
(university_cologne)-[:PROVIDES]->(german_languages_literature),
(university_cologne)-[:PROVIDES]->(history),
(university_cologne)-[:PROVIDES]->(information_processing),
(university_cologne)-[:PROVIDES]->(intermedia),
(university_cologne)-[:PROVIDES]->(japanese_culture_pp),
(university_cologne)-[:PROVIDES]->(law),
(university_cologne)-[:PROVIDES]->(mathematics),
(university_cologne)-[:PROVIDES]->(media_culture_studies),
(university_cologne)-[:PROVIDES]->(media_studies),
(university_cologne)-[:PROVIDES]->(medicine),
(university_cologne)-[:PROVIDES]->(pedagogy),
(university_cologne)-[:PROVIDES]->(philosophy),
(university_cologne)-[:PROVIDES]->(physics),
(university_cologne)-[:PROVIDES]->(politics),
(university_cologne)-[:PROVIDES]->(psychology),

(ancient_culture)-[:IS_SIMILAR_WITH]->(ancient_languages_culture),
(ancient_languages_culture)-[:IS_SIMILAR_WITH]->(ancient_culture),
(art)-[:IS_SIMILAR_WITH]->(art_history),
(art_history)-[:IS_SIMILAR_WITH]->(art),
(biochemistry)-[:IS_SIMILAR_WITH]->(biology),
(biochemistry)-[:IS_SIMILAR_WITH]->(chemistry),
(biology)-[:IS_SIMILAR_WITH]->(biochemistry),
(chemistry)-[:IS_SIMILAR_WITH]->(biochemistry),
(communication_media_studies)-[:IS_SIMILAR_WITH]->(media_culture_studies),
(communication_media_studies)-[:IS_SIMILAR_WITH]->(intermedia),
(communication_media_studies)-[:IS_SIMILAR_WITH]->(media_studies),
(media_culture_studies)-[:IS_SIMILAR_WITH]->(communication_media_studies),
(media_culture_studies)-[:IS_SIMILAR_WITH]->(intermedia),
(media_culture_studies)-[:IS_SIMILAR_WITH]->(media_studies),
(intermedia)-[:IS_SIMILAR_WITH]->(communication_media_studies),
(intermedia)-[:IS_SIMILAR_WITH]->(media_culture_studies),
(intermedia)-[:IS_SIMILAR_WITH]->(media_studies),
(media_studies)-[:IS_SIMILAR_WITH]->(communication_media_studies),
(media_studies)-[:IS_SIMILAR_WITH]->(media_culture_studies),
(media_studies)-[:IS_SIMILAR_WITH]->(intermedia),
(computer_linguistics)-[:IS_SIMILAR_WITH]->(computer_science),
(computer_linguistics)-[:IS_SIMILAR_WITH]->(information_science),
(computer_linguistics)-[:IS_SIMILAR_WITH]->(information_processing),
(computer_science)-[:IS_SIMILAR_WITH]->(computer_linguistics),
(computer_science)-[:IS_SIMILAR_WITH]->(information_science),
(computer_science)-[:IS_SIMILAR_WITH]->(information_processing),
(information_science)-[:IS_SIMILAR_WITH]->(computer_linguistics),
(information_science)-[:IS_SIMILAR_WITH]->(computer_science),
(information_science)-[:IS_SIMILAR_WITH]->(information_processing),
(information_processing)-[:IS_SIMILAR_WITH]->(computer_linguistics),
(information_processing)-[:IS_SIMILAR_WITH]->(computer_science),
(information_processing)-[:IS_SIMILAR_WITH]->(information_science),
(politics)-[:IS_SIMILAR_WITH]->(political_economy),
(political_economy)-[:IS_SIMILAR_WITH]->(politics),
(politics)-[:IS_SIMILAR_WITH]->(political_science),
(political_science)-[:IS_SIMILAR_WITH]->(politics)

RETURN university_dusseldorf, university_cologne, ancient_culture, ancient_languages_culture, archeology, art, art_history, biochemistry, biology, chemistry, china_studies, communication_media_studies, computer_linguistics, computer_science, earth_sciences, economics, educational_sciences, english_studies, ethnology, geography, german_languages_literature, history, information_processing, information_science, intermedia, japanese_culture_pp, japanese_studies, law, linguistics, literary_translation, mathematics, media_culture_studies, media_studies, medicine, pedagogy, pharmacy, philosophy, physics, political_economy, political_science, politics, psychology, romance_languages_literature, yiddish_cll, social_sciences_ssdg, sociology

Nach der Ausführung, wird das Output in einem hierfür generierten Frame auf vier Weisen zur Verfügung gestellt, die du via der zur linken Seite des Frames eingeblendeten Leiste erreichst, wie du dem Screenshot unten entnimmst. Hier kannst du dir das Output entweder als Graphen, im Tabellen- oder Textformat oder als Quellcode anzeigen lassen. Zusätzlich bieten sechs Werkzeug-Icons die Möglichkeit, mit dem betreffenden Output-Format in Interaktion zu treten. Diese Icons befinden sich oben rechts im Output-Frame. Via dem ersten Icon ist es dir möglich, das betreffende Output-Format entweder als .png oder.svg-Datei auf deinen Rechner zu exportieren. Des Weiteren kannst du die Icons u.a. nutzen, um den Output-Frame zu pinnen, das Fenster des Frames zu expandieren, neu zu laden oder zu löschen.

Graph im Neo4j Browser

Der Screenshot unten verbildlicht dir, wie die Export-Datei dann aussehen würde. Falls die Knoten im Output-Frame unvorteilhaft zusammengewürfelt sind, sodass man nicht mehr durchblickt, kannst du die Knoten via Drag&Drop bewegen und an eine vorteilhaftere Stelle navigieren.

Aus Neo4j Browser exportierter Graph

Alternativ zum RETURN im oben gezeigten Code-Block, hätte das RETURN auch so aussehen können, wie im unten eingeblendeten Code-Snippet. Dann wären jedoch zunächst lediglich die Knoten/Elemente zur Entität University abgebildet worden und erst mit Doppelklick auf den betreffende Knoten wären die Knoten/Elemente der Entität StudiesCourse mit in das Output generiert worden.


RETURN university_dusseldorf, university_cologne

Wenn du das erste Icon (Datenbank-Icon) in der linken Menüleiste des Neo4j Browsers aufrufst, hast du einen guten Überblick über die im Neo4j Browser verwendeten Knoten-Label, sowie die Relationen und die Identifier der Eigenschaften.

Database Information-Schaltfläche im Neo4j Browser

Via Klick auf das zweite Icon (Stern-Icon) in der linken Menüleiste, wird eine Schaltfläche generiert, in der du entweder die Möglichkeit hast, Dateien mit vorgefertigten Datenbank-Statements hochzuladen und diese in von dir angelegten Ordnern für einen jederzeit verfügbaren Zugriff abzuspeichern oder default-Beispiel-Skripte aufzurufen und dir diese in der Kommandozeile ausführen zu lassen, um zu sehen, was daraufhin passiert.

Favorites-Schaltfläche im Neo4j Browser

Fazit

Es hat mir Freude gemacht, dir bei der Installation und Einrichtung von Neo4j zu helfen und dir die Datenbank nahe zu bringen. Du hast Neo4j als eine moderne Datenbankplattform kennen gelernt, die es dir ermöglicht, interaktiv im Browser via Datenbanksprache Cypher Projekte anzulegen, Queries zu stellen, Graphen zu bestimmten Projekten zu erzeugen und diese zu exportieren und in der Datenbank jederzeit wieder auffindbar zu machen. Ich wünsche dir viel Erfolg und Spaß bei der Umsetzung deiner Ideen.

Aus unserer Rubrik zu Open Source Datenbanken und Datenbank-Plattformen auch noch interessant und hilfreich:

Zurück zur Tutorial Übersicht Back to Tutorial Overview

ArangoDB unter Ubuntu 16.04 installieren und einrichten

ArangoDB unter Ubuntu

Nachdem wir dir in unseren Tutorials zu den Themen MySQL Datenbank erstellen und löschen, PostgreSQL 10 auf Ubuntu 16.04 / 14.04 installieren, MongoDB auf Ubuntu installieren, Apache Cassandra auf Ubuntu installieren, Redis auf Ubuntu 16.04 LTS installieren und RethinkDB auf Ubuntu installieren eine unterstützende Anleitung zur Installation und Einrichtung einer Reihe von SQL- und NoSQL-Datenbanken unter Ubuntu bereitgestellt haben und sich unsere beiden Tutorials zu den Themen InfluxDB unter Ubuntu 16.04/18.04 installieren und einrichten sowie Neo4j unter Ubuntu 16.04/18.04 installieren und einrichten zwei weiteren NoSQL-Datenbank-Plattformen widmen, werde ich nun die Sammlung ergänzen und dir die NoSQL-Datenbank-Plattform ArangoDB vorstellen.

Zu ArangoDB

ArangoDB stellt Nutzern die Möglichkeit bereit, Dokumente im JSON-Format zu speichern und abzurufen. Ein Dokument ist ein Objekt. Innerhalb eines Dokuments befinden sich entweder keine oder eine Menge von Attributen mit Werten. Analog zum Konzept Datenbank werden auch bei ArangoDB solche Werte von Attributen durch Datentypen wie Zeichenketten, Zahlen oder Boolean transportiert. Im Unterschied zum konventionellen Modell einer Datenbank, existieren in ArangoDB nicht nur Werte im Sinne atomarer Typen, sondern auch zusammengesetzter Typen. Ein zusammengesetzter Typ kann ein Array oder ein eingebettetes Dokument sein. Es lassen sich somit pro Dokument verschachtelte Datenstrukturen konstruieren und abbilden.

Mit Hilfe von Connections können Dokumente gruppiert und somit voneinander differenziert werden. Eine Collection enthält entweder keins oder eine Menge von Dokumenten und kann somit als Sammlung von JSON-Objekten eines Clusters genutzt werden. Verglichen mit dem Modell der relationalen Datenbank, kann man eine Collection mit einer Tabelle gleichstellen und Dokumente kämen Zeilen innerhalb solch einer Tabelle nah. Wenn man in einer traditionellen Datenbank Datensätze in einer Tabelle hinzufügen möchte, ist die Voraussetzung hierfür, zuvor Spalten zu definieren. Das Konstrukt Tabelle in einer traditionellen Datenbank setzt sich sozusagen aus Schemen zusammen, die beim Anlegen einer Tabelle implementiert werden. In ArangoDB muss hingegen nicht definiert werden, welche Attribute ein Dokument haben kann. In ein und derselben Sammlung von Dokumenten können unterschiedliche Datenstrukturen herrschen.

Es ist aber nicht nur möglich Dokument-Collections zu erstellen, sondern auch Collections von Kanten, sogenannten Edges-Collections. Dokumente können dann in solch einer Sammlung von Kanten gespeichert werden. Diese Art von Collection enthält dann die beiden speziellen Attribute _from und _to, mit denen sich die Relationen zwischen Objekten – also den Dokumenten – herstellen lassen.

Genau genommen können Collections von Kanten zwischen Dokumenten in Dokument-Collections Zusammenhänge herstellen. Ein Dokument, das sich in einer Kanten-Collection befindet, bildet sozusagen die Schnittstelle zwischen zwei Dokumenten, die sich in Dokument-Collections befinden und bringt diese beiden sozusagen in eine Beziehung zueinander. Diese Relation folgt dem mathematischen Prinzip eines gerichteten, beschrifteten Graphen. Das die Relation definierende Dokument der Edge-Collection ist in diesem Graphen die beschriftete Kante.

Anwendungsszenario

ArangoDB ist ein natives Multi-Modell-Datenbanksystem, das von der triAGENS GmbH entwickelt und im Jahr 2011 released wurde. Es ist als Multi-Modell-Datenbanksystem zu verstehen, da ArangoDB drei wichtige Datenmodelle unterstützt, nämlich das Modell einer Schlüssel/Wert-Datenbank, sowie einer Dokumentendatenbank als auch einer Graph-Datenbank. ArangoDB vereint diese drei Modelle in einem Datenbankkern und einer einheitlichen Abfragesprache AQL (ArangoDB Query Language). Das bedeutet, dass Schlüssel-/Wert-, Dokument- und Graphendaten unter ein und derselben Sprache zusammen gespeichert und abgefragt werden können.

AQL ist SQL sehr ähnlich, obwohl ArangoDB eine NoSQL-Datenbank ist. AQL ist deklarativ und ermöglicht die Kombination verschiedener Zugriffsmuster von Daten in einer einzigen Abfrage.

Mit ArangoDB ist es möglich skalierbare, hocheffiziente Abfragen bei der Arbeit mit Graph-Daten durchzuführen. Als Standard-Speicherformat wird JSON verwendet.

Ich werde ArangoDB dazu nutzen, einen kleinen Ausschnitt einer Folksonomy durch einen Graphen abbildbar zu machen. Eine Folksonomy is gemeinschaftliches Tagging von Inhalten und findet im Internet statt. Flickr ist ein Beispiel für eine Folksonomy. Dort können Bilder von Nutzern mit Schlagwörtern versehen und somit indexiert und wiederauffindbar gemacht werden. Auch in meinem realisierten Anwendungsszenario soll es um eine digitale Foto-Sharing-Plattform gehen, wo Nutzer Bilder verschlagworten. Der Graph soll am Ende visuell transportieren welche Schlagworte von welchen Nutzern zu welchen Inhalten (Bildern/Fotos) vergeben wurden.

ArangoDB installieren

Zu Beginn solltest du sicherstellen, dass dein Server up-to-date ist.


apt-get update -y && apt-get upgrade -y

Dann musst du den Public-Key von der ArangoDB-Site downloaden, um im Anschluss das ArangoDB-Repository einrichten zu können. Führe den folgenden Befehl aus, um den Public-Key herunterzuladen.


wget https://www.arangodb.com/repositories/arangodb3/xUbuntu_16.04/Release.key

Füge den Key dann mittels dem folgenden Kommando hinzu.


apt-key add Release.key

Bei Ubuntu stehen die Repositories in /etc/apt/sources.list. Als nächstes musst du das Repository von ArangoDB zu sources.list hinzufügen und erneut ein Update des Servers durchführen.


apt-add-repository 'deb https://www.arangodb.com/repositories/arangodb3/xUbuntu_16.04/ /'

apt-get update

Die Installation von ArangoDB vollziehst du dann schließlich via dem folgenden Kommando.


apt-get install arangodb3

Nach dem Installationsprozess erscheint ein Widget, in dem du das root-Passwort festlegen kannst.

root-Passwort für ArangoDB festlegen

Überprüfe daraufhin den Status, indem du den untenstehenden Befehl ausführst.


systemctl status arangodb

Das Output sollte dann so aussehen, wobei server-X als Platzhalter für den Namen deines Servers zu interpretieren ist.


● arangodb3.service - LSB: arangodb
   Loaded: loaded (/etc/init.d/arangodb3; bad; vendor preset: enabled)
   Active: active (running) since Tue 2018-05-29 13:16:39 CEST; 2min 52s ago
     Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/arangodb3.service
           ├─26207 /usr/sbin/arangod --uid arangodb --gid arangodb --pid-file /var/run/arangodb/arangod.pid --temp.path /var/tmp/arangod --log.foreground-tty false -
           └─26208 /usr/sbin/arangod --uid arangodb --gid arangodb --pid-file /var/run/arangodb/arangod.pid --temp.path /var/tmp/arangod --log.foreground-tty false -

May 29 13:16:37 server-X systemd[1]: Starting LSB: arangodb...
May 29 13:16:37 server-X arangodb3[26150]:  * Starting arango database server arangod
May 29 13:16:39 server-X arangodb3[26150]: {startup} starting up in daemon mode
May 29 13:16:39 server-X arangodb3[26150]: changed working directory for child process to '/var/tmp'
May 29 13:16:39 server-X arangodb3[26150]:    ...done.
May 29 13:16:39 server-X systemd[1]: Started LSB: arangodb.

ArangoDB über die Shell einrichten

Mit dem Kommando arangosh bietet ArangoDB die Möglichkeit via Kommandozeilen-Shell mit der Datenbank zu interagieren. Du kannst mit diesem Client neue Datenbanken, Benutzer, Sammlungen, Dokumente erstellen und alle administrativen Aufgaben managen.

Du kannst diese Befehlszeilenschnittstelle starten, indem du den folgenden Befehl ausführst.


arangosh

Daraufhin wirst du bei erstmaligem Anmelden in der Datenbank nach dem root-Passwort gefragt, dass ich im vorherigen Kapitel bei der Installation erstellt habe. Denn zu dem Zeitpunkt existieren in der Datenbank noch keine Nutzer außer dem root-Nutzer. Nach erfolgreicher Verifizierung des Passworts, solltest du im Terminal das Output sehen, dass dir der Code-Snippet unten vor Augen führt.


                                       _     
  __ _ _ __ __ _ _ __   __ _  ___  ___| |__  
 / _` | '__/ _` | '_  / _` |/ _ / __| '_  
| (_| | | | (_| | | | | (_| | (_) __  | | |
 __,_|_|  __,_|_| |_|__, |___/|___/_| |_|
                       |___/                 

arangosh (ArangoDB 3.0.12 [linux] 64bit, using VPack 0.1.30, ICU 54.1, V8 5.0.71.39, OpenSSL 1.0.2g-fips  1 Mar 2016)
Copyright (c) ArangoDB GmbH

Pretty printing values.
Connected to ArangoDB 'http+tcp://127.0.0.1:8529' version: 3.0.12 [server], database: '_system', username: 'root'

Please note that a new minor version '3.3.9' is available
Type 'tutorial' for a tutorial or 'help' to see common examples

Solltest du Hilfe benötigen, kann dich dieser Befehl jederzeit weiter bringen.


db._help()

Datenbanken und Nutzer erstellen, managen und löschen

Im Folgenden werde ich dir Kommandos zeigen, mit denen sich Datenbanken und Nutzer managen lassen. Alles, was sich in den abgebildeten Code-Snippets zwischen zwei Rauten befindet, ist als Platzhalter zu verstehen. Das folgende Kommando liefert die Datenbank zurück, in der man sich gerade befindet.


require("internal").db._name()

Der Befehl unten gibt aus, ob die Datenbank, in der man sich gerade befindet, die _system-Datenbank ist. Rückgabewert ist dann der Boolean-Wert true oder false.


db._isSystem()

Eine Datenbank anlegen kann man mit dem folgenden Kommando.


db._createDatabase(#"name"#)

Der unten eingeblendete Befehl dient dazu, in eine bestimmte Datenbank zu wechseln.


db._useDatabase(#"name"#)

Eine bestimmte Datenbank löschen. Allerdings muss man diesen Befehl aus der _system-Datenbank heraus ausführen. Wenn man sich nämlich während dem Ausführen des Kommandos in der Datenbank befindet, die gelöscht werden soll, wird eine Exception geworfen.


db._dropDatabase(#"name"#)

Auch für die Auflistung der existierenden Datenbanken gibt es ein Kommando, welches sich allerdings ab einer bestimmten Version geändert hat und je nach genutzter Version zu einer Exception führen kann, wenn der Befehl nicht mit dieser kompatibel ist. Vor ArangoDB 3.0, konnte man sich die Datenbanken anzeigen lassen, indem man das unten stehenden Kommando ausführte.


db._listDatabases()

Seit ArangoDB 3.0 lautet das Kommando aber so:


db._databases()

Den Nutzer einer Datenbank anlegen. Hierzu muss man sich in der betreffenden Datenbank befinden. Es ist in ArangoDB nicht möglich, ein und demselben Nutzernamen mehreren Datenbanken zuzuordnen. Der Versuch wird als Duplizierung interpretiert und führt zu einer Exception.


require("org/arangodb/users").save(#"testuser"#, #"password"#)

Die Tatsache, dass ein Nutzer in einer Datenbank angelegt wurde, bedeutet aber nicht, dass dieser Berechtigungen für den Zugriff auf die betreffende Datenbank hat. Zugriffsrechte müssen zunächst gewährt werden. Hierzu würdest du den folgenden Befehl ausführen müssen.


require("org/arangodb/users").grantDatabase(#"testuser"#, #"_system"#)

Du hast die Möglichkeit für einen Nutzer den Zugriff auf eine Datenbank mittels dem unten eingeblendeten Kommando auch wieder aufzuheben.


require("org/arangodb/users").revokeDatabase(#"testuser"#, #"_system"#)

Wenn du einen Nutzer in der Datenbank beibehalten, aber sein Passwort ändern möchtest, dann wird dir dies mit Hilfe des folgenden Befehls möglich sein.


require("org/arangodb/users").update(#"testuser"#, #"new_password"#)

In ArangoDB kannst du dir nicht nur die Liste verfügbarer Datenbanken anzeigen lassen, sondern auch die in einer Datenbank befindlichen Nutzer. Um dies zu tun, müsstest du den folgenden Befehl ausführen.


require("org/arangodb/users").all()

Letztlich kann es immer mal vorkommen, dass du einen Nutzer aus einer Datenbank löschen möchtest. Dies würdest du via dem unten gezeigten Kommando umsetzen.


require("org/arangodb/users").remove(#"testuser"#)

Du kannst die Datenbank jederzeit mit dem unten im Code-Snippet eingeblendeten Befehl verlassen.


exit

Sobald neben dem root-User weitere Nutzer in der Datenbank existieren, ist es möglich sich in Kombination mit dem arangosh-Befehl direkt als solcher- und nicht als root-User, in der Datenbank anzumelden. So würdest du z.B. nach Eingabe des unten präsentierten Kommandos und erfolgreicher Verifizierung des daraufhin auf Anfrage eingegebenen Passworts, per default in der default-Datenbank _system unter dem Nutzer testuser angemeldet werden.


arangosh testuser

Ebenfalls ist es möglich, dass du direkt beim Aufruf der arangosh-Befehlszeilenschnittstelle, explizit eine bestimmte Datenbank antriggerst, in der du dich dann nach der Anmeldung befindest und dir somit das db._useDatabase-Kommando zum Wechsel in die betreffende Datenbank ersparst. Der Code-Snippet unten zeigt, wie das Kommando hierzu aussehen würde.


arangosh --server.database testDatabase

Auch die Kombination beider oben gezeigten Code-Snippets ist beim Aufruf der arangosh-Befehlszeilenschnittstelle möglich.


arangosh --server.database testDatabase testuser

Mit dem unten eingeblendeten Kommando kannst du einer Datenbank eine Collection hinzufügen. Der Befehl enthält nicht die Zuordnung zur betreffenden Datenbank, in der die Collection implementiert werden soll. Denn die Zuordnung zwischen Collection(s) und Datenbank wird dadurch bestimmt, dass man, bevor man die Collection(s) anlegt, in die entsprechende Datenbank via dem im vorherigen Kapitel gezeigten db._useDatabase-Kommando wechseln muss. Der properties-Parameter, sowie der type– als auch der options-Parameter sind optional, müssen also nicht gesetzt werden. Sie sind im unten abgebildeten Code-Snippet daher in eckige Klammern gesetzt. Der properties-Parameter ist ein Objekt mit Attributen, hinter denen Werte stehen. Jeder der verfügbaren Werte enthält einen default-Wert, der automatisch zugewiesen wird, wenn man den properties-Parameter in der Anfrage nicht selbst bestimmt. Auch der type-Parameter wird per default gesetzt. Der default-Wert hierbei ist immer document. Der type-Parameter kann auch lediglich document oder edge sein. Wenn man eine Collection vom Typ Edge anlegen möchte, ohne den type-Parameter zu setzen, müsste der db._create-Befehl db._createEdgeCollection lauten, was ich in einem der folgenden Code-Snippets auch vorführe.
Eine Übersicht zu den Attributen des properties– und des options-Parameters, Erklärungen zu deren Werten, sowie Beispiele zu deren Einbindung in ein Kommando zur Implementierung einer Collection, findest du in der Dokumentation von ArangoDB.


db._create(#"collection-name"# [, #properties#, #type#, #options#])

Im Code-Block unten erkennst du, dass ich beispielhaft die Collection testCollection1 angelegt habe und daraufhin im Output u.a. die Information zum Identifier (siehe: 578657) angezeigt wird. Eine neu implementierte Collection ist immer vom Typ Dokument (siehe: type document). Ich habe zusätzlich die beiden weiteren Collections testCollection2 und testCollection3 implementiert. Diese drei Collections habe ich in der _system-Datenbank erzeugt.


_system> db._create("testCollection")
[ArangoCollection 578657, "testCollection1" (type document, status loaded)]

Das Abrufen einer Collection ist nun entweder über ihren Namen oder den zu ihr gehörenden Identifier möglich, wie in den beiden folgenden Code-Snippets präsentiert.


db._collection(#"collection-name"#)

db._collection(#collection-identifier#)

Der Befehl für das Anlegen einer neuen Edge-Collection, erfolgt analog dem für das Erzeugen einer Collection.


db._createEdgeCollection(#"edge-collection-name"#)

Im unten eingeblendeten Code-Snippet zeige ich, wie ich die Edge-Collection namens testEdgeCollectionA in der _system-Datenbank implementiere. Am Output des Befehls erkennst du, dass – wie im Fall der Erzeugung einer Collection – auch hier u.a. die Information zum Identifier (Identifier =585224) vorliegt. Anders als im Fall einer Collection, ist bei einer neu angelegten Edge-Collection der Typ kein Dokument, sondern eine Kante (siehe: type edge).


_system> db._createEdgeCollection("testEdgeCollectionA")
[ArangoCollection 585224, "testEdgeCollectionA" (type edge, status loaded)]

Alle Collections einer Datenbank kannst du dir via dem folgenden Befehl anzeigen lassen. Das Output hängt dann davon ab, in welcher Datenbank du dich während der Anfrage befindest.


db._collections()

Auf Basis der bisher in diesem Tutorial gezeigten Implementierungen, sähe das Output für die db._collections()-Anfrage – ausgehend aus der _system-Datenbank – folglich so aus, wie im Code-Block unten vorgeführt. Hier erkennst du, dass dort nun – neben den per default in der Datenbank existierenden Collections – die Collections testCollection1, testCollection2 und testCollection3, sowie die Edge-Collection testEdgeCollectionA verfügbar sind.


_system> db._collections()
[ 
  [ArangoCollection 585224, "testEdgeCollectionA" (type edge, status loaded)], 
  [ArangoCollection 578706, "testCollection3" (type document, status loaded)], 
  [ArangoCollection 578704, "testCollection2" (type document, status loaded)], 
  [ArangoCollection 578657, "testCollection1" (type document, status loaded)], 
  [ArangoCollection 184143, "_fishbowl" (type document, status loaded)], 
  [ArangoCollection 50, "_statistics15" (type document, status loaded)], 
  [ArangoCollection 7, "_users" (type document, status loaded)], 
  [ArangoCollection 40, "_statisticsRaw" (type document, status loaded)], 
  [ArangoCollection 55, "_frontend" (type document, status loaded)], 
  [ArangoCollection 22, "_modules" (type document, status loaded)], 
  [ArangoCollection 45, "_statistics" (type document, status loaded)], 
  [ArangoCollection 59, "_jobs" (type document, status loaded)], 
  [ArangoCollection 57, "_queues" (type document, status loaded)], 
  [ArangoCollection 38, "_aqlfunctions" (type document, status unloaded)], 
  [ArangoCollection 61, "_apps" (type document, status loaded)], 
  [ArangoCollection 2, "_graphs" (type document, status loaded)], 
  [ArangoCollection 25, "_routing" (type document, status loaded)] 
]

Würde man denselben Befehl in der im vorherigen Kapitel angelegten testDatabase-Datenbank ausführen, wären dem Output lediglich die per default integrierten Collections zu entnehmen.


testDatabase> db._collections()
[ 
  [ArangoCollection 185255, "_apps" (type document, status loaded)], 
  [ArangoCollection 185253, "_jobs" (type document, status loaded)], 
  [ArangoCollection 185251, "_queues" (type document, status loaded)], 
  [ArangoCollection 185249, "_frontend" (type document, status loaded)], 
  [ArangoCollection 185230, "_graphs" (type document, status loaded)], 
  [ArangoCollection 185232, "_modules" (type document, status loaded)], 
  [ArangoCollection 185247, "_aqlfunctions" (type document, status loaded)], 
  [ArangoCollection 185234, "_routing" (type document, status loaded)] 
]

Die Ausführung des folgenden Befehls sorgt dafür, dass eine Collection inklusive aller ihrer Indizes und Daten gelöscht wird.


db._drop(#"collection-name"#)

Analog dazu würde der Befehl für das Löschen einer Kanten-Collection so aussehen:


db._drop(#"edge-collection-name"#)

Jedes Dokument in einer Collection verfügt über einen eindeutig identifizierbaren Primärschlüssel. Der Primärschlüssel wird als String im Attribut _key gespeichert. Sobald ein Dokument erstellt wird, wird diesem automatisiert ein _key-Wert zugewiesen, wenn dieser nicht durch den Nutzer festgelegt wurde. Einmal erzeugt, ist der _key-Wert per default Eigenschaft einer Collection unveränderlich, wenn man nicht vorab beim Erstellen der Collection, im properties-Parameter das Attribut keyOptions entsprechend definiert hat, sodass das default-Verhalten für keyOptions nicht greift. Hierzu verweise ich erneut auf die Dokumentation von ArangoDB hin. Ebenfalls eindeutig ist der Alias eines Dokuments, der als String im Attribut _id gespeichert wird. Dieser String setzt sich aus dem Namen der Collection und dem Wert des _key-Attributs zusammen, wobei beide durch ein / voneinander separiert sind.
Schließlich verfügt jedes Dokument über ein _rev-Attribut, das Aufschluss über die Revision des Dokuments gibt. Auch der Wert dieses Attributs wird als Datentyp String gespeichert. Das _rev-Attribut wird von ArangoDB automatisiert gesetzt und geupdated. In ArangoDB ist es möglich, dass mehrere Revisionen ein und desselben Dokuments existieren. Dies wiederum führt dazu, dass mit Hilfe des _rev-Attributs via einer Anfrage an die Datenbank, Dokumente geupdated, ersetzt oder gelöscht werden können. Einer Collection ein Dokument hinzufügen kannst du, indem du im Terminal ein Kommando ausführst, dass der Syntax im unten präsentierten Code-Snippet entspricht. Die geschweiften {}-Klammern stehen für das Dokument. Wie bereits erwähnt ist ein Dokument in ArangoDB ein JSON-Objekt. Mit eckigen []-Klammer hervorgehoben ist hierbei, dass das _key-Attribut optional ist. Wenn du versuchst das _id-Attribut und/oder das _rev-Attribut in der Anfrage zu definieren, erscheint keine Fehlermeldung, aber die Definitionen für diese beiden Attribute werden dann beim Erzeugen des Dokuments trotzdem überschrieben, da sie immer automatisiert von der Datenbank generiert werden.


db.#collection-name#.save({[_key:#"key-name"#], #"attribute1"#:#"value1"#, #attribute2#:#"value2"# ...})

Der folgende Code-Snippet demonstriert wie die Syntax aussieht, wenn du ein Dokument in eine Edge-Collection einbindest. Hier spielen dann u.a. die mit _from und _to gelabelten Attribute eine Rolle. Dort wird jeweils das _id-Attribut der Dokumente angetriggert, zwischen denen die Relation hergestellt werden soll. Zusätzlich kann eine Reihe von Attributen definiert werden, mit deren Hilfe schließlich spezifiziert werden kann, um was für eine Art von Relation es sich konkreter handelt. Damit können auch jegliche Arten von Informationen gespeichert werden, die die Kante zwischen den zwei Dokumenten beschreibt. Später, wenn man den Graph zu einer Edge-Collection erstellt, kann man eines der angelegten Attribute auswählen, um es als Kantenbeschriftung im Graph zu setzen.


db.#collection-name#.save({"_from":#"_id1"#, "_to":#"_id2"#, #"attribute1"#:#"value1"#, #"attribute2"#:#"value2"# ...})

Ich werde nun beginnen das zu Beginn des Tutorials erwähnte Anwendungsszenario in ArangoDB zu implementieren. Hierzu lege ich zunächst eine neue Datenbank namens folksonomy an


_system> db._createDatabase("folksonomy")

und weise dem Nutzer testuser Rechte an dieser Datenbank zu.


_system> require("org/arangodb/users").grantDatabase("testuser", "folksonomy")

Um die Folksonomy einer Foto-Sharing-Plattform in ArangoDB als Graph umzusetzen, werde ich zwei Collections anlegen. In der Collection namens member werden die Nutzer der Plattform jeweils als Dokument angelegt und in einer weiteren Collection namens picture, werden die Fotos der Plattform jeweils als Dokument erzeugt. Es ist zudem eine Edge-Collection namens interaction notwendig. In dieser werden die Relationen zwischen Nutzern und den Fotos hergestellt.

Bevor ich mit der Implementierung beginne, wechsle ich mittels dem unten eingeblendeten Kommando in die folksonomy-Datenbank


_system> db._useDatabase("folksonomy")

und lege dort die member-Collection an.


folksonomy> db._create("member")
[ArangoCollection 125364, "member" (type document, status loaded)]

Den folgenden Code-Snippets entnimmst du die Kommandos, mit denen ich jeweils ein Dokument in der member-Collection gespeichert habe. Das dazugehörige Output in {}-Klammern ist das betreffende Dokument.


folksonomy> db.member.save({_key:"peter", "name":"Peter"})
{ 
  "_id" : "member/peter", 
  "_key" : "peter", 
  "_rev" : "125394" 
}

folksonomy> db.member.save({_key:"mia", "name":"Mia"})
{ 
  "_id" : "member/mia", 
  "_key" : "mia", 
  "_rev" : "125416" 
}

folksonomy> db.member.save({_key:"hanna", "name":"Hanna"})
{ 
  "_id" : "member/hanna", 
  "_key" : "hanna", 
  "_rev" : "125438" 
}

folksonomy> db.member.save({_key:"michael", "name":"Michael"})
{ 
  "_id" : "member/michael", 
  "_key" : "michael", 
  "_rev" : "125460" 
}

Du könntest dir nun eine bestimmte Menge an Dokumenten der member-Collection – limitiert auf die Anzahl von drei Stück – als Elemente eines Array ausgeben lassen, indem du ein solches Kommando ausführst.


db.#collection-name#.all().limit(#number#).toArray()

Das Output enthält entsprechend einen Array der Collection member, in dem drei Dokumente enthalten sind.


folksonomy> db.member.all().limit(3).toArray()
[ 
  { 
    "_key" : "peter", 
    "_id" : "member/peter", 
    "_rev" : "125394", 
    "name" : "Peter" 
  }, 
  { 
    "_key" : "michael", 
    "_id" : "member/michael", 
    "_rev" : "125460", 
    "name" : "Michael" 
  }, 
  { 
    "_key" : "hanna", 
    "_id" : "member/hanna", 
    "_rev" : "125438", 
    "name" : "Hanna" 
  } 
]

Es gibt eine Reihe weiterer Anfragen und Möglichkeiten diese zu modellieren. Eine konkrete und umfangreiche Vorstellung dieser findest du in der Dokumentation von ArangoDB.
Daraufhin lege ich die Collection picture an


folksonomy> db._create("picture")
[ArangoCollection 125533, "picture" (type document, status loaded)]

und binde mittels den folgenden Kommandos drei Dokumente in diese ein.


folksonomy> db.picture.save({_key:"pic1", "description":"joining the sun and the sea"})
{ 
  "_id" : "picture/pic1", 
  "_key" : "pic1", 
  "_rev" : "125554" 
}

folksonomy> db.picture.save({_key:"pic2", "description":"dancing as art"})
{ 
  "_id" : "picture/pic2", 
  "_key" : "pic2", 
  "_rev" : "125576" 
}

folksonomy> db.picture.save({_key:"pic3", "description":"celebrating_friendship"})
{ 
  "_id" : "picture/pic3", 
  "_key" : "pic3", 
  "_rev" : "125607" 
}

Letztlich erzeuge ich die Edge-Collection interaction, in der Verbindungen zwischen Nutzern und Fotos hergestellt werden sollen


folksonomy> db._createEdgeCollection("interaction")
[ArangoCollection 125664, "interaction" (type edge, status loaded)]

und befülle diese mit Dokumenten.


folksonomy> db.interaction.save({"_key":"mia_pic1", "_from":"member/mia", "_to":"picture/pic1", "type":"add_tag", "tag-name":"sun_and_sea"})
{ 
  "_id" : "interaction/mia_pic1", 
  "_key" : "mia_pic1", 
  "_rev" : "126344" 
}

folksonomy> db.interaction.save({"_key":"peter_pic1", "_from":"member/peter", "_to":"picture/pic1", "type":"add_tag", "tag-name":"holiday"})
{ 
  "_id" : "interaction/peter_pic1", 
  "_key" : "peter_pic1", 
  "_rev" : "126819" 
}

folksonomy> db.interaction.save({"_key":"hanna_pic1", "_from":"member/hanna", "_to":"picture/pic1", "type":"add_tag", "tag-name":"beach"})
{ 
  "_id" : "interaction/hanna_pic1", 
  "_key" : "hanna_pic1", 
  "_rev" : "126841" 
}

folksonomy> db.interaction.save({"_key":"michael_pic1", "_from":"member/michael", "_to":"picture/pic1", "type":"add_tag", "tag-name":"summer"})
{ 
  "_id" : "interaction/michael_pic1", 
  "_key" : "michael_pic1", 
  "_rev" : "126872" 
}

folksonomy> db.interaction.save({"_key":"mia_pic2", "_from":"member/mia", "_to":"picture/pic2", "type":"add_tag", "tag-name":"performance"})
{ 
  "_id" : "interaction/mia_pic2", 
  "_key" : "mia_pic2", 
  "_rev" : "126939" 
}

folksonomy> db.interaction.save({"_key":"michael_pic2", "_from":"member/michael", "_to":"picture/pic2", "type":"add_tag", "tag-name":"dance"})
{ 
  "_id" : "interaction/michael_pic2", 
  "_key" : "michael_pic2", 
  "_rev" : "126976" 
}

folksonomy> db.interaction.save({"_key":"mia_pic3", "_from":"member/mia", "_to":"picture/pic3", "type":"add_tag", "tag-name":"friendship"})
{ 
  "_id" : "interaction/mia_pic3", 
  "_key" : "mia_pic3", 
  "_rev" : "127016" 
}

folksonomy> db.interaction.save({"_key":"peter_pic3", "_from":"member/peter", "_to":"picture/pic3", "type":"add_tag", "tag-name":"friends"})
{ 
  "_id" : "interaction/peter_pic3", 
  "_key" : "peter_pic3", 
  "_rev" : "127038" 
}

folksonomy> db.interaction.save({"_key":"michael_pic3", "_from":"member/michael", "_to":"picture/pic3", "type":"add_tag", "tag-name":"friendship"})
{ 
  "_id" : "interaction/michael_pic3", 
  "_key" : "michael_pic3", 
  "_rev" : "127105" 
}

Im Anschluss an die Implementierung des Anwendungsszenarios, möchte ich mir hierzu einen Graph erstellen. Dies werde ich im ArangoDB-Web-Interface machen. Hierzu muss ich jedoch ein paar Einstellungen an der Konfiguration vornehmen, was ich dir im nächsten Kapitel zeige.

ArangoDB Web-Interface einrichten

ArangoDB verfügt über eine integrierte, benutzerfreundliche Weboberfläche, die für alle administrativen Aufgaben genutzt werden kann. Es können hierüber alle Aufgaben erledigt werden, die sich auch über die im vorherigen Kapitel eingeführte arangosh-Befehlszeilenschnittstelle ausführen lassen. Auch lassen sich darüber Datenbanken-Szenarien implementieren, sowie Anfragen auf diese ausführen und ein Monitoring durchführen.
Der Zugriff auf dieses Web-Interface ist per default nicht möglich, sondern erfordert ein paar Anpassungen, die du in den ArangoDB-Konfigurationsdateien vorgenommen müsstest.
Zunächst öffnest du mit dem folgenden Kommando die arangod-Konfigurationsdatei im nano-Editor.


nano /etc/arangodb3/arangod.conf

Dort scrollst du dich dann bis zu der Zeile, die ich im Screenshot farblich hervorgehoben habe und bindest in den im Screenshot gelb markierten Teil die IP-Adresse deines Servers ein. Im Anschluss daran betätigst du die Tastenkombination Strg+O, um das Speichern deiner Anpassung einzuleiten, bestätigst den daraufhin in einem weiß hinterlegten Balken eingeblendeten Namen der Konfigurationsdatei mit der Enter-Taste und verlässt den nano-Editor dann mit der Tastenkombination Strg+X.

arangod-Konfigurationsdatei editieren

Als nächstes öffnest du dann mit dem folgenden Kommando die arangosh-Konfigurationsdatei im nano-Editor.


nano /etc/arangodb3/arangosh.conf

Dort tauscht du die IP für die Kommunikation mit dem Endpunkt ebenfalls mit der IP-Adresse deines Servers aus. Die Stelle, an der du deine IP-Adresse implementieren musst, habe ich auch im folgenden Screenshot farblich kenntlich gemacht. Du verlässt den nano-Editor auf dieselbe Weise, wie ich dir im Beispiel für das Editieren der arangod-Konfigurationsdatei erklärt habe.

Um die Anpassungen in den beiden Konfigurationsdateien zu aktivieren, startest du den Service, indem du den folgenden Befehl im Terminal ausführst.


systemctl restart arangodb3

Getting started mit ArangoDB Web-Interface

Nachdem du – wie im vorherigen Kapitel gezeigt – das Web-Interface von ArangoDB konfiguriert hast, sollte es dir möglich sein, dieses via Aufruf der URL http://localhost:8529 in deinem Browser zu erreichen. Hierbei müsstest du dann localhost mit der IP-Adresse deines Servers austauschen. Wenn du neben dem root-User keine weiteren Nutzer in der Datenbank angelegt hast, ist es dir möglich, dich zunächst über den root-Nutzer im Web-Interface einzuloggen. Das Passwort entspräche dann dem Passwort, mit dem du dich auch bei der Nutzung der Befehlszeilenschnittstelle nach Eingabe des arangosh-Kommandos anmeldest und das du bei der Installation von ArangoDB als root-Passwort festgelegt hast. Andernfalls kannst du dich unter jedem x-beliebigen User anmelden, der in der Datenbank existiert. In meinem Beispiel werde ich mich unter dem Nutzer testuser einloggen. Nach erfolgreicher Authentifizierung durch Nutzername und Passwort kannst du, wie im Screenshot unten präsentiert, in der DropDown-Liste die für den betreffenden Nutzer verfügbaren Datenbanken einsehen und eine bestimmte wählen. In dieser DropDown-Liste sind quasi nur die Datenbanken gelistet, für die dem Nutzer Rechte zugeteilt worden sind.

Anmeldung zum Web-Interface von ArangoDB

Angemeldet in der _system-Datenbank kannst du im DASHBOARD-Menüpunkt die Prozesse der Datenbank grafisch aufbereitet einsehen.

Dashboard in _system-Datenbank von ArangoDB

Im USERS-Menüpunkt findest du eine Übersicht der angelegten Nutzer, wie du im Screenshot unten erkennst. Mit Klick auf eines der User-Items hast du die Möglichkeit, diesen zu löschen oder das Passwort zu ändern.

Users-Menüpunkt in Web-Interface von ArangoDB

Zudem kannst du den Add User-Button nutzen, um einen neuen Nutzer anzulegen. Hierbei wird dann ein Interface eingeblendet, in dem du die notwendigen Informationen zum neuen User eintragen kannst.

In Web-Interface von ArangoDB Nutzer hinzufügen

Einen Überblick über alle Datenbanken bietet der DATABASES-Menüpunkt. Dort befindet sich in jedem Item oben rechts ein Zahnrad-Icon, mit dessen Betätigung du das Editieren des Items einleiten kannst. Das Editieren beschränkt sich hierbei dann aber auf das Löschen des betreffenden Items.

Databases-Menüpunkt in Web-Interface von ArangoDB

Wie im Fall der User hast du auch bei den Datenbanken die Möglichkeit via dem Button Add Database eine neue Datenbank zu erstellen. Im hierfür eingeblendeten Interface kannst du dann den Namen der Datenbank sowie den Nutzer bestimmen.

In Web-Interface von ArangoDB Datenbank hinzufügen

Der SUPPORT-Menüpunkt stellt dir eine Reihe von nützlichen Links zur Verfügung, mit denen du dir weiterführende Informationen zu ArangoDB und der Datenbanksprache AQL beschaffen kannst.

Support-Menüpunkt in Web-Interface von ArangoDB

Für die Erstellung des Graphen zum Anwendungsszenario, das ich in die folksonomy-Datenbank implementiert habe, wechsle ich in die folksonomy-Datenbank. Dies tue ich, indem ich den switch-Icon-Button betätige, der sich in der Mitte von insgesamt drei Icon-Buttons ganz oben rechts in der ArangoDB-Web-Anwendung befindet. Nach dem Wechsel steht dort links neben dem switch-Icon-Button nicht mehr DB: _SYSTEM, sondern DB: FOLKSONOMY.
Unter dem COLLECTIONS-Menüpunkt findet man alle in der betreffenden Datenbank existieren Collections. Via dem Add Collection-Button kann man jederzeit eine neue Collection hinzufügen. Wie im Screenshot unten abgebildet, befinden sich dort nun nach meinen Implementierungen die Edge-Collection interaction, die Dokument-Collection member und die Dokument-Collection picture.

Collections-Menüpunkt in Web-Interface von ArangoDB

Wenn man nun auf ein Collection-Item klicken würde, würde man eine Übersicht aller darin befindlichen Dokumente erhalten und könnte den Inhalt sowohl der Collection als auch der Elemente der Collection (Dokumente) editieren. Ich dokumentiere dies kurz mittels Screenshots am Beispiel der Edge-Collection interaction. Nachdem ich diese Collection angeklickt habe, werden mir alle darin befindlichen Dokumente gelistet. Via dem (+)-Button kann ich weitere Dokumente zu dieser Collection hinzufügen oder gar Dokumente löschen, indem ich den jeweils hinter dem Dokument stehenden ()-Button betätige.

Collection im Web-Interface von ArangoDB editieren

Würde ich den (+)-Button betätigen, würde ein Interface eingeblendet, in das ich das _from-, sowie das _to-Attribut festlegen, sowie das _key-Attribut definieren kann.

Einer Collection im Web-Interface von ArangoDB neues Dokument hinzufügen

Möchte ich ein bereits bestehendes oder ein gerade neu angelegtes Dokument um Attribute erweitern, klicke ich auf das betreffende Dokument. Wie du dem Screenshot unten entnimmst, ist es möglich via Klick auf den zur linken Seite befindlichen Button, Attribute anzuknüpfen, neu zu implementieren, zu duplizieren oder zu löschen.

Einem Dokument im Web-Interface von ArangoDB neues Attribut hinzufügen

Der QUERIES-Menüpunkt macht es über den eingebundenen Editor möglich- mittels AQL-konformen-Anfragen, Datenbankinhalte wiederzugeben, wie im folgenden Screenshot abgebildet. Für AQL-Anfragen verweise ich auf die online verfügbare

AQL-Dokumentation von ArangoDB.

Queries-Menüpunkt in Web-Interface von ArangoDB

Nun möchte ich den Graphen zu meinem implementierten Anwendungsszenario erstellen. Hierzu wechsle ich im Menü in den Punkt GRAPHS. Nachdem ich den Add Graph-Button betätigt habe, wird ein Interface eingeblendet, in dem ich im Create Graph-Tab die Formalitäten des Graphen sowie die Zusammenhänge der Collections im Graphen bestimmen kann. Wie dies für den Graphen zu den beiden Dokument-Collections member und picture sowie der Edge-Collection interaction aussieht, zeige ich dir im Screenshot unten im Tab. Im Example Graphs-Tab hast du die Möglichkeit, dir von der ArangoDB Web-Anwendung zur Verfügung gestellte Beispielgraphen generieren zu lassen, um so ein Gefühl für die Beschaffenheit von Graphen und dem Zusammenhang, der darin in Relationen stehenden Dokumente zu bekommen.

Graph im Web-Interface von ArangoDB hinzufügen

Nach Betätigung des Create-Button ist der Graph als abrufbares Item im GRAPHS-Menüpunkt verfügbar.

Graphs-Menüpunkt in Web-Interface von ArangoDB

Via Klick auf das betreffende Graph-Item gelangst du in die Maske, in der du dir den Graph ansehen und diesen editieren kannst, wie dir der Screenshot unten verbildlicht.

Graph im Web-Interface von ArangoDB

Fazit

Es hat mir Spaß gemacht, dich durch die Installation und die ersten Schritte in der Anwendung von ArangoDB zu leiten, die du bei Interesse mit Hilfe der online verfügbaren Dokumentation von ArangoDB vertiefen kannst. Ich wünsche dir gutes Gelingen bei der Umsetzung deiner Ideen mit ArangoDB.

Aus unserer Rubrik zu Open Source Datenbanken und Datenbank-Plattformen auch noch interessant und hilfreich:

Zurück zur Tutorial Übersicht Back to Tutorial Overview

OrientDB unter Ubuntu 16.04/18.04 installieren und einrichten

OrientDB auf Ubuntu installieren

In unseren vorhergehenden Tutorials habe ich dir gezeigt, wie du MySQL, PostgreSQL, MongoDB, Apache Cassandra, Redis, RethinkDB, InfluxDB, Neo4j und ArangoDB unter Ubuntu installierst und einrichtest. In diesem Tutorial nun werde ich dir die NoSQL-Datenbank-Plattform OrientDB vorstellen, mit dir Schritt für Schritt einen Installations- und Einrichtungsprozess durchgehen und dir die wichtigsten Features von OrientDB anhand einem kleinen Anwendungsszenario nahe bringen.

Zu OrientDB

OrientDB ist eine in Java geschriebene Open-Source-NoSQL-Multi-Modell-Datenbank, die die Leistungsfähigkeit von Graphen mit Dokumenten-, Schlüssel / Wert-, reaktiven, objektorientierten und Geodatenmodellen in einer einzigen skalierbaren, leistungsfähigen Datenbank vereint. OrientDB verfolgt als NoSQL-Datenbank-Plattform einen nicht-relationalen Ansatz, nutzt jedoch eine SQL-basierte Abfragesprache, die erweitert wurde, um Bäume und Graphen zu erstellen.

Anwendungsszenario

Um dir die dokumentenorientierte Datenbank-Plattform aus der Warte der wichtigsten Features zu zeigen, habe ich mir ein kleines Anwendungsszenario ausgedacht. Die Dokumente in OrientDB kannst du dir als Informationseinheiten im JSON-Format vorstellen. Ein Dokument ist im Sinne eines Graphen entweder ein Knoten oder eine Kante. Ein Knoten käme zur besseren Verständlichkeit im konventionellen relationalen Datenbankmodell einer Entität gleich und eine Kante einer Relation zwischen Entitäten. Ich werde in diesem Tutorial eine kleine Filmdatenbank erstellen, in der ich das Genre von Filmen der Schauspielerin Jennifer Lawrence in Form von Graphen abbildbar mache.

Voraussetzung

Java muss auf deinem Server installiert sein. Eine Anleitung hierzu findest du in unserem Tutorial zum Thema Neo4j unter Ubuntu 16.04/18.04 installieren und einrichten.

Installation und Konfiguration von OrientDB

Stelle sicher, dass dein Server up-to-date ist.


apt-get update && apt-get upgrade

Lade dir OrientDB-Community herunter. Bei Bedarf kannst du die Versionsnummer im folgenden Befehl entsprechend anpassen.


wget https://s3.us-east-2.amazonaws.com/orientdb3/releases/3.0.4/orientdb-3.0.4.tar.gz

Der heruntergeladene Tarball enthält vorkompilierte Binärdateien, um OrientDB auf deinem System auszuführen. Mit dem unten stehenden Kommando entpackst du diesen.


tar -zxvf orientdb-3.0.4.tar.gz

Die Dateien wurden in das Verzeichnis orientdb-community-3.0.4 extrahiert. Als nächstes musst du dieses in das /opt-Verzeichnis überführen und es in orientdb umbenennen. Hierzu führst du das unten eingeblendete Kommando aus.


mv ~/orientdb-3.0.4 /opt/orientdb

Wenn dein Server speicherbeschränkt ist, kannst du OrientDB so konfigurieren, dass weniger RAM verwendet wird. Per default erwartet der OrientDB-Daemon nämlich mindestens 2 GB RAM und kann nicht starten, wenn er weniger findet. Die Änderung des Arbeitsspeichers müsstest du bei Bedarf dann in der Datei server.sh dahingehend vornehmen, dass der Daemon mit weniger RAM starten kann.


nano /opt/orientdb/bin/server.sh

Scrolle in der Datei zu dem Teil, der im Code-Snippet unten zu erkennen ist


. . .

# ORIENTDB memory options, default to 2GB of heap.

if [ -z "$ORIENTDB_OPTS_MEMORY" ] ; then
    ORIENTDB_OPTS_MEMORY="-Xms2G -Xmx2G"
fi

. . .

und ändere die Werte für Xms und Xmx, da diese den initialen und maximalen Speicherzuweisungspool für die Java Virtual Machine spezifizieren.
Stelle jedoch sicher, dass Xms mindestens 128 MB groß ist, da OrientDB ansonsten nicht gestartet wird. Zum Beispiel lege die Werte für die anfängliche und maximale Menge von RAM so fest, dass diese zwischen 128 MB und 256 MB liegen.


# ORIENTDB memory options, default to 2GB of heap.

if [ -z "$ORIENTDB_OPTS_MEMORY" ] ; then
    ORIENTDB_OPTS_MEMORY="-Xms128m -Xmx256m"
fi

Als nächstes geht es nun daran, den Server zu starten, um eine Verbindung zur Konsole herzustellen. Navigiere vorab mittels dem folgenden Befehl zum /opt/orientdb-Installationsverzeichnis.


cd /opt/orientdb

Starte daraufhin schließlich den Server.


bin/server.sh

Wenn du den Server zum ersten Mal startest, wirst du aufgefordert, ein Kennwort für das root-Benutzerkonto anzulegen, wie am Ende des unten gezeigten Outputs aufgeführt. Das Konto, dass du hierbei anlegst, ist ein internes OrientDB-Konto, das für den Zugriff auf den Server verwendet wird, beispielsweise für OrientDB Studio, die webbasierte Schnittstelle für die Verwaltung von OrientDB. Wenn du kein Passwort angibst, wird eines automatisch generiert.


           .                                          
          .`        `                                 
          ,      `:.                                  
         `,`    ,:`                                   
         .,.   :,,                                    
         .,,  ,,,                                     
    .    .,.:::::  ````                                 :::::::::     :::::::::   
    ,`   .::,,,,::.,,,,,,`;;                      .:    ::::::::::    :::    :::  
    `,.  ::,,,,,,,:.,,.`  `                       .:    :::      :::  :::     ::: 
     ,,:,:,,,,,,,,::.   `        `         ``     .:    :::      :::  :::     ::: 
      ,,:.,,,,,,,,,: `::, ,,   ::,::`   : :,::`  ::::   :::      :::  :::    :::  
       ,:,,,,,,,,,,::,:   ,,  :.    :   ::    :   .:    :::      :::  :::::::     
        :,,,,,,,,,,:,::   ,,  :      :  :     :   .:    :::      :::  :::::::::   
  `     :,,,,,,,,,,:,::,  ,, .::::::::  :     :   .:    :::      :::  :::     ::: 
  `,...,,:,,,,,,,,,: .:,. ,, ,,         :     :   .:    :::      :::  :::     ::: 
    .,,,,::,,,,,,,:  `: , ,,  :     `   :     :   .:    :::      :::  :::     ::: 
      ...,::,,,,::.. `:  .,,  :,    :   :     :   .:    :::::::::::   :::     ::: 
           ,::::,,,. `:   ,,   :::::    :     :   .:    :::::::::     ::::::::::  
           ,,:` `,,.                                  
          ,,,    .,`                                  
         ,,.     `,                                              VELOCE  
       ``        `.                                                          
                 ``                                       www.orientdb.com
                 `                                    

2018-07-30 22:26:52:433 INFO  Detected limit of amount of simultaneously open files is 1048576,  limit of open files for disk cache will be set to 523776 [ONative]
2018-07-30 22:26:52:449 INFO  Loading configuration from: /opt/orientdb/config/orientdb-server-config.xml... [OServerConfigurationLoaderXml]
2018-07-30 22:26:53:001 INFO  OrientDB Server v3.0.4 - Veloce (build 4578b51f72a55feaa0852bc8ddd52929011d956c, branch 3.0.x) is starting up... [OServer]
2018-07-30 22:26:53:027 INFO  4124733440 B/3933 MB/3 GB of physical memory were detected on machine [ONative]
2018-07-30 22:26:53:028 INFO  Soft memory limit for this process is set to -1 B/-1 MB/-1 GB [ONative]
2018-07-30 22:26:53:028 INFO  Hard memory limit for this process is set to -1 B/-1 MB/-1 GB [ONative]
2018-07-30 22:26:53:029 INFO  Path to 'memory' cgroup is '/user.slice/user-0.slice/session-1.scope' [ONative]
2018-07-30 22:26:53:032 INFO  Mounting path for memory cgroup controller is '/sys/fs/cgroup/memory' [ONative]
2018-07-30 22:26:53:033 INFO  cgroup soft memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB [ONative]
2018-07-30 22:26:53:034 INFO  cgroup hard memory limit is 9223372036854771712 B/8796093022207 MB/8589934591 GB [ONative]
2018-07-30 22:26:53:034 INFO  Detected memory limit for current process is 4124733440 B/3933 MB/3 GB [ONative]
2018-07-30 22:26:53:036 INFO  JVM can use maximum 1963MB of heap memory [OMemoryAndLocalPaginatedEnginesInitializer]
2018-07-30 22:26:53:036 INFO  Because OrientDB is running outside a container 2g of memory will be left unallocated according to the setting 'memory.leftToOS' not taking into account heap memory [OMemoryAndLocalPaginatedEnginesInitializer]
2018-07-30 22:26:53:037 WARNI Not enough physical memory available for DISKCACHE: 3,933MB (heap=1,963MB). Set lower Maximum Heap (-Xmx setting on JVM) and restart OrientDB. Now running with DISKCACHE=256MB [orientechnologies]
2018-07-30 22:26:53:037 INFO  OrientDB config DISKCACHE=256MB (heap=1,963MB os=3,933MB) [orientechnologies]
2018-07-30 22:26:53:051 INFO  Databases directory: /opt/orientdb/databases [OServer]
2018-07-30 22:26:53:093 INFO  Creating the system database 'OSystem' for current server [OSystemDatabase]
2018-07-30 22:26:53:698 INFO  Storage 'plocal:/opt/orientdb/databases/OSystem' is created under OrientDB distribution : 3.0.4 - Veloce (build 4578b51f72a55feaa0852bc8ddd52929011d956c, branch 3.0.x) [OLocalPaginatedStorage]
2018-07-30 22:26:57:843 INFO  Listening binary connections on 0.0.0.0:2424 (protocol v.37, socket=default) [OServerNetworkListener]
2018-07-30 22:26:57:847 INFO  Listening http connections on 0.0.0.0:2480 (protocol v.10, socket=default) [OServerNetworkListener]

+---------------------------------------------------------------+
|                WARNING: FIRST RUN CONFIGURATION               |
+---------------------------------------------------------------+
| This is the first time the server is running. Please type a   |
| password of your choice for the 'root' user or leave it blank |
| to auto-generate it.                                          |
|                                                               |
| To avoid this message set the environment variable or JVM     |
| setting ORIENTDB_ROOT_PASSWORD to the root password to use.   |
+---------------------------------------------------------------+

Root password [BLANK=auto generate it]: *

Wenn dir das oben eingeblendete Output erscheint, läuft OrientDB jetzt in deinem aktuellen Terminal. Nachdem ich ein Passwort angelegt habe, erhalte ich ein Output der Form, wie du es im Code-Block unten erkennst.


Root password [BLANK=auto generate it]: ********
Please confirm the root password: ********

2018-07-30 22:29:23:355 INFO  Installing dynamic plugin 'orientdb-neo4j-importer-plugin-3.0.4-dist.jar'... [OServerPluginManager]
2018-07-30 22:29:23:363 INFO  Installing dynamic plugin 'orientdb-teleporter-3.0.4.jar'... [OServerPluginManager]
2018-07-30 22:29:23:372 INFO  Installing dynamic plugin 'orientdb-studio-3.0.4.zip'... [OServerPluginManager]
2018-07-30 22:29:23:373 INFO  Installing dynamic plugin 'orientdb-etl-3.0.4.jar'... [OServerPluginManager]
2018-07-30 22:29:23:378 INFO  ODefaultPasswordAuthenticator is active [ODefaultPasswordAuthenticator]
2018-07-30 22:29:23:379 INFO  OServerConfigAuthenticator is active [OServerConfigAuthenticator]
2018-07-30 22:29:23:380 INFO  OSystemUserAuthenticator is active [OSystemUserAuthenticator]
2018-07-30 22:29:23:381 INFO  [OVariableParser.resolveVariables] Property not found: distributed [orientechnologies]
2018-07-30 22:29:23:389 WARNI Authenticated clients can execute any kind of code into the server by using the following allowed languages:  [OServerSideScriptInterpreter]
2018-07-30 22:29:23:392 INFO  OrientDB Studio available at http://185.201.144.136:2480/studio/index.html [OServer]
2018-07-30 22:29:23:392 INFO  OrientDB Server is active v3.0.4 - Veloce (build 4578b51f72a55feaa0852bc8ddd52929011d956c, branch 3.0.x). [OServer]

Als nächstes startest du den Server neu, was du mit dem folgenden Kommando umsetzt.


reboot

Schließlich meldest du dich mit Hilfe des unten stehenden Kommandos wieder auf deinem Server an, wobei du localhost mit der IP deines Servers austauscht,


ssh [email protected]

erneut in das Installationsverzeichnis wechselst


cd /opt/orientdb

und den OrientDB-Server startest.


bin/server.sh

Als nächstes lässt du dir bestätigen, dass der Server die entsprechenden Ports abhört. Öffne hierzu ein zweites Terminal und verbinde dich dort ebenfalls über den oben präsentierten Befehl mit demselben Server. Vergewissere dich dann in diesem zweiten Terminal, dass der Server die Ports 2424 (für binäre Verbindungen) sowie 2480 (für HTTP-Verbindungen) mit dem folgenden Befehl abhört.


netstat -plunt | grep -i listen

Das Output sollte Referenzen auf beide Portnummern enthalten, wie folgt:


tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1262/sshd       
tcp6       0      0 :::2480                 :::*                    LISTEN      1625/java       
tcp6       0      0 :::22                   :::*                    LISTEN      1262/sshd       
tcp6       0      0 :::2424                 :::*                    LISTEN      1625/java

Nachdem der Server gestartet wurde und du verifiziert hast, dass er ausgeführt wird, stelle eine Verbindung zur OrientDB-Konsole im zweiten Terminal her. Lasse den ersten Terminal parallel dazu noch geöffnet. Die OrientDB-Konsole ist die Befehlszeilenschnittstelle für die Arbeit mit der Anwendung. Du startest die OrientDB-Konsole mit dem folgenden Kommando.


/opt/orientdb/bin/console.sh

Output:


OrientDB console v.3.0.4 - Veloce (build 4578b51f72a55feaa0852bc8ddd52929011d956c, branch 3.0.x) https://www.orientdb.com
Type 'help' to display all the supported commands.

orientdb>

Stelle jetzt eine Verbindung zur Server Instanz her. Das erforderliche Kennwort ist das Kennwort, das du beim ersten Starten des Servers festgelegt hast. Im Code-Snippet unten präsentierten Kommando würdest du password mit dem betreffenden Passwort austauschen.


orientdb> connect remote:127.0.0.1 root password

Output nach erfolgreicher Verbindung:


OK
orientdb {server=remote:127.0.0.1}>

Wenn du fertig bist, gib exit im zweiten Terminal ein, um die OrientDB-Eingabeaufforderung zu beenden.


orientdb {server=remote:127.0.0.1/}> exit

Nachdem du nun OrientDB installiert, manuell gestartet und eine Verbindung hergestellt hast, weißt du zwar, dass es funktioniert, aber es bedeutet auch, dass du es manuell starten musst, wenn du den Server neu starten würdest. In den nächsten Schritten konfiguriere ich OrientDB so, dass es wie jeder andere Daemon auf dem Server ausgeführt wird. Dazu muss zum einen das Skript /opt/orientdb/bin/orientdb.sh und zum anderen die Konfigurationsdatei /opt/orientdb/config/orientdb-server-config.xml geändert werden.
Schließe vor den nächsten Schritten das 1. Terminalfenster.
Die Änderung des Skripts /opt/orientdb/bin/orientdb.sh ist erforderlich, um OrientDB den Benutzer mitzuteilen, unter dem es ausgeführt werden soll, und um es auf das Installationsverzeichnis zu verweisen. Erstelle hierfür vorab den Systembenutzer, den OrientDB ausführen soll. In meinem Beispiel erstelle ich den testuser-Benutzer. Der Befehl inkludiert die Erstellung der testuser-Gruppe.


useradd -r testuser -s /sbin/nologin

Erteile dem neu erstellten testuser-Benutzer und der testuser-Gruppe den Besitz des OrientDB-Verzeichnisses und der zugehörigen Dateien mittels folgendem Kommando.


chown -R testuser:testuser /opt/orientdb

Schließlich nehme ich ein paar Änderungen am Skript orientdb.sh vor. Ich öffne es mit dem folgenden Befehl im nano-Editor.


nano /opt/orientdb/bin/orientdb.sh

Dort navigierst du dich zu der Stelle, die du im Code-Snippet unten erkennst


. . .

# You have to SET the OrientDB installation directory here
ORIENTDB_DIR="YOUR_ORIENTDB_INSTALLATION_PATH"
ORIENTDB_USER="USER_YOU_WANT_ORIENTDB_RUN_WITH"

. . .

und tauscht die Inhalte der beiden Zeilen mit denen aus, die du dem Code-Block unten entnimmst. Du speicherst das Update durch Betätigung der Tastenkombination Strg+O, bestätigst den daraufhin in einem weißen Balken eingeblendeten Dateinamen mit der Enter-Taste und verlässt den nano-Editor durch Betätigung der Tastenkombination Strg+X.


…

# You have to SET the OrientDB installation directory here
ORIENTDB_DIR="/opt/orientdb"
ORIENTDB_USER="orientdb"

...

Ändere anschließend die Berechtigungen der Serverkonfigurationsdatei, um zu verhindern, dass nicht autorisierte Benutzer sie lesen können.


chmod 640 /opt/orientdb/config/orientdb-server-config.xml

Mit dem nächsten Kommando konfiguriere ich den Daemon so, dass er von Systemd, dem Service-Manager, gesteuert wird.


cp /opt/orientdb/bin/orientdb.service /etc/systemd/system

In dieser Datei müssen einige Einstellungen geändert werden. Öffne sie zum Editieren mittels folgendem Kommando.


nano /etc/systemd/system/orientdb.service

Ändere die Benutzer-, Gruppen- und ExecStart-Variablen unter dem Punkt Service, damit diese mit deiner Installation übereinstimmen. Du hinterlegst – wie im Code-Block unten demonstriert – den Benutzer und die Gruppe (beide sind in meinem Beispiel testuser). ExecStart gibt den Pfad zum Skript an, der mit /opt/orientdb beginnen sollte.


. . .

[Service]
User=testuser
Group=testuser
ExecStart=/opt/orientdb/bin/server.sh

...

Führe anschließend den folgenden Befehl aus, um alle Einheiten neu zu laden.


systemctl daemon-reload

Wenn alles vorhanden ist, kannst du jetzt den OrientDB-Dienst starten.


systemctl start orientdb

Und stelle sicher, dass OrientDB beim Booten startet.


systemctl enable orientdb

Stelle zudem sicher, dass OrientDB wirklich begonnen hat, indem du den Prozessstatus mit Hilfe des folgenden Kommandos überprüfst.


systemctl status orientdb

Output:


● orientdb.service - OrientDB Server
   Loaded: loaded (/etc/systemd/system/orientdb.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2018-07-30 22:49:44 CEST; 24s ago
 Main PID: 1747 (java)
   CGroup: /system.slice/orientdb.service
           └─1747 java -server -Xms2G -Xmx2G -Djna.nosys=true -XX:+HeapDumpOnOutOfMemoryError -Djava.awt.headless=true -Dfile.encoding=UT

Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:463 INFO  Installing dynamic plugin 'orientdb-neo4j-importer-plugin-
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:469 INFO  Installing dynamic plugin 'orientdb-teleporter-3.0.4.jar'.
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:475 INFO  Installing dynamic plugin 'orientdb-studio-3.0.4.zip'... [
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:476 INFO  Installing dynamic plugin 'orientdb-etl-3.0.4.jar'... [OSe
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:481 INFO  ODefaultPasswordAuthenticator is active [ODefaultPasswordA
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:482 INFO  OServerConfigAuthenticator is active [OServerConfigAuthent
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:483 INFO  OSystemUserAuthenticator is active [OSystemUserAuthenticat
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:484 INFO  [OVariableParser.resolveVariables] Property not found: dis
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:490 WARNI Authenticated clients can execute any kind of code into th
Jul 30 22:49:46 server-qqo7zytv server.sh[1747]: 2018-07-30 22:49:46:493 INFO  OrientDB Studio available at http://185.201.144.136:2480/s
lines 1-17/17 (END)

Getting started mit OrientDB Studio

OrientDB Studio ist die Weboberfläche für die Verwaltung von OrientDB. Wenn du es aktivieren möchtest, musst du deiner Firewall eine Regel hinzufügen. Standardmäßig hört OrientDB Studio Port 2480 ab. Wenn du die Firewall auf dem Server konfiguriert hast, musst du den Zugriff auf Port 2480 zulassen, was du mit dem unten stehenden Befehl umsetzen würdest.


ufw allow 2480

Starte daraufhin UFW mit dem unten gezeigten Kommando neu.


systemctl restart ufw

Rufe im Anschluss daran in deinem Browser die Adresse http://localhost:2480 auf, wobei du localhost mit der IP deines Servers austauscht.

Du kannst dich als root mit dem zuvor festgelegten Passwort anmelden. Alternativ kannst du auch die demodb-Datenbank in der im Screenshot unten ersichtlich werdenden Dropdown-Liste auswählen und dich mit einem der in OrientDB enthaltenen Standardbenutzerkonten anmelden (Administrator, Leser oder Schreiber). Diese Datenbank stellt sozusagen eine Demo zur Verfügung anhand der du dich mit den Funktionalitäten von OrientDB vertraut machen und experimentieren kannst. Je nach Rolle würden sich entsprechend die Anmeldedaten ändern. Wenn du dich in der besagten demodb-Datenbank mit Administratorrechten anmelden möchtest, dann wäre der Benutzername admin und das Passwort admin. Im Fall der Anmeldung mit Leserechten wäre der Benutzername reader und das Passwort reader. Und im Fall der Anmeldung mit Schreibrechten wäre der Benutzername writer und das Passwort writer.

Anmeldeseite der Weboberfläche von OrientDB

In meinem Fall erstelle ich eine neue Datenbank namens testDB. Im Screenshot unten erkennst du, dass hierfür neben dem Namen der Datenbank Informationen zum Benutzernamen und seinem Passwort erforderlich sind.

In der Weboberfläche von OrientDB eine Datenbank anlegen

Im SCHEMA-Menüpunkt ist es dir möglich eine beliebige Anzahl an Knoten und deren verbindende Kanten zu erstellen. Hierzu bietet sich der Button + NEW VERTEX, bzw. + NEW EDGE an. Im unten präsentierten Screenshot erkennst du das Interface, dass nach Betätigung des Button + NEW VERTEX erscheint. Hier lege ich die Entität Movie an.

In der Weboberfläche von OrientDB einen Knoten anlegen

Als weitere Knoten-Klasse lege ich danach Genre an. Schließlich stelle ich noch die Relation zwischen den beiden Entitäten Movie und Genre her. Im Interface, dass nach Betätigung des Button + NEW EDGE generiert wird, benenne ich die Relation als belong_to und erzeuge die Verbindung zwischen Movie und Genre. Wie du im Screenshot unten erkennst, bieten dir hierzu Dropdown-Listen die Möglichkeit aus der vorhandenen Menge zu wählen.

In der Weboberfläche von OrientDB eine Kante anlegen

Als nächstes lege ich fest, über welche Eigenschaften die Entitäten Movie und Genre verfügen sollen. Hierzu klicke ich auf die betreffende Entität, gelange auf deren Webseite und betätige dort den Button + NEW PROPERTY, woraufhin sich ein Interface öffnet, in dem du u.a. den Namen der Eigenschaft, sowie deren Datentyp definieren kannst. In den drei folgenden Screenshots siehst du, wie ich der Entität Genre die Eigenschaft type (Art), sowie der Entität Movie die Eigenschaften year_of_publication (Publikationsjahr), length (Spiellänge) und name (Name/Titel) zuschreibe.

In der Weboberfläche von OrientDB Eigenschaften einer Kante definieren

In der Weboberfläche von OrientDB Eigenschaften einer Kante definieren

In der Weboberfläche von OrientDB Eigenschaften einer Kante definieren

In der Weboberfläche von OrientDB Eigenschaften einer Kante definieren

Im BROWSE-Tab befülle ich danach dann die betreffenden Entitäten Movie und Genre mit Informationen. Hierzu bietet die darin befindliche Kommandozeile die Möglichkeit. Hierbei folge ich der Syntax, wie sie im Code-Snippet unten eingeblendet ist.


INSERT INTO Entity(Attribute1, Attribute2 ...) VALUES (Value1, Value2 ...)

Zum besseren Nachvollziehen dient dir der Screenshot unten, aus dem du eine beispielhafte Query über die Kommandozeile im BROWSE-Tab entnimmst.

In der Weboberfläche von OrientDB einen Knoteneintrag hinzufügen

Zusätzlich stelle ich dir alle Kommandos zum Befüllen der Entität Movie mit Daten in den folgenden Code-Snippets bereit.


INSERT INTO Movie(length, name, year_of_publication) VALUES (116, "Passengers", 2016)

INSERT INTO Movie(length, name, year_of_publication) VALUES (122, "Silver Linings", 2012)

INSERT INTO Movie(length, name, year_of_publication) VALUES (124, "Joy - Alles außer gewöhnlich", 2015)

INSERT INTO Movie(length, name, year_of_publication) VALUES (138, "American Hustle", 2013)

INSERT INTO Movie(length, name, year_of_publication) VALUES (109, "Serena", 2014)

INSERT INTO Movie(length, name, year_of_publication) VALUES (101, "House at the End of the Street", 2012)

INSERT INTO Movie(length, name, year_of_publication) VALUES (100, "Winter's Bone", 2010)

INSERT INTO Movie(length, name, year_of_publication) VALUES (141, "Red Sparrow", 2018)

INSERT INTO Movie(length, name, year_of_publication) VALUES (142, "Die Tribute von Panem - The Hunger Games", 2012)

INSERT INTO Movie(length, name, year_of_publication) VALUES (146, "Die Tribute von Panem - Catching Fire", 2013)

INSERT INTO Movie(length, name, year_of_publication) VALUES (123, "Die Tribute von Panem - Mockingjay Teil 1", 2014)

INSERT INTO Movie(length, name, year_of_publication) VALUES (137, "Die Tribute von Panem - Mockingjay Teil 2", 2015)

Hiernach erkennst du im SCHEMA-Menüpunkt in der Spalte Records die Anzahl der implementierten Items in der Knoten-Klasse Movie.

Schema Manager in der Weboberfläche von OrientDB

Wenn du auf die Knoten-Klasse Movie klickst und auf der daraufhin weitergeleiteten Seite den Button QUERY ALL aktivierst, wird dir die Menge der in der Entität Movie befindlichen Items angezeigt, wie dir der untenstehende Screenshot verbildlicht. Analog dazu würde die Query in der Kommandozeile des BROWSE-Menüpunkts, wie sie ebenfalls im Screenshot unten zu sehen ist, die entsprechende Ergebnismenge liefern.

Treffermenge einer Query in der Weboberfläche von OrientDB

Schließlich stelle ich dir noch die Kommandos zum Befüllen der Entität Genre mit Daten in den folgenden Code-Snippets zur Verfügung.


INSERT INTO Genre(type) VALUES ("Drama")

INSERT INTO Genre(type) VALUES ("Science fiction")

INSERT INTO Genre(type) VALUES ("Tragicomedy")

INSERT INTO Genre(type) VALUES ("Thriller")

Letztlich müssen noch die Relationen zwischen Items der beiden Entitäten Movie und Genre in die Datenbank geschrieben werden. Eine Musteranfrage würde so aussehen, wie im Code-Block unten eingeblendet. Optionale Parameter habe ich mit [ ]-Klammern kenntlich gemacht.


CREATE EDGE edge_name FROM (SELECT FROM Entity1 WHERE Attribute1 = Value1 [AND/OR Attribute2 = Value2 …]) TO (SELECT FROM Entity2 WHERE Attribute1 = Value1 [AND/OR Attribute2 = Value2 …])

Mit Hilfe der folgenden Code-Snippets können die Relationen implementiert werden.


CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "American Hustle") TO (SELECT FROM Genre WHERE type = "Drama")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Passengers") TO (SELECT FROM Genre WHERE type = "Science fiction")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Red Sparrow") TO (SELECT FROM Genre WHERE type = "Drama")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Die Tribute von Panem - The Hunger Games") TO (SELECT FROM Genre WHERE type = "Science fiction")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Die Tribute von Panem - Catching Fire") TO (SELECT FROM Genre WHERE type = "Science fiction")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Die Tribute von Panem - Mockingjay Teil 1") TO (SELECT FROM Genre WHERE type = "Science fiction")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Die Tribute von Panem - Mockingjay Teil 2") TO (SELECT FROM Genre WHERE type = "Science fiction")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Serena") TO (SELECT FROM Genre WHERE type = "Drama")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Silver Linings") TO (SELECT FROM Genre WHERE type = "Tragicomedy")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "House at the End of the Street") TO (SELECT FROM Genre WHERE type = "Thriller")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Joy - Alles außer gewöhnlich") TO (SELECT FROM Genre WHERE type = "Drama")

CREATE EDGE belong_to FROM (SELECT FROM Movie WHERE name = "Winter's Bone") TO (SELECT FROM Genre WHERE type = "Thriller")

Im Anschluss daran ist es möglich in der Kommandozeile des GRAPH-Menüpunkts den dazugehörigen Graph zu plotten. Mit der Anfrage, die du im Code-Block unten siehst, ließe sich dies umsetzen.


SELECT * FROM belong_to

Der Klick auf einen Knoten ermöglicht es dir, diesen zu editieren, z.B. dahingehend, dass du bestimmen kannst, welche Eigenschaft des Knotens im Graphen letztlich abgebildet werden soll.

Graph Editor in der Weboberfläche von OrientDB

Des Weiteren bietet dir die Weboberfläche von OrientDB im SECURITY-Menüpunkt die Option Nutzer anzulegen und diesen spezielle Rechte zuzuweisen, wie z.B. Admin-, Lese und/oder Schreibrechte.

In der Weboberfläche von OrientDB Benutzer managen

Zudem ist es im FUNCTIONS-Tab möglich, benutzerdefinierte ausführbare Code-Einheiten zu definieren und zur Wiederverwendbarkeit für deine Abfragen zu speichern. Der Code übernimmt Parameter aus der Datenbank. Die auf Code-Basis erstellten Funktionen sind persistent. Sie sind in der Datenbank gespeichert und können von jedem Client aufgerufen werden. Du kannst derzeit Funktionen in den Sprachen SQL und JavaScript schreiben. Weitere Programmiersprachen sind in Planung.

In der Weboberfläche von OrientDB Funktionen managen

Fazit

Du hast einen Einblick in die wichtigsten Features von OrientDB bekommen und weißt nun, wie du die Datenbank-Plattform auf deinem Ubuntu-Server lauffähig machst. Vielleicht habe ich dich während der Simulation des Anwendungsszenarios auf ein paar Ideen für zukünftige Projekte gebracht oder du greifst demnächst irgendwann darauf zurück. Ich wünsche dir auf alle Fälle viel Spaß mit OrientDB.

Aus unserer Rubrik zu Open Source Datenbanken und Datenbank-Plattformen auch noch interessant und hilfreich:

Zurück zur Tutorial Übersicht Back to Tutorial Overview

Elasticsearch und der ELK-Stack unter Ubuntu 16.04/18.04

Elastic Stack auf Ubuntu installieren

In der Sammlung unserer Tutorials habe ich dir gezeigt, wie du MySQL, PostgreSQL, MongoDB, Apache Cassandra, Redis, RethinkDB, InfluxDB, Neo4j, ArangoDB und OrientDB unter Ubuntu installierst, einrichtest und erste Schritte damit umsetzt. Ich erweitere die Reihe, indem ich dir die NoSQL-Datenbank-Plattform Elasticsearch vorstelle, dir bei der Installation sowie der Konfiguration helfe und dir ein paar Basics vorführe. Dabei ist wichtig zu berücksichtigen, dass Elasticsearch Teil eines Stacks ist, dem so genannten ELK-Stack. Weitere Bestandteile dieses Stacks sind Logstash und Kibana. Zusätzlich zu den genannten Stack-Elementen dient Nginx zur Lastenverteilung und Reverse-Proxy-Authentifizierung für Elasticsearch, weswegen ich eines der folgenden Kapitel zusätzlich dessen Installation und Konfiguration widme.

Zu Elasticsearch und dem ELK-Stack

Als REST-basierte Such- und Analytik-Engine macht Elasticsearch für dich die Suche und Analyse deiner Daten in Echtzeit möglich. Es lassen sich viele Arten von Suchanfragen durchführen und kombinieren und somit Daten großflächig erfassen.
Elasticsearch verwendet standardmäßige RESTful APIs und JSON, arbeitet schemalos und dokumentenorientiert. Intern legt Elasticsearch die Dokumente in Indizes ab, wobei unter einem Index beliebig viele Dokumente unterschiedlichen Typs abgelegt werden können.
Logstash wirkt im Stack als Pipeline zum Sammeln, Verarbeiten und Weiterleiten von Ereignissen. Kibana baut als browserbasierte Open-Source-Analyseplattform auf der Suchmaschine Elasticsearch auf und ermöglicht u.a. die Suche und Visualisierung der in Elasticsearch-Indizes enthaltenen Daten.

Voraussetzung

Du musst Java auf deinem Server installieren. Eine Anleitung hierzu findest du in unserem Tutorial zum Thema Neo4j unter Ubuntu 16.04/18.04 installieren und einrichten.

Installation und Konfiguration von Elasticsearch

Gewährleiste mittels dem folgenden Kommando, dass dein Server up to date ist.

apt-get update && apt-get upgrade

Dann lädst du den GPG-Key zu Elasticsearch herunter.

wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

Im Anschluss daran fügst du das Repository von Elasticsearch mit folgendem Befehl hinzu. Solltest du eine andere Versionsnummer von Elasticsearch installieren möchten, dann kannst du diese im untenstehenden Kommando entsprechend anpassen.

echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list

Führe mit dem neuen Repository ein Update auf deinem Server durch.

apt-get update

Schließlich installierst du daraufhin Elasticsearch.

apt-get -y install elasticsearch

Danach ist es notwendig in den beiden Konfigurationsdateien /etc/default/elasticsearch und /etc/elasticsearch/elasticsearch.yml jeweils eine Anpassung vorzunehmen. Zunächst öffnest du die Erstere der Beiden mit dem Kommando unten im nano-Editor.

nano /etc/default/elasticsearch

Unterhalb der Headline fügst du dann als neuen Inhalt den unten eingeblendeten Code hinzu.

START_DAEMON=true

Der folgende Screenshot zeigt dir, wie dies am Ende aussehen soll.

Editierte Konfigurationsdatei von Elasticsearch unter /etc/default/elasticsearch

Nach diesem Update speicherst du die Konfigurationsdatei mit der Tastenkombination Strg+O, bestätigst die Speicherung mit der Taste Enter und verlässt den Editor dann mit der Tastenkombination Strg+X.

Als nächstes öffnest du die Zweite der beiden Konfigurationsdateien im nano-Editor,

nano /etc/elasticsearch/elasticsearch.yml

scrollst darin bis zur Network-Sektion und machst die Zeile ausfindig, in der die Information zu network.host hinterlegt ist. Im Screenshot unten ist diese farblich hervorgehoben.

Konfigurationsdatei von Elasticsearch unter /etc/elasticsearch/elasticsearch.yml

Du entfernst die Raute zu Beginn der Zeile, um diese wieder rein zu kommentieren und änderst diese Information entsprechend in localhost um, wie im Code-Snippet unten und im darauf folgenden Screenshot zu sehen.

network.host: localhost

Editierte Konfigurationsdatei von Elasticsearch unter /etc/elasticsearch/elasticsearch.yml

Schließlich speicherst und verlässt du den nano-Editor auf dieselbe Weise wie in der Konfigurationsdatei zuvor. Restarte den Service von Elasticsearch und füge diesen dem Boot mit Hilfe der beiden folgenden Kommandos hinzu.

service elasticsearch restart
systemctl enable elasticsearch

Verifiziere danach mit dem unten eingeblendeten Befehl den Status dieses Service.

service elasticsearch status

Dabei sollte dir folgendes Output im Terminal wiedergegeben werden, das dir bestätigt, dass der Service aktiv ist.

● elasticsearch.service - Elasticsearch
   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-07-31 08:07:28 CEST; 7h ago
     Docs: http://www.elastic.co
 Main PID: 7025 (java)
   CGroup: /system.slice/elasticsearch.service
           ├─7025 /usr/bin/java -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiating
           └─7106 /usr/share/elasticsearch/modules/x-pack/x-pack-ml/platform/linux-x86_64/bin/controller

Jul 31 08:07:28 server-ou11tvdq systemd[1]: Started Elasticsearch.
lines 1-10/10 (END)

Installation und Konfiguration von Kibana

Zur Installation von Kibana führst du auf deinem Server im Terminal zunächst das Kommando aus, das wir dir im betreffenden Tutorial zum Thema Kibana auf Ubuntu installieren im Kapitel Kibana installieren zeigen. Daraufhin ist es notwendig in der Konfigurationsdatei von Kibana eine Anpassung vorzunehmen. Öffne diese Datei im nano-Editor

nano /etc/kibana/kibana.yml

und machst die Zeile ausfindig, in der die Information zu server.host hinterlegt ist, wie im unten präsentierten Screenshot farblich hervorgehoben.

Konfigurationsdatei von Kibana

Kommentiere diese Information wieder ein und mache sie zugänglich, indem du die davorstehende Raute entfernst. Das Ergebnis entnimmst du dem folgenden Screenshot.

Editierte Konfigurationsdatei von Kibana

Hiernach speicherst du die Konfigurationsdatei mit der Tastenkombination Strg+O, bestätigst die Speicherung mit der Taste Enter und verlässt den Editor mit der Tastenkombination Strg+X. Um den Installations- und Konfigurationsprozess zu finalisieren, befolgst du die Terminal-Befehle, wie ich sie dir im Tutorial Kibana auf Ubuntu installieren im Kapitel Kibana als Service starten bereitstelle.

Installation und Konfiguration von Nginx

Nun installierst du Nginx mit dem folgenden Kommando

apt-get install nginx

und entfernst daraufhin die default-Konfiguration.

rm /etc/nginx/sites-enabled/default

Auch im Fall von Nginx musst du eine Anpassung an der Konfiguration vornehmen. Hierzu öffnest du die im Code-Snippet ersichtlich werdende Datei im nano-Editor

nano /etc/nginx/sites-available/kibana

und befüllst diese mit dem Code, den du im Code-Block unten siehst. Hierbei fügst du Nginx Config Reverse Proxy auf Port 80 zu Kibana Port 5601 hinzu. Speichere dies und beende die Editierung, indem du den nano-Editor verlässt.

server {
    listen 80;
    location / {
        proxy_pass http://localhost:5601;  
    }
}

Erstelle im Anschluss daran eine symbolische Verbindung zur nginx-Konfiguration.

ln -s /etc/nginx/sites-available/kibana /etc/nginx/sites-enabled/kibana

Schließlich führst du dann noch die beiden unten vorgegebenen Kommandos im Terminal aus, um zu gewährleisten, dass Nginx auf deinem Server aktiv ist.

systemctl restart nginx
systemctl status nginx

Installation und Konfiguration von Logstash

Abschließend installierst du Logstash.

apt -y install logstash

Öffne hiernach die Konfigurationsdatei im nano-Editor

nano /etc/logstash/conf.d/logstash-simple.conf

und füge eine benutzerdefinierte logstash-Konfiguration hinzu, indem die den Code in die Datei einbindest, den ich dir im untenstehenden Code-Snippet zur Verfügung stelle. Speichere wie gewohnt das von dir durchgeführte Update und verlasse den nano-Editor.

input { 
    tcp {
        port => 514
        type => syslog
    }
    udp {
        port => 514
        type => syslog
    }
}
 
 
   
 
 
output {
  elasticsearch {
    hosts => ["localhost"]
  }
 
}

Schließe Java von privilegierten Ports aus, denn es kann Port 514 verwenden, der auf Ubuntu privilegiert ist.

setcap cap_net_bind_service=+epi /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java

Je nachdem wie du Java installiert hast, kann der Java-Pfad bei dir anders sein, als der im oben gezeigten Code-Snippet. Wäre dies der Fall, müsstest du diesen entsprechend im oben eingeblendeten Kommando anpassen.

Mit dem folgende Befehl

which java

oder alternativ

whereis java

könntest du den symbolischen Link herausfinden, der wiederrum weiterführend Aufschluss zum Standort bzw. zum Pfad der aktuellen jre-Datei geben könnte. In der Regel sollte es sich bei diesem symbolischen Link um /usr/bin/java handeln. Das unten aufgeführte Kommando würde dir dazu dienen, den korrekten Pfad deiner Java-Distribution ausfindig zu machen.

readlink -f /usr/bin/java

Letztlich führst du im Terminal dann noch die drei folgenden Befehle aus, um zu verifizieren, dass Logstash auf deinem Server aktiv ist.

systemctl restart logstash
systemctl enable logstash
systemctl status logstash

Getting started mit Kibana

Die browserbasierte Open-Source-Analyseplattform von Kibana erreichst du, nachdem du meine Installations- und Konfigurations-Tipps aus den vorherigen Kapiteln befolgt hast und dann im Browser http://localhost/app/kibana eingibst. Hierbei tauscht du localhost mit der IP deines Servers aus.
Dem unten eingeblendeten Screenshot entnimmst du die Startseite, auf der du die Features verbildlicht durch Icons übersichtlich aufgeführt hast und diese rasch erreichen kannst. Eine Anmeldung zur Plattform ist nicht notwendig.

Startseite von Kibana

In der Dokumentation von Elasticsearch findest du u.a. Informationen zur Nutzung von Kibana. Über das Console-Icon auf der Startseite oder analog dazu über den Menüpunkt DevTools gelangst du zur Konsole, in der du sämtliche Queries, die von Elasticsearch interpretiert werden können, ausführen kannst. Beginnt deine Query mit GET, dann möchtest du Daten einlesen und dir wiedergeben lassen. Beginnt diese jedoch mit POST, dann fügst du Daten hinzu. Startet deine Query mit PUT, erstellst du Daten und mit DELETE leitest du die Löschung von Daten ein.
In der linken Seite der Konsole kannst du deine Query formulieren und ausführen. Auf der rechte Seite entnimmst du das auf die Query generierte Output.

Kibana-Console

Um die Graph-Funktion von Kibana zu nutzen, musst du sicherstellen, dass du eine Testlizenz bekommen kannst. Hierzu kannst du die Konsole von Kibana nutzen. Dort gibst du zunächst den untenstehenden Code ein

GET _xpack/license/trial_status

und führst diesen aus, sodass dein Output dem gleicht, wie im folgenden Screenshot auf der rechten Hälfte der Konsole veranschaulicht.

Status der Testlizenz via Kibana-Console prüfen

Danach führst du folgenden Code via Kibana-Konsole aus,

POST _xpack/license/start_trial?acknowledge=true

sodass du in der Konsole zur Rechten das Output erhältst, das dir der Screenshot unten präsentiert.

Testlizenz via Kibana-Console bekommen

Zur weiteren Nutzung der Konsole:
Bei den Indizierungs-, Such-, Aktualisierungs- und Löschoperationen beziehst du dich immer auf den Namen eines Index, da Dokumente in Elasticsearch unter Indexen geführt werden. Unter ein und demselben Index kann eine beliebige Menge von Dokumenten enthalten sein. Ein Index dient in der Regel zur Sammlung von Dokumenten mit einem ähnlichen Merkmal und somit zur eindeutigen Identifikation dieser. Ein Dokument als Informationseinheit wird im JSON-Format ausgedrückt.

Gefolgt auf einen Index kannst du die Information zum Typ in deine Query mit aufnehmen. Ein Typ ist eine logische Kategorie/Partition eines Index. Für ein und denselben Index kann mehr als ein Typ definiert werden. Zusätzlich kannst du in deiner Query die ID des Index mit angeben. Beim Typ und der ID handelt es sich um zwei Arten von Meta-Feldern. Informationen zu allen verfügbaren Meta-Feldern für deine Queries entnimmst der Dokumentation von Elasticsearch.

Elasticsearch macht es möglich einen Index in mehrere Teile zu zerlegen, die wiederum Shards genannt werden. Jeder Shard ist an sich ein voll funktionsfähiger und eigenständiger Index, der auf jedem Knoten innerhalb des Clusters gehostet werden kann.

Würdest du über die Konsole einen Index erstellen, könnte die Query z.B. folgender Syntax folgen, wie du sie im Code-Snippet unten erkennst.

PUT index

Würdest du bei der Query Meta-Felder, wie de Typ und die ID einsetzen, könntest du den Index spezifizieren und eine Property oder eine beliebige Menge an Properties definieren.

PUT index/type/id
{
  "property1": type1,
  "property2": type2,
  …
}

Zur Veranschaulichung habe ich beispielhaft einen Datensatz angelegt, wie du dem Code im unten präsentierten Snippet entnimmst. Das Dokument unter der ID 1010 gehört dem Index auto an. Ich könnte nun im Nachgang weitere Dokumente zu diesem Index erstellen, indem ich diese alle durch unterschiedliche IDs voneinander differenzierbar mache.

PUT auto/_doc/1010
{
  "year_of_construction": 2013,
  "color": "white",
  "brand": "Audi"
}

Wenn ich daraufhin im Menü den Punkt Management aufrufe und dort den Button Index Management betätige, werden mir alle in der Datenbank befindlichen Indexe aufgelistet, wie du im Screenshot unten erkennst. Beim Klick auf einen Index wird zur Rechten eine Übersicht zur Informationsstruktur im Dokument bereitgestellt. Wie dir der Screenshot unten zeigt, kann man im Tab Mapping nachvollziehen, wie die Felder im Dokument definiert sind.

Index Management in Kibana

Alternativ zu oben vorgeführten Query zum auto-Index hätte ich auch folgende Syntax nutzen können, in der ich explizit das Mapping antriggere.

PUT index/type/id
{
  "mappings": {
    "doc": { 
      "properties": { 
        "property1": {"type": data type1}, 
        "property2": {"type": data type2}, 
        ...
      }
    }
  }
}

Beim Mapping wird festgelegt, wie ein Dokument und die darin enthaltenen Felder gespeichert und indiziert werden. Hiermit lassen sich die Felder im Dokument definieren. Eine Übersicht zu den Parametern, die beim Mapping verwendet werden, und zu den Strukturen, die ein Mapping haben kann, bietet dir die Dokumentation von Elasticsearch.

Die oben eingeblendete Syntax in Anwendung auf die zuvor vorgeführte Query zum auto-Index, sähe so aus, wie du im Code-Block unten siehst.

PUT auto/_doc/1010
{
  "mappings": {
    "doc": { 
      "properties": { 
           "year_of_construction": 2013,
           "color": "white",
           "brand": "Audi"
      }
    }
  }
}

Wie ich dir bereits mitgeteilt habe, gelangst du an in der Datenbank befindliche Daten, indem du deine Query mit GET beginnst. Eine einfach gestrickte Query könnte der Syntax folgen, wie du sie unten siehst.

GET index

Soll deine Query ausgereifter ausfallen, kannst du Einfluss auf die Treffermenge nehmen, indem du auf Basis bestimmter Felder suchst (Stichwort: query), auf Basis bestimmter Felder aggregierst (Stichwort: aggs), auf Basis bestimmter Felder (Stichwort: sort) sortierst und/oder bestimmte Felder in Skripten adressierst (Stichwort: script_fields).

GET index/_search
{
  "query": {
    ...
  },
 "aggs": {
    ...
  },
  "sort": [
    ...
  ],
  "script_fields": {
    ...
  }
}

Beim Löschen eines Index verwendest du die Syntax, wie sie im Code-Snippet unten zu sehen ist.

DELETE index

Fazit

Die Installation und Konfiguration der Komponenten des ELK-Stacks haben wir zusammen gemeistert. Ich habe dir die Basics der Nutzung der Konsole in der Weboberfläche von Kibana gezeigt und dir dabei die Syntax der Elasticsearch-Queries nahe gebracht. Eine detaillierte und umfangreiche Dokumentation bietet dir hierzu Elasticsearch selbst, sodass du einen jederzeit abrufbaren Leitfaden bei der Realisierung deiner Projekte hast.

Aus unserer Rubrik zu Open Source Datenbanken und Datenbank-Plattformen auch noch interessant und hilfreich:

Zurück zur Tutorial Übersicht Back to Tutorial Overview

Apache CouchDB unter Ubuntu 16.04/18.04 installieren und einrichten

CouchDB auf Ubuntu installieren

Datenbanken und Datenbank-Plattformen wie MySQL, PostgreSQL, MongoDB, Apache Cassandra, Redis, RethinkDB, InfluxDB, Neo4j, ArangoDB, OrientDB sowie Elasticsearch und deren Installation und Konfiguration unter einem Ubuntu-Server sowie deren wichtigste Features, haben wir dir bereits in einer Reihe unserer Tutorials vorgestellt.
Apache CouchDB zählt wie die oben genannten Datenbanken und Datenbank-Plattformen mit zu den Meistgenutzten und ich möchte dir in diesem Tutorial helfen, diese zu installieren, einzurichten und erste Schritte als Nutzer dieser Datenbank durchzuführen.

Zu Apache CouchDB

Apache CouchDB ist ein relationales und dokumentenorientiertes NoSQL-Datenbankmanagementsystem, das von der Apache Software Foundation entwickelt wurde. CouchDB wurde das erste Mal in 2015 veröffentlicht und ist 2008 zu einem Apache Projekt geworden. Du kannst mit einer einzelnen CouchDB-Instanz beginnen und anspruchsvollere Projekte nahtlos auf einen Cluster aktualisieren. Anders als bei einem konventionellen relationalen Datenbankmanagementsystem werden die Daten und Relationen bei Apache CouchDB nicht in Tabellen, Zeilen und Spalten gespeichert, sondern jede Datenbank ist eine Sammlung unabhängiger Dokumente. Jedes Dokument erhält seine eigenen Daten, die im JSON-Format gespeichert werden. Die Queries werden in JavaScript durchgeführt. Apache CouchDB nutzt das HTTP-Protokoll für seine bereitgestellte API. Über diese REST-HTTP-Schnittstelle sind Daten erreichbar. Zusätzlich macht Fauxton, die Web-Benutzeroberfläche von Apache CouchDB, diese leistungsstark und einfach zu verwalten. Apache CouchDB bietet Merge-Replikation als Feature, was dir ermöglicht, mehrere Instanzen gleichzeitig und unabhängig voneinander zu betreiben.

Installation von Apache CouchDB

Füge Apache CouchDB Repository zu Ubuntu hinzu, indem du die im Code-Snippet unten präsentierten Befehle ausführst, um den Repository-Schlüssel und das Repository addest

curl -L https://couchdb.apache.org/repo/bintray-pubkey.asc  | apt-key add -

Wenn dein Server auf Ubuntu 16.04 läuft, dann nutze weiter folgendes Kommando.

echo "deb https://apache.bintray.com/couchdb-deb xenial main"  | tee -a /etc/apt/sources.list.d/apache_couchdb_xenial.list

Andernfalls, wenn 18.04 die Version deines Ubuntu-Servers ist, setze folgendes Kommando im Terminal um.

echo "deb https://apache.bintray.com/couchdb-deb bionic main"  | tee -a /etc/apt/sources.list.d/apache_couchdb_bionic.list

Führe auf deinem Server ein Update durch

apt update

und führe im Anschluss daran folgenden Befehle aus, um Apache CouchDB zu installieren.

apt-get install apache2 couchdb

Während der Installation wirst du dann automatisch zur Konfiguration via Interface aufgefordert, wie im Screenshot unten zu sehen. Hierbei bestätigst du zunächst mit der Enter-Taste.

Konfiguration während Installation von Apache CouchDB starten

Für die Server-Konfiguration kannst du entweder „standalone“ oder „clustered“ wählen. Solltest du diese von Grund auf selbst konfigurieren wollen, bietet sich „none“ als Auswahl an.

Typ der Konfiguration während Installation von Apache CouchDB festlegen

Im nächsten Abschnitt kannst du eine Schnittstelle auswählen, an die CouchDB bindet. Per default ist hierfür die IP 127.0.0.1 vorgesehen. Wenn du möchtest, dass dein Apache CouchDB-Panel über das Internet zugänglich ist, trage „0.0.0.0“ in die vorgesehene Zeile ein, wie im Screenshot unten zu erkennen.

IP-Adresse des Web-Interface während Installation von Apache CouchDB starten

Schließlich wirst du dann noch gebeten ein Passwort als admin-Nutzer festzulegen.

Passwort während Installation von Apache CouchDB festlegen

Nachdem der Installationsvorgang abgeschlossen ist, führe die drei unten stehenden Kommandos aus, um Apache CouchDB zu starten.

systemctl stop couchdb.service
systemctl start couchdb.service
systemctl enable couchdb.service

Du kannst den Status des Dienstes mit den folgenden Befehlen überprüfen.

systemctl status couchdb
netstat -ln | grep 5984

Getting started mit Apache CouchDB via Fauxton UI

Nachdem du die Anleitung im vorherigen Kapitel durchgeführt hast, kannst du in deinem Browser http://localhost:5984/_utils/ eingeben, wobei du localhost mit der IP deines Servers austauscht. Daraufhin solltest du die Anmeldeseite der Fauxton UI sehen, wie im Screenshot unten verbildlicht. Hier meldest du dich dann unter dem Nutzer admin und dem während der Installation im Interface festgelegten Passwort an, um Zugriff zu bekommen.

Anmeldeseite von Fauxton

Unter dem Databases-Menüpunkt hast du eine Liste der in Apache CouchDB existierenden Datenbanken. _replicator und _users gehören zu default-Datenbanken.

Databases-Menüpunkt in Fauxton

Via dem Create Database-Button oben rechts, wie im Screenshot unten präsentiert, ist es dir möglich den Namen einer neuen Datenbank festzulegen und diese anzulegen.

In Fauxton eine Datenbank adden

In meinem Beispiel habe ich die Datenbank test_db hinzugefügt.
Oben rechts befinden sich weitere Buttons. Mit dem { } JSON-Button lassen sich die Datenbank-Prozesse in JSON-Format überführen. Der darauf folgende Dokument-Button führt zu online verfügbaren Dokumentation von Apache CouchDB. Schließlich erhälst du über das Glocken-Icon eine Übersicht der Vorgänge, die in der Datenbank stattgefunden haben. Es werden sozusagen alle Vorgänge im Sinne von Benachrichtigungen gleich einem Verlauf abrufbar gemacht.

Databases-Menüpunkt in Fauxton

Wenn ich nun auf meine eben erzeugte Datenbank test_db klicke, gelange ich auf die Seite der Datenbank, in der ich u.a. die Möglichkeit habe der Datenbank Dokumente hinzuzufügen und nach diesen via Query zu suchen.

Mittels dem Create Document-Button gelangst du zu einem Editor, in dem du das Dokument mit Inhalt im JSON-Format definieren kannst. Im Screenshot unten siehst du, dass zu diesem Zeitpunkt noch nichts erstellt wurde. Das Dokument besteht per default zunächst nämlich lediglich aus einem JSON-Objekt und einer ID mit einem Globally Unique Identifier (GUID). Du kannst dem JSON-Objekt nun eine beliebige Anzahl an Elementen hinzufügen.

Fazit

Du hast gesehen, wie schnell und unkompliziert es möglich ist Apache CouchDB auf deinem Ubuntu-Server zu installieren und dass hierfür keine weiteren Voraussetzungen nötig sind. Mit Fauxton stellt dir Apache CouchDB eine einfache Web-Oberfläche für das Management von Datenbanken, die Implementierung von Daten in diese und deren Abrufbarkeit via Query zur Verfügung, sowie den direkten Zugang zur Dokumentation von Apache CouchDB. Ich wünsche dir viel Erfolg bei der Umsetzung deiner Projekte.

Aus unserer Rubrik zu Open Source Datenbanken und Datenbank-Plattformen auch noch interessant und hilfreich:

Zurück zur Tutorial Übersicht Back to Tutorial Overview