Data Access & Storage

Cosmos DB in eigenen Projekten einsetzen: Grundlagen und Einsatzszenarien

Ganz ir-relational

Thorsten Kansy

Dokumentendatenbanken wie Microsofts Cloud-basierte Azure Cosmos DB bieten neue Ansätze und Möglichkeiten, um mit Daten umzugehen – zumindest neu für die Microsoft-Entwicklerwelt, die von relationalen Datenbanken dominiert wurde.

Dieser Artikel gibt Ihnen einen kleinen Überblick über die Grundlagen, Möglichkeiten und unterstützten APIs, die Azure Cosmo DB für Ihre Projekte bereitstellt und bietet Überlegungen zu möglichen Einsatzszenarien an.

Einführung

Microsofts Azure Cosmos DB ist eine Dokumentendatenbank, ein NoSQL JSON Data Storage, das neben einer ganzen Reihe interessanter Features mehrere APIs bietet, um mit diesen zu arbeiten. „NoSQL“ steht dabei übrigens für „Not only SQL“, was einen Hinweis auf die unterschiedlichen APIs darstellt.

Dabei ist der Ansatz, Daten zu speichern, ein völlig anderer als z. B. bei relationalen Datenbanken. So werden Daten nicht in Tabellen abgelegt, sondern in Collections (auch Container genannt). Eine Dokumentendatenbank speichert Daten in Form von Dokumenten im JSON-Format. Dies erlaubt, diese Daten verschachtelt und – und das ist wichtig – heterogen abzuspeichern. Das heißt, Dokumente, die sich einen Container (Collection) teilen, müssen nicht über den gleichen Aufbau verfügen. Es können also mal mehr, mal weniger oder schlicht unterschiedliche Informationen in einem solchen Dokument untergebracht werden. Auch können von Dokument zu Dokument für gleichnamige Eigenschaften unterschiedliche Datentypen verwendet werden. Listing 1 zeigt ein kleines JSON-Dokument als Beispiel. Bei Abfragen wird dies (je nach API) entsprechend berücksichtigt.

Listing 1

  {
  "BusinessEntityID": 1,
  "PersonType": "EM",
  "NameStyle": false,
  "Title": null,
  "FirstName": "Ken",
  "MiddleName": "J",
  "LastName": "Sánchez",
  "Suffix": null,
  "EmailPromotion": 0,
  "AdditionalContactInfo": null,
  "Demographics": "0",
  "rowguid": "92c4279f-1207-48a3-8448-4636514eb7e2",
  "ModifiedDate": "2009-01-07T00:00:00",
  "Password": {
    "Hash": "pbFwXWE99vobT6g+vPWFy93NtUU/orrIWafF01hccfM=",
    "ModifiedDate": "2009-01-07T00:00:00",
    "Salt": "bE3XiWw="
  }
}

 

Für den Zugriff auf diese Daten stehen aktuell fünf unterschiedliche APIs zur Verfügung (mehr dazu später). Existieren also schon Code für und Erfahrung und mit z. B. MongoDB oder Apache Cassandra, steht einem Einsatz von Azure Comos DB eigentlich nichts im Weg. In Abbildung 1 sehen Sie eine Übersicht aller APIs.

 

Abb. 1: Die unterstützten APIs

 

Die unterschiedlichen APIs können dabei prinzipiell alle Dokumente nutzen, die mit Hilfe eines anderen APIs erstellt wurden. In der Praxis gibt es jedoch deutliche Einschränkungen, da z. B. mit dem Gremlin API auch Graphdaten erzeugt werden, deren Strukturen von anderen APIs nicht verstanden werden.

Melden Sie sich für unseren Newsletter an und erfahren Sie als Erster, wann die nächste BASTA! online geht.

Features

Welches sind nun die erwähnten interessanten Features? Als Cloud Service ist Azure Cosmos DB „fully managed“, sodass keinerlei administrative Aufgaben anfallen. Mit einem SLA (Service Level Agreement) garantiert Microsoft eine hohe Verfügbarkeit und schnelle Antwortzeiten mit der Option, bei Bedarf zu skalieren. Eine automatische und für eine Anwendung völlig transparente Verschlüsselung sorgt für die notwendige Sicherheit der Daten.

