Azure Cosmos DB mit der MongoDB-API verwenden

Beim Erstellen einer Instanz der Azure Cosmos DB kann man eine Zugriffsschnittstelle angeben - unter anderem die API für MongoDB. Das ist besonders von Vorteil, wenn man in einer bestehenden Anwendung, die MongoDB nutzt, von den Vorteilen einer Cloud-Datenbank profitieren will oder lokal gegen einen MongoDB-Container entwickeln will. Im Folgenden geben wir Tipps, um die Verwendung der API möglichst reibungslos zu starten.

Die API gibt es in mehreren Versionen

Ältere Azure Cosmos DB-Instanzen unterstützen die Version 3.2 oder 3.4 des MongoDB-Protokolls; neue Instanzen können mit Version 3.6 des Protokolls aufgesetzt werden. Leider gibt es momentan noch keine Möglichkeit, eine ältere Instanz auf die neue Schnittstellenversion 3.6 umzustellen. Hierfür ist bisher eine Datenmigration in eine neue Instanz notwendig. Laut diesem Blogeintrag arbeitet Microsoft jedoch daran, dies auch für bestehende Instanzen bereit zu stellen.

Führt man sich vor Augen, dass das aktuelle Release von MongoDB die Versionsnummer 4.2 trägt, sind natürlich Unterschiede in den verfügbaren Möglichkeiten zu erwarten. Aus unserer Projekterfahrung kommt man mit den beiden Versionen für viele Anwendungsfälle schon einmal sehr weit. Insbesondere dann, wenn man besonders effiziente Statements schreiben will und erweiterte Möglichkeiten von MongoDB nutzen will, stößt man mitunter jedoch an die ein oder andere Grenze.
Vor allem bei der Migration einer bestehenden Anwendung sollte man sich also informieren, welche MongoDB-Version momentan in der Anwendung genutzt wird, um sich Überraschungen zu ersparen.

Die API ist eine Emulation

Neben den Unterschieden in der Version ist zu beachten, dass es sich bei der Schnittstelle um eine Emulation handelt und die Cosmos DB nicht im Hintergrund mit einer "echten" MongoDB arbeitet. Auch hieraus entstehen einige Abweichungen, die auf folgenden Seiten dokumentiert sind:

Übrigens resultieren Abfragen, die nicht unterstützte Befehle verwenden, nicht immer in einer Fehlermeldung. Insofern empfiehlt es sich, die genannten Artikel im Hinterkopf zu behalten, um bei unerwartetem Verhalten nachschlagen zu können.

Erstellung von Indizes

Ein Feature der Azure Cosmos DB ist, dass alle Eigenschaften automatisch indiziert werden. Dies gilt jedoch nicht für die MongoDB-API (abgesehen vom _id-Feld). Entscheidet man sich bei Einrichtung der Instanz für diese Schnittstelle, so ist es notwendig, Indizes für weitere Felder manuell zu definieren, um von den Performance-Vorteilen bei der Abfrage zu profitieren.
Einen genauen Überblick bietet der Artikel Indizieren mit der API für MongoDB von Azure Cosmos-DB.

Request Units

Zur Leistungsabrechnung verwendet Azure Cosmos DB sogenannte Request Units. Dieser Wert drückt aus, wie aufwändig die Bearbeitung einer Abfrage ist. Bei der Einrichtung einer Datenbank oder Collection reserviert man eine bestimmte Anzahl von Request Units pro Sekunde, die bei Abfragen gegen den Container bereit gestellt werden. Wird dieses Kontingent durch die Abfragen eines Systems überschritten, so führt das zum Abbruch einer oder mehrerer Abfragen mit dem Hinweis, dass diese später wiederholt werden sollten.

Die SQL API für Azure Cosmos DB bietet im Gegensatz zur MongoDB-API den Vorteil, dass diese Retry-Logik bereits in der Client-Bibliothek integriert ist und man diese aus Entwicklersicht ohne weiteres nutzen kann. Der MongoDB-Driver für C# enthält derart spezifischen Code für Azure Cosmos DB (natürlich) nicht, so dass man die entsprechende Logik selbst integrieren muss, wenn man gegen das Request-Limit läuft.

Im Gegensatz zu anderen Preismodellen ist die Abrechnung über die Request Unit-Kontingente natürlich erst einmal schwer zu greifen, so dass eine genaue Analyse der Datenbankstatements notwendig ist. Andere APIs liefern die Request Units, die durch eine Abfrage verbraucht werden, in den Metadaten zurück; in der API für MongoDB hat Microsoft mit dem speziellen Kommando getLastRequestStatistics die Möglichkeit geschaffen, den Wert auszulesen. Dieses Kommando kann in einer mongo Shell ausgeführt werden:

db.runCommand({ "getLastRequestStatistics": 1 })

Bei der Verwendung des MongoDB-Drivers für C# kann das Kommando auch aus dem Programmcode ausgeführt werden.

Zur Reduzierung der verbrauchten Request Units hilft die Anpassung des Dokumentenschemas an die Abfragen. Im Gegensatz zu relationalen Datenbanken ist es bei Dokumentendatenbanken ohnehin üblich, mehrere Arten von Dokumenten in einer Collection zu verwalten, wenn dies dem Abfrageschema entgegen kommt. Durch die Reservierung des Request Unit-Kontingents auf Ebene der Datenbank und Collection bietet es sich bei Azure Cosmos DB an, die Anzahl der Container gering zu halten, um Kosten zu sparen.
Auch das Setzen der richtigen Indizes unterstützt dabei, die Request Units zu reduzieren, die eine Abfrage verbraucht.

Ausprobieren

Auch wenn es um Datenbanken geht, gilt natürlich, dass alle Theorie grau und praktische Erfahrung immer von Vorteil ist. Glücklicherweise ist es mittlerweile einfach möglich, diese mit Azure Cosmos DB zu sammeln. Wie, das beschreibt Microsoft im Artikel Optimieren der Entwicklungs- und Testkosten in Azure Cosmos DB.


Online-Programm

Basierend auf unserer langjährigen Erfahrung im Developer Coaching haben wir folgendes Programm für Sie zusammengestellt:

Professional .NET-Developer Programm

.NET & .NET Core Projekte durch bewährte Vorgehensweisen und stabile Strukturen erfolgreich meistern

Nächster Lauf ab 04.11.2020