Cassandra- und NoSQL-Basics, Teil 3

So funktionieren Abfragen in Apache Cassandra

| Autor / Redakteur: Thomas Drilling / Nico Litzel

Das Logo der NoSQL-Datenbank Cassandra
Das Logo der NoSQL-Datenbank Cassandra (Bild: The Apache Software Foundation)

Die NoSQL-Datenbank Cassandra ist als skalierbares, ausfallsicheres System für den Umgang mit großen Datenmengen auf verteilten Systemen (Clustern) konzipiert. Im dritten Teil geht es um das Arbeiten mit Cassandra.

Hier geht es zu Teil 1 „Grundlagen der NoSQL-Datenbank Apache Cassandra“ und hier zu Teil 2 „So funktioniert Cassandra“.

Cassandra ist eine Datenbank, welche die einzelnen Datensätze in sogenannten multidimensionalen Hashtables ablegt und verwaltet. Eine Besonderheit dabei ist, dass jede Zeile eines Hashtables eine oder sogar beliebig viele Spalten haben kann. Insofern besteht Ähnlichkeit mit einer Relation in einem RDBMS oder, einfach ausgedrückt, einer riesigen Excel-Tabelle. Diese Spalten müssen aber nicht in jeder Zeile gleich sein, wie bei einer Relation in einem RDBMS. Identifiziert wird jede Zeile eines Hashtable über eine eindeutige ID. Man kann sich Cassandra also als zeilenorientierten, indizierten Store vorstellen.

Cassandras Datenmodell

Allerdings muss sich der Entwickler zu Beginn eines Projektes keinerlei Gedanken, machen, welche Art Daten er mit Cassandra speichern und verwalten will, da intern sämtliche Daten der beschriebenen Form eines multidimensionalen Hashtable verwaltet werden. In diesem Punkt ist das Datenmodell von Cassandra wieder eher mit einem Document-Store zur Aufnahme weitgehend unstrukturierter Daten vergleichbar, zumal der Nutzer jederzeit neue Spalten hinzufügen kann. Einige Merkmale und Begrifflichkeiten dürften aber auch für SQL-erfahrene Datenbank-Administratoren neu sein.

Keyspaces

Ferner gibt es im Datenmodell von Cassandra sogenannte Keyspaces. Mit Keyspaces wird die Datenhaltung in X-Richtung von der in Y-Richtung unterteilt. Darüber hinaus gibt es Column Families. Diese fassen Columns und so genannte Super Columns zusammen, allerdings entweder nur Columns oder Super Columns, nicht beide gleichzeitig. Erst dann kommt der Key, die eindeutige ID, wobei jeder Key auf einen eindeutigen Eintrag innerhalb einer Column Family verweist.

Keyspaces sind übrigens der einzige eindeutige Index im Datenmodell von Cassandra. Das eigentliche Speichern der Daten passiert dann entweder in Columns oder Super Columns. Bei einer Column speichert Cassandra zu je einem Namen einen Wert und den zugehörigen Key. Eine Super Column kann man sich als Organisationseinheit vorstellen, die hierarchisch eine Stufe oberhalb der Column angeordnet ist.

Folgendes Beispiel macht es deutlicher. Beim Speichern eines Adressdatensatzes „Users“ entsprächen die Einträge

„Privateadress: Hauptstr. 1“, „businessadress: Siemensstr. 2 “ und „postaladress: Poststr. 3“

einer Column, wobei eine Super Column mit dem Namen „adresses“ existieren könnte.

Das ist bei der einfachen Struktur von Key-Value Stores die einzige Möglichkeit, 1:n-Beziehungen direkt in einer Datenstruktur abzubilden und physisch zu speichern, während bei SQL-Datenbanken bekanntlich Joins zum Einsatz kämen. Joins stellen aber bei sehr großen Datenmengen ein Performanceproblem dar, da die Laufzeit viel zu lang ist.

Abfragen

Ohne SQL-Queries kann man mit Cassandra auch keine Abfragen im eigentlichen Sinne durchführen. Hier kommt MapReduce in Spiel, was nichts anderes bedeutet, als das Reduzieren der Gesamtdatenmenge auf den gewünschten Umfang. Das erfolgt über ein API.

NoSQL-Datenbanken speichern die Daten immer so ab, wie sie auch wieder abgerufen werden sollen, also sortiert. Das Prinzip „Sortierung folgt dem Anwendungszweck“ ist bei NoSQL-Datenbanken maßgeblich für die hohe Geschwindigkeit, während die Sortierung bei SQL ja erst im Zuge einer Query stattfindet.

Cassandra von der Kommandozeile

