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.