Globale Verteilung („globally distributed“) erlaubt die Festlegung, in welchem Rechenzentrum die Daten gespeichert werden. Dabei ist vorgesehen, dass dies mehr als nur ein Rechenzentrum ist. Die Infrastruktur im Hintergrund sorgt für die notwendige Replikation. Der Vorteil der globalen Verteilung liegt dabei auf der Hand: Beim Zugriff von Orten weltweit wird das nächstgelegene Replikat verwendet. Anwender z. B. aus Australien greifen damit auf eines der beiden Rechenzentren in Down Under zu (wenn dort ein Replikat konfiguriert wurde). Das betrifft übrigens nicht nur Lese- sondern auch Schreibzugriffe. Abbildung 2 zeigt mit Hexagonen die möglichen Standorte weltweit.

 

Abb. 2: Globale Verteilung

 

ACID-Transaktionen (Atomicity, Consistency, Isolation, Durability) sorgen dafür, dass Änderungen an mehr als nur einem Dokument gemeinschaftlich nach dem Alles-oder-nichts-Prinzip durchgeführt werden. So arbeiten z. B. auch Prozeduren und Trigger im Hintergrund mit Transaktionen, um eine Datenkonsistenz zu gewährleisten.

Um Zugriffe auf Dokumente möglichst schnell auszuführen, verwendet Azure Comos DB Indizes, wie andere Datenbanken auch. Diese werden automatisch erstellt und gepflegt. Dazu werden Abfragen analysiert, und ermittelt, welche Eigenschaften wie oft zum Filtern verwendet werden. Diese automatische Indexierung kann durch Policies beeinflusst werden, funktioniert aber durchaus auch ohne weiteres Zutun.

Tools

Für die Entwicklung mit Cosmos DB existieren schon einige praktische Tools. Als Erstes wäre natürlich das schon erwähnte Azure Portal zu nennen, über das die Datenbanken angelegt und verwaltet werden. Außerdem gibt es über das Portal die Möglichkeit, Daten abzufragen und zu modifizieren (Abb. 3).

 

Abb. 3: Azure Portal

 

Wer bei der Entwicklung auf keine (verlässliche) Verbindung zugreifen kann oder schlicht mögliche Kosten vermeiden möchte, dem steht der Azure-Cosmos-DB-Emulator zur Verfügung (Abb. 4). Dieser Emulator, der natürlich ohne Azure Cloud auskommt, kann wahlweise installiert oder als Docker Image genutzt werden.

 

Abb. 4: Azure-Cosmos-DB-Emulator

 

Zugriffschlüssel und Verbindungszeichenfolgen sind (standardmäßig) für alle Installationen und Docker Images gleich, sodass bei einer Entwicklung im Team kein Sicherheitsproblem auftritt und Entwickler immer wieder Anpassungen vornehmen müssten, um auf die Daten im Emulator zuzugreifen.

Und als Letztes sei da noch das Azure Cosmos DB Migration Tool genannt, mit dem Daten von Quellen in ein Ziel geschrieben werden können. Dabei steht eine Reihe von Formaten für die eine und auch die andere Seite zur Auswahl (Tabelle 1)

DynamoDB
HBase

Quelle Ziel
JSON-Datei JSON-Datei
DocumentDB
– SQL API
– Table API
DocumentDB
– SQL API
– Table API
SQL-Server
CSV
AzureTable
Tabelle 1: Quellen und Ziele des Azure Cosmos DB Migration Tools

 

Da einige Quellen wie z. B. relationale Datenbanken wie SQL Server keine verschachtelten Daten unterstützen, gibt es hier die Option, in der Abfrage Joins zu verwenden und in den Namen der zurückgegebenen Spalten einen „Nesting Seperator“ (z. B. einen Punkt) einzubauen, der für die gewünschte Verschachtelung im Ziel sorgt.

 

Abb. 5: Azure Cosmos DB Migration Tool

 

Als Nebeneffekt lassen sich mit diesem Tool z. B. Daten aus einer SQL-Server-Abfrage in eine JSON-Datei schreiben, was sicherlich das eine oder andere Mal ganz nützlich sein kann.

Sicherheit

Selbstverständlich ist, gerade bei einer Cloud-basierten Technologie, das Thema Sicherheit wichtig. Neben der Sicherheit während des Transports über das Netzwerk mittels SSL/TLS und der Absicherung durch die Anbindung an ein virtuelles Netzwerk bietet Azure Cosmos DB eine Sicherheit, die zwischen nur lesenden und Lese-und-Schreib-Zugriffen unterscheidet (von administrativen Aufgaben einmal abgesehen). Gesteuert wird dies über entsprechende Schlüssel.

Eine differenzierte Kontrolle auf Ebene eines Containers (Collection) oder einzelner Elemente (Dokumente) ist nicht vorgesehen. Dafür muss die Anwendung bei Bedarf selbst sorgen.

Der Data Access & Storage Track auf der BASTA!

APIs

Für Anwendungen stehen fünf APIs zur Auswahl, um auf Azure Cosmos DB zuzugreifen. Ihr Vorteil: Wenn Sie bereits Erfahrung mit einem dieser APIs haben oder sogar bereits fertiger Code existiert, kann dieser mit wenigen (oder sogar keinen) Anpassungen verwendet werden. Beispielsweise verwendet der Zugriff via MongoDB API die gleichen Bibliotheken, die auch zum Einsatz kommen, um auf eine „gewöhnliche“ MongoDB-Installation zuzugreifen.

Angeboten wird also das MongoDB API und damit die Schnittstelle zu einer „klassischen“ Open-Source-Dokumentendatenbank. Mit dem API für Gremlin steht eine Graph-Datenbank zur Verfügung. Eine Graph-Datenbank speichert Informationen in Knotenpunkten und deren Beziehungen untereinander. Damit lassen sich Beziehungsgeflechte in sozialen Netzwerken, Nutzungsprofile und Ähnliches abbilden und abfragen. Das Core (SQL) API bietet die Möglichkeit, Informationen mit einer (einfachen) SQL-Syntax abzurufen. Das Anlegen, Löschen und Verändern von Dokumenten geschieht hingegen via der üblichen HTTP-Verben POST, PUT und DELETE, während die Abfrage selbst ein GET verwendet. Mit dem Table API steht ein Schlüsselwertspeicher (Key-Value-Store) à la Azure Table zur Verfügung. Bei dem „Wert“ kann es sich um komplexe Objekte handeln, die als JSON serialisiert abgelegt werden. Ein Zugriff ist mittels der Schlüssel möglich. Und schließlich wird seit einiger Zeit als neuester Zuwachs das Cassandra API verwendet, das von vielen großen Unternehmen wie GitHub, Ebay, Netflix und auch im CERN eingesetzt wird.

Der Einsatz von Entity Framework Core

Ab Version 2.2 bietet Entity Framework Core das erste Mal in der Geschichte von Microsofts O/R-Mapper die Option, auf nicht relationale Datenbanken zuzugreifen. Im Nuget-Paket Microsoft.EntityFrameworkCore.Cosmos befindet sich der benötigte Code. Allerdings ist der aktuelle Stand der Entwicklung noch nicht so weit, ihn tatsächlich sinnvoll einzusetzen. Dafür gibt es noch zu viele Probleme, Ungereimtheiten und nicht umgesetzte Features. Konsequenterweise ist in der stabilen Version von .NET 2.2 (vom 4. Dezember 2018) die Untersetzung für Azure Cosmos DB entfallen. Diese taucht erst im Preview für .NET 3.0 wieder auf. Dennoch ist es ein Schritt in die richtige Richtung und es bleibt spannend zu sehen, was EF Core 3.0 in dieser Richtung bringen wird.

Funktionen, Prozeduren und Trigger

Azure Comos DB erlaubt die Verwendung von Funktionen, Stored Procedures und Trigger, die in Serverside JavaScript geschrieben werden können. Sämtliche Elemente werden für eine Collection geschrieben; auch Funktionen und Prozeduren gehören also, nicht wie bei SQL Server, zu der gesamten Datenbank.

Funktionen können z. B. mit dem Core (SQL) API verwendet werden, um weitere Möglichkeiten in die Abfragen einzubauen. Werden für eine Abfrage reguläre Ausdrücke benötigt, reicht es, eine einfache Funktion wie im Folgenden zu schreiben:

  function RexExpTest(s, p){
  return s.match(p) != null;
}

Für die Entwicklung bieten sich die üblichen Tools und Wege wie online JavaScript Playgrounds, Visual Studio Code mit Code Runner und viele andere Optionen an. Diese neu geschaffene Funktion kann einfach verwendet werden. Achten Sie dabei auf den Präfix udf, der zwingend notiert werden muss. Die folgende Zeile zeigt die Core-(SQL-)Abfrage:

  SELECT * FROM c WHERE udf.RexExpTest(c.Name, 'Speaker [0-2]') = true

Das abschließende Listing zeigt eine kleine Demo für eine Prozedur, die einen kleinen Text an den Client zurücksendet. Der body legt dabei die Funktionalität fest:

  var helloWorldDemoProc = {
  id: "helloWorldDemo",
  body: function () {
    var context = getContext();
    var response = context.getResponse();
    response.setBody("Hello World!");
  }
}

Gründe für den Einsatz

Die große Frage ist nun nur noch, ob sich der Einsatz einer Dokumentendatenbank, speziell Azure Cosmos DB, im eigenen Projekt lohnt. Diese ist pauschal weder einfach noch überhaupt zu beantworten; es sei denn, der Einsatz der Azure Cloud ist ein No-Go. Wenn Sie bis dato (wie der Autor) Ihre Daten in Tabellen und relationalen Datenbanken gespeichert haben, lohnt sich ein neugieriger Blick auf die anderen Möglichkeiten. Wenn die zu verarbeitenden Daten oft in flexiblen Varianten verarbeitet werden müssen oder wenn sie über Beziehungen verfügen, die in allen (oder den meisten) Use Cases aufgelöst werden müssen, dann bietet sich die Flexibilität von JSON-Dokumenten an. Müssen die Daten immer in der gleichen Form vorliegen, kann sich diese Flexibilität als eher nachteilig erweisen – schließlich muss die Anwendung für feste Vorgaben sorgen.

Der .NET-Framework & C# Track auf der BASTA!

Auf der anderen Seite ist jedoch zu bedenken, dass die APIs aktuell keine partiellen Updates der Dokumente unterstützen. Wenn also ein Dokument auch noch so minimal verändert wird, muss das komplette Dokument übertragen werden. Häufige kleine Änderungen können sich also, gerade bei größeren JSON-Dokumenten (>1 Kilobyte), schlecht auf die Performance auswirken.

Bei nicht so großen, flexiblen Daten oder solchen, die kaum geändert werden müssen, kann NoSQL seine Stärke ausspielen. Das gilt auch für Azure Comos DB mit seinen unterschiedlichen APIs.

Fazit

Azure Cosmos DB im Speziellen und NoSQL-Datenbanken im Allgemeinen sind auf jeden Fall einen Blick wert und bieten Möglichkeiten, die mit relationalen Datenbanken nur schwer realisiert werden können. Praktische Tools bis hin zum Emulator und fertige Beispiele machen den Einstieg leicht.

 

Azure Cosmos DB auf der BASTA!


Passend zum Thema dieses Artikels finden Sie auf der BASTA! z. B. den Power Workshop Azure Cosmos DB von Thorsten Kansy am Freitag.

Top Articles About Data Access & Storage

Ihr aktueller Zugang zur .NET- und Microsoft-Welt.
Der BASTA! Newsletter:

Behind the Tracks

.NET Framework & C#
Visual Studio, .NET, Git, C# & mehr

Agile & DevOps
Agile Methoden, wie Scrum oder Kanban und Tools wie Visual Studio, Azure DevOps usw.

Web Development
Alle Wege führen ins Web

Data Access & Storage
Alles rund um´s Thema Data

JavaScript
Leichtegewichtig entwickeln

UI Technology
Alles rund um UI- und UX-Aspekte

Microservices & APIs
Services, die sich über APIs via REST und JavaScript nutzen lassen

Security
Tools und Methoden für sicherere Applikationen

Cloud & Azure
Cloud-basierte & Native Apps

NIE MEHR BASTA! NEWS VERPASSEN