How-Tos und Anleitungen zum Installieren von Cassandra findet man im Internet zuhauf. Auf die relativ gut dokumentierte und vergleichsweise einfache Installation eines Cassandra-Datenbankknotens soll hier nicht weiter eingegangen werden. Eine hervorragende und umfassende Dokumentation zu Cassandra einschließlich der Installation findet sich z. B. bei Tutorialspoint.

Zu Evaluierungszwecken kann man sogar auf eine komplexe Cluster-Installation verzichten. Grundlegende Einstellungen speichert Cassandra in den Dateien storage-conf.xmlundcassandra.in.sh. Letztere ist dann für den Betrieb mehrerer Cassandra-Nodes mit der gleichen Datenbank essenziell.

Prinzipiell lässt sich die aktuelle Version 2.2.1 relativ einfach per

wget http://www.us.apache.org/dist/cassandra/2.2.1/apache-cassandra-2.2.1-bin.tar.gz

in einem Rutsch als gepacktes Archiv vom Server des Projektes in einem temporären Ordner herunterladen, entpacken und dann im gewünschten Verzeichnis platzieren. Hat man die von Cassandra benötigte Umgebung zuvor durch

  • Einrichten der JVM
  • Setzen einiger Umgebungsvariablen
  • und Anlegen der von Cassandra erwarteten Verzeichnisse

vorbereitet, lässt sich ein lokaler Cassandra-Knoten nach dem Anpassen einiger weniger Konfigurationseinträge bzw. dem Ausführen von

~/cassandra/conf/cassandra-env.sh

mit

sudo sh ~/cassandra/bin/cassandra

z. B. unter Ubuntu recht einfach starten.

Cassandra-Client

In älteren Cassandra-How-Tos findet sich häufig noch der Hinweis, den zugehörigen CLI-Client z. B. auf dem gleichen Host mit

sh ~/cassandra/bin/ cassandra-cli -h localhost -p 9160

aufzurufen. Er lässt sich für Aufgaben im Zusammenhang mit Data Definition (DDL) und Data Manipulation (DML) verwenden. Für Datenabfragen, wie man sie von MySQL & Co. kennt (MapReduce-Prinzip), ist/war er nicht gedacht.

Allerdings ist das Cassandra-CLI noch ein Überbleibsel aus der Zeit, bevor es die SQL-ähnliche Abfragesprache CQL gab. Die Cassandra-Entwickler empfehlen unbedingt, zur CQL-Shell cqlsh zu wechseln. Diese unterstützt alles, was auch mit der CLI möglich war.

Cqlsh

Eine aktuelle Cassandra-Version stellt per Default die Cassandra query language shell (cqlsh) zur Kommunikation mit dem Cassandra-Server zur Verfügung. Mit cqlsh lassen sich Schemas definieren, Daten einfügen und Abfragen absetzen. Zum Starten der Shell genügt die Eingabe von

cqlsh

womit man automatisch beim Cassandra cqlsh prompt landet. Das sieht dann z. B. an einem Linux-Rechner so aus:

[hadoop@linux bin]$ cqlsh

Connected to Test Cluster at 127.0.0.1:9042.

[cqlsh 5.0.1 | Cassandra 2.1.2 | CQL spec 3.2.0 | Native protocol v3]

Use HELP for help.

cqlsh

Hinweis: Cassandra generiert bei der Installation automatisch einen entsprechendes Cluster mit dem Namen Test Cluster, mit dem sich cqlsh automatisch verbindet. Für erste Gehversuche tut es im Zweifel aber auch eine Online-Demo mit einer CQL Shell, wie sie z. B. Planet Cassandra zur Verfügung steht. Das Eingeben von

help

liefert den zur Verfügung stehenden Befehlsvorrat, gruppiert nach Document shell commands und cql-Befehlen. Zum Verlassen der Shell dient

quit

oder

exit

Die cqlsh-Shell und der zur Verfügung stehende Befehlsvorrat.
Die cqlsh-Shell und der zur Verfügung stehende Befehlsvorrat. (Planet Cassandra, Thomas Drilling)

Keyspaces

Beim Anlegen einer neuen Datenbank sind zuerst Container, bei Cassandra Keyspaces genannt, einzurichten, was in etwa dem Schema in einer relationalen Datenbank entspricht. Der Keyspace funktioniert wie ein Namespace für die Datenbankanwendung und kapselt die darin enthaltenen Daten in Form von Column Families, Tables und Konfigurationen. Zum Erstellen eines Keyspace „demo“ gibt man in der Cassandra-CLI

CREATE KEYSPACE demo WITH replication = {

'class': 'SimpleStrategy',

'replication_factor': '1'

};

ein. Um den neuen Keyspace zu verwenden, genügt dann ein

USE demo;

Der Prompt ändert sich dann damit zu

: cqlsh:demo>

Jetzt ist es möglich, in diesem Keyspace, Tables, bzw. Column Families anzulegen, die wiederum aus Columns und Rows bestehen können. Das Erstellen einer Tabelle users im keyspace demo, in dem dann letztendlich die Daten abgelegt werden, erfolgt dann mit

CREATE TABLE users (

firstname text,

lastname text,

age int,

email text,

city text,

PRIMARY KEY (lastname));

Damit hat man eine Tabelle mit einem einfachen primären Schlüssel lastname kreiert.

Diese Vorgehensweise zum Erstellen einer Table oder Column Family, bei der man bereits vorher die Struktur der Datenbank und der einzelnen Attribute kennt, heißt statisch.

Cassandra kennt aber auch die o. g. dynamischen Column Families. Hier werden beim Erstellen der Column Family keine Spaltendefinitionen angegeben. Vielmehr werden diese dann von der Applikation selbst generiert.

Um die einzelnen Attribute der Tabelle Users anzuzeigen, genügt das Eingeben von

DESCRIBE TABLE users;

Um erste Zeilen mit Daten in der Users-Tabelle einzufügen, dient z. B. derINSERT INTO-Befehl. Hierbei ist nach jedem Statement ENTER zu drücken, um die neue Zeile in die Tabelle zu übernehmen.

INSERT INTO users (firstname, lastname, age, email, city) VALUES ('Thomas', 'Drilling', 48, 'info@thomas-drilling.de', 'Kassel');

INSERT INTO users (firstname, lastname, age, email, city) VALUES ('Max', 'Muster', 39, 'max@muster.com', 'Augsburg');

usw. Ein

SELECT * FROM users;

liefert dann sämtliche Inhalte der Tabelle users sortiert nach „lastname“, der ja als Primärschlüssel fungiert.

Das Anzeigen von Daten in CQL
Das Anzeigen von Daten in CQL (Planet Cassandra, Thomas Drilling)

Mit dem WHERE-Kommando in Verbindung mit dem SELECT-Statement, lässt sich gezielt nach einem Wert fahnden.

SELECT * FROM users WHERE lastname= 'Drilling';

Abfragen in CQL
Abfragen in CQL (Planet Cassandra, Thomas Drilling)

Hier wird die gewollte Ähnlichkeit zu SQL sichtbar. Da Cassandra keine reinen Read-Operationen „vor“, bzw. „ohne“ Write-Operation kennt, führen INSERT und UPDATE beide zu einer Aktualisierung des betreffenden Spaltenwertes, egal ob bereits Daten existieren.

Das UPDATE-Kommando kommt z. B. zum Einsatz, um Änderungen unter Zuhilfenahme des Primärschlüssels zu übernehmen. Soll für den Eintrag lastname=Drilling (Primärschlüssel) der Wert für City aktualisiert werden, klappt das mit

UPDATE users SET city= 'Frankfurt' WHERE lastname= 'Drilling';

Die Aktualisierung lässt sich wie gehabt mit

SELECT * FROM users WHERE lastname= 'Drilling';

übernehmen. Zum Löschen einer Spalte dient das DELETE-Kommando:

DELETE from users WHERE lastname = 'Drilling';

Auch das kann mit wie folgt überprüft werden.

SELECT * FROM users;

Kommentare werden geladen....

Kommentar zu diesem Artikel abgeben

Der Kommentar wird durch einen Redakteur geprüft und in Kürze freigeschaltet.

Anonym mitdiskutieren oder einloggen Anmelden

Avatar
Zur Wahrung unserer Interessen speichern wir zusätzlich zu den o.g. Informationen die IP-Adresse. Dies dient ausschließlich dem Zweck, dass Sie als Urheber des Kommentars identifiziert werden können. Rechtliche Grundlage ist die Wahrung berechtigter Interessen gem. Art 6 Abs 1 lit. f) DSGVO.
  1. Avatar
    Avatar
    Bearbeitet von am
    Bearbeitet von am
    1. Avatar
      Avatar
      Bearbeitet von am
      Bearbeitet von am

Kommentare werden geladen....

Kommentar melden

Melden Sie diesen Kommentar, wenn dieser nicht den Richtlinien entspricht.

Kommentar Freigeben

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

Freigabe entfernen

Der untenstehende Text wird an den Kommentator gesendet, falls dieser eine Email-hinterlegt hat.

copyright

Dieser Beitrag ist urheberrechtlich geschützt. Sie wollen ihn für Ihre Zwecke verwenden? Infos finden Sie unter www.mycontentfactory.de (ID: 43734755 / Infrastruktur)