Leistungstipps für das Azure Cosmos DB Java SDK v4

GILT FÜR: SQL-API

Wichtig

Die Leistungstipps in diesem Artikel gelten ausschließlich für das Azure Cosmos DB Java SDK v4. Weitere Informationen finden Sie in den Versionshinweisen zum Azure Cosmos DB Java SDK v4, im Maven-Repository und im Leitfaden zur Problembehandlung für das Azure Cosmos DB Java SDK v4. Wenn Sie aktuell eine ältere Version als v4 verwenden, lesen Sie den Leitfaden Migrieren zum Azure Cosmos DB Java SDK v4, um Hilfe beim Upgrade auf v4 zu erhalten.

Azure Cosmos DB ist eine schnelle und flexible verteilte Datenbank mit nahtloser Skalierung, garantierter Latenz und garantiertem Durchsatz. Die Skalierung Ihrer Datenbank mit Azure Cosmos DB erfordert weder aufwendige Änderungen an der Architektur noch das Schreiben von komplexem Code. Zentrales Hoch- und Herunterskalieren ist ebenso problemlos möglich wie das Aufrufen einer einzelnen API oder SDK-Methode. Da der Zugriff auf Azure Cosmos DB jedoch über Netzwerkaufrufe erfolgt, können Sie bei der Verwendung des Azure Cosmos DB Java SDK v4 clientseitige Optimierungen vornehmen, um eine optimale Leistung zu erzielen.

Wenn Sie sich also fragen, wie Sie die Leistung Ihrer Datenbank verbessern können, sollten Sie die folgenden Optionen in Betracht ziehen:

Netzwerk

  • Verbindungsmodus: Verwenden des direkten Modus

Als Standardverbindungsmodus des Java SDK wird der direkte Modus verwendet. Sie können den Verbindungsmodus im Client-Generator mithilfe der Methode directMode() oder gatewayMode() wie unten gezeigt konfigurieren. Um einen der beiden Modi mit den Standardeinstellungen zu konfigurieren, rufen Sie beide Methoden ohne Argumente auf. Andernfalls übergeben Sie eine Konfigurationseinstellungs-Klasseninstanz als Argument (DirectConnectionConfig für directMode() und GatewayConnectionConfig für gatewayMode()). Weitere Informationen zu verschiedenen Konnektivitätsoptionen finden Sie im Artikel zu den Konnektivitätsmodi.

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API


/* Direct mode, default settings */
CosmosAsyncClient clientDirectDefault = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .directMode()
        .buildAsyncClient();

/* Direct mode, custom settings */
DirectConnectionConfig directConnectionConfig = DirectConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
directConnectionConfig.setMaxConnectionsPerEndpoint(120);
directConnectionConfig.setIdleConnectionTimeout(Duration.ofMillis(100));

CosmosAsyncClient clientDirectCustom = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .directMode(directConnectionConfig)
        .buildAsyncClient();

/* Gateway mode, default settings */
CosmosAsyncClient clientGatewayDefault = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .gatewayMode()
        .buildAsyncClient();

/* Gateway mode, custom settings */
GatewayConnectionConfig gatewayConnectionConfig = GatewayConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
gatewayConnectionConfig.setProxy(new ProxyOptions(ProxyOptions.Type.HTTP, InetSocketAddress.createUnresolved("your.proxy.addr",80)));
gatewayConnectionConfig.setMaxConnectionPoolSize(150);

CosmosAsyncClient clientGatewayCustom = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .gatewayMode(gatewayConnectionConfig)
        .buildAsyncClient();

/* No connection mode, defaults to Direct mode with default settings */
CosmosAsyncClient clientDefault = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .buildAsyncClient();

Die Methode directMode() verfügt aus dem folgenden Grund über eine zusätzliche Außerkraftsetzung: Vorgänge auf Steuerungsebene, z. B. Datenbank- und Container-CRUD, verwenden immer den Gatewaymodus. Wenn der Benutzer den direkten Modus für Vorgänge auf Datenebene konfiguriert hat, werden die Standardeinstellungen für den Gatewaymodus verwendet. Dies ist für die meisten Benutzer geeignet. Benutzer, die den direkten Modus für Datenebenenvorgänge verwenden und Gatewaymodusparameter anpassen möchten, können jedoch die folgenden directMode() -Außerkraftsetzung verwenden:

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API


/* Independent customization of Direct mode data plane and Gateway mode control plane */
DirectConnectionConfig directConnectionConfig = DirectConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
directConnectionConfig.setMaxConnectionsPerEndpoint(120);
directConnectionConfig.setIdleConnectionTimeout(Duration.ofMillis(100));

GatewayConnectionConfig gatewayConnectionConfig = GatewayConnectionConfig.getDefaultConfig();

// Example config, do not use these settings as defaults
gatewayConnectionConfig.setProxy(new ProxyOptions(ProxyOptions.Type.HTTP, InetSocketAddress.createUnresolved("your.proxy.addr",80)));
gatewayConnectionConfig.setMaxConnectionPoolSize(150);

CosmosAsyncClient clientDirectCustom = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .directMode(directConnectionConfig,gatewayConnectionConfig)
        .buildAsyncClient();

  • Platzieren Sie Clients in derselben Azure-Region, um die Leistung zu verbessern.

Platzieren Sie nach Möglichkeit sämtliche Anwendungen, die Azure Cosmos DB aufrufen, in der gleichen Region wie die Azure Cosmos-Datenbank. Damit Sie einen ungefähren Vergleich haben: Azure Cosmos DB-Aufrufe aus derselben Region werden normalerweise innerhalb von 1 bis 2 ms abgeschlossen, während die Latenz zwischen West- und Ostküste der USA >50 ms beträgt. Diese Latenz variiert ggf. von Anforderung zu Anforderung und ist abhängig von der Route, die die Anforderung zwischen dem Client und der Grenze des Azure-Datencenters nimmt. Die geringste Latenz erzielen Sie, wenn sich die aufrufende Anwendung in der gleichen Azure-Region wie der bereitgestellte Azure Cosmos DB-Endpunkt befindet. Eine Liste mit den verfügbaren Regionen finden Sie unter Azure-Regionen.

Illustration of the Azure Cosmos DB connection policy

Eine App, die mit einem Azure Cosmos DB-Konto in mehreren Regionen interagiert, muss bevorzugte Regionen konfigurieren, um sicherzustellen, dass Anforderungen in eine angegebene Region weitergeleitet werden.

  • Aktivieren des beschleunigten Netzwerkbetriebs auf Ihrer Azure-VM für geringere Wartezeit

Es wird empfohlen, dass Sie die Anweisungen zum Aktivieren des beschleunigten Netzwerkbetriebs für Ihre Windows- oder Linux-VM befolgen (für Anweisungen jeweils klicken), um die Leistung zu maximieren.

Ohne den beschleunigten Netzwerkbetrieb können E/A-Vorgänge zwischen Ihrer Azure-VM und anderen Azure-Ressourcen unnötigerweise über einen Host und einen virtuellen Switch zwischen der VM und dessen Netzwerkkarte weitergeleitet werden. Wenn sich der Host und der virtuelle Switch inline auf dem Datenpfad befinden, sorgt dies beim Kommunikationskanal nicht nur für eine längere Wartezeit und Jitter, sondern auch die CPU-Zyklen von der VM werden reduziert. Bei beschleunigtem Netzwerkbetrieb erstellt die VM ohne Vermittler direkt Schnittstellen mit der Netzwerkkarte. Alle Netzwerkrichtliniendetails, die zuvor vom Host und dem virtuellen Switch verarbeitet wurden, werden jetzt über die Hardware der Netzwerkkarte verarbeitet, und der Host und der virtuelle Switch werden umgangen. Im Allgemeinen sind eine kürzere und konsistentere Wartezeit, ein höherer Durchsatz und eine geringere CPU-Auslastung zu erwarten, wenn Sie den beschleunigten Netzwerkbetrieb aktivieren.

Einschränkungen: Der beschleunigte Netzwerkbetrieb muss vom Betriebssystem der VM unterstützt werden und kann nur aktiviert werden, wenn die VM beendet und ihre Zuordnung aufgehoben wurde. Die VM kann nicht mit dem Azure Resource Manager bereitgestellt werden.

Weitere Informationen finden Sie in den Anweisungen für Windows bzw. Linux.

SDK-Verwendung

  • Installieren des neuesten SDKs

Azure Cosmos DB-SDKs werden ständig verbessert, um eine optimale Leistung zu ermöglichen. Informationen zum neuesten SDK und zu den Verbesserungen finden Sie auf den Seiten unter Azure Cosmos DB SDK.

  • Verwenden eines Singleton-Azure Cosmos DB-Clients für die Lebensdauer der Anwendung

Jede Azure Cosmos DB-Clientinstanz ist threadsicher und verfügt über eine effiziente Verbindungsverwaltung und Adressenzwischenspeicherung. Es empfiehlt sich, für die gesamte Lebensdauer der Anwendung pro Anwendungsdomäne nur eine einzelne Azure Cosmos DB-Clientinstanz zu verwenden, um eine effiziente Verbindungsverwaltung und bessere Leistung des Azure Cosmos DB-Clients zu ermöglichen.

  • Verwenden der niedrigsten für die Anwendung erforderlichen Konsistenzebene

Wenn Sie eine CosmosClient-Klasse erstellen, wird Sitzung als Standardkonsistenz festgelegt, falls keine andere explizite Angabe gemacht wird. Wenn die Konsistenz Sitzung für Ihre Anwendungslogik nicht erforderlich ist, legen Sie die Konsistenz auf Letztlich fest. Hinweis: Es wird empfohlen, mindestens Sitzung für die Konsistenz bei Anwendungen zu verwenden, die den Azure Cosmos DB-Änderungsfeedprozessor verwenden.

  • Verwenden der Async-API zum Ausschöpfen des bereitgestellten Durchsatzes

Das Azure Cosmos DB Java SDK v4 bündelt die APIs „Sync“ und „Async“. Grob gesagt implementiert die Async-API SDK-Funktionen, während die Sync-API ein einfacher Wrapper ist, der blockierende Aufrufe der Async-API durchführt. Dies steht im Kontrast zum älteren Azure Cosmos DB Async Java SDK v2, das nur die Async-API enthielt, und dem älteren Azure Cosmos DB Sync Java SDK v2, das lediglich die Sync-API enthielt und eine vollständig unterschiedliche Implementierung erforderte.

Die Auswahl der API wird während der Clientinitialisierung getroffen. Eine CosmosAsyncClient-Klasse unterstützt die Async-API, während die CosmosClient-Klasse die Sync-API unterstützt.

Die Async-API implementiert nicht blockierende E/A-Vorgänge und ist die beste Wahl, wenn Sie den Durchsatz beim Ausgeben von Anforderungen an Azure Cosmos DB voll ausschöpfen möchten.

Die Verwendung der Sync-API eignet sich, wenn Sie eine API benötigen, die die Antwort auf jede Anforderung blockiert, oder wenn im Zusammenhang mit Ihrer Anwendung hauptsächlich der synchrone Vorgang verwendet wird. Sie verwenden beispielsweise die Sync-API, wenn Sie Daten für Azure Cosmos DB in einer Microserviceanwendung beibehalten und der Durchsatz nicht entscheidend ist.

Beachten Sie, dass der Durchsatz der Sync-API mit zunehmender Anforderungsantwortzeit geringer wird, während mit der Async-API die vollständige Bandbreitenkapazität Ihrer Hardware genutzt werden kann.

Bei Verwendung der Sync-API ermöglicht eine geografische Kollokation einen höheren und konsistenteren Durchsatz (siehe Bereitstellen von Clients in derselben Azure-Region für eine bessere Leistung), der Durchsatz der Async-API wird jedoch nicht erreicht.

Einige Benutzer sind möglicherweise auch nicht mit Project Reactor vertraut. Dabei handelt es sich um das Reactive Streams-Framework, das zum Implementieren der Async-API des Azure Cosmos DB Java SDK v4 verwendet wird. Wenn dies ein Problem darstellt, empfiehlt es sich, den Einführungsleitfaden zu Reactor-Mustern durchzulesen und sich mithilfe dieser Einführung in das reaktive Programmieren damit vertraut zu machen. Wenn Sie Azure Cosmos DB bereits mit einer Async-Schnittstelle verwendet haben und es sich bei dem verwendeten SDK um das Azure Cosmos DB Async Java SDK v2 gehandelt hat, sind Sie möglicherweise mit ReactiveX/RxJava vertraut, sind sich aber nicht sicher, was sich bei Project Reactor geändert hat. Sehen Sie sich in diesem Fall unseren Leitfaden mit dem Vergleich von Reactor und RxJava an.

Die folgenden Codeausschnitte zeigen, wie Sie Ihren Azure Cosmos DB-Client für Async- oder Sync-API-Vorgänge initialisieren:

Java V4 SDK

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API


CosmosAsyncClient client = new CosmosClientBuilder()
        .endpoint(HOSTNAME)
        .key(MASTERKEY)
        .consistencyLevel(CONSISTENCY)
        .buildAsyncClient();

  • Optimieren von ConnectionPolicy

Bei Verwendung des Azure Cosmos DB Java SDK v4 erfolgen Cosmos DB-Anforderungen im direkten Modus standardmäßig über TCP. Intern verwendet der direkte Modus eine spezielle Architektur, um Netzwerkressourcen dynamisch zu verwalten und die beste Leistung zu erzielen.

Im Azure Cosmos DB Java SDK v4 ist der direkte Modus die beste Wahl, um die Datenbankleistung bei den meisten Workloads zu verbessern.

  • Übersicht über den direkten Modus

Illustration of the Direct mode architecture

Die clientseitige Architektur, die im direkten Modus eingesetzt wird, ermöglicht vorhersagbare Netzwerkauslastungen und Multiplexzugriff auf Azure Cosmos DB-Replikate. Das obige Diagramm zeigt, wie Clientanforderungen im direkten Modus an Replikate im Cosmos DB-Back-End weitergeleitet werden. Bei der Architektur für den direkten Modus werden auf der Clientseite bis zu 10 Kanäle pro DB-Replikat zugeordnet. Ein Kanal ist eine TCP-Verbindung mit einem vorgeschalteten Anforderungspuffer, der 30 Anforderungen aufnehmen kann. Die zu einem Replikat gehörenden Kanäle werden nach Bedarf dynamisch vom Dienstendpunkt des Replikats zugeordnet. Wenn der Benutzer eine Anforderung im direkten Modus übermittelt, leitet der TransportClient die Anforderung basierend auf dem Partitionsschlüssel an den richtigen Dienstendpunkt weiter. In der Anforderungswarteschlange werden die Anforderungen vor dem Dienstendpunkt gepuffert.

  • Konfigurationsoptionen für den direkten Modus

Wenn ein nicht standardmäßiges Verhalten beim direkten Modus gewünscht ist, erstellen Sie eine DirectConnectionConfig-Instanz, passen Sie deren Eigenschaften an, und übergeben Sie die angepasste Eigenschafteninstanz dann an die Methode directMode() im Azure Cosmos DB-Client-Generator.

Diese Konfigurationseinstellungen steuern das Verhalten der zugrunde liegenden Architektur des weiter oben behandelten direkten Modus.

Verwenden Sie als ersten Schritt die folgenden empfohlenen Konfigurationseinstellungen. Diese DirectConnectionConfig-Optionen sind erweiterte Konfigurationseinstellungen, die sich auf unerwartete Weise auf die SDK-Leistung auswirken können. Es wird empfohlen, dass Benutzer diese nicht ändern, es sei denn, sie kennen die möglichen Auswirkungen und dies ist absolut notwendig. Wenden Sie sich an das Azure Cosmos DB-Team, wenn Sie mit diesem speziellen Thema Probleme haben.

Konfigurationsoption Standard
idleConnectionTimeout „PT0“
maxConnectionsPerEndpoint „130“
connectTimeout „PT5S“
idleEndpointTimeout „PT1H“
maxRequestsPerConnection „30“
  • Aufskalieren Ihrer Clientworkload

Wenn Sie auf einem hohen Durchsatzniveau testen, kann sich die Clientanwendung als Engpass erweisen, da der Computer die CPU- oder Netzwerkauslastung deckelt. Wenn dieser Punkt erreicht wird, können Sie das Azure Cosmos DB-Konto weiter auslasten, indem Sie Ihre Clientanwendungen auf mehrere Server horizontal hochskalieren.

Eine gute Faustregel ist, eine CPU-Auslastung von >50 Prozent auf einem beliebigen Server nicht zu überschreiten, um die Wartezeit gering zu halten.

  • Verwenden des geeigneten Planers (Vermeiden des Diebstahls von Eventloop-E/A-Threads in Netty)

Die asynchrone Funktionalität des Azure Cosmos DB Java SDK basiert auf nicht blockierenden E/A-Vorgängen in Netty. Das SDK verwendet eine feste Anzahl (die Anzahl von CPU-Kernen Ihres Computers) von E/A-Eventloop-Threads in Netty zum Ausführen von E/A-Vorgängen. Das von der API zurückgegebene Flux-Objekt gibt das Ergebnis auf einem der freigegebenen E/A-Eventloop-Threads in Netty aus. Daher ist es wichtig, die freigegebenen E/A-Eventloop-Threads in Netty nicht zu blockieren. CPU-intensives Arbeiten oder das Blockieren von Vorgängen auf dem E/A-Eventloop-Thread in Netty kann einen Deadlock verursachen oder den SDK-Durchsatz deutlich reduzieren.

Beispiel: Der folgende Code führt eine CPU-intensive Arbeit auf dem E/A-Eventloop-Thread in Netty aus:

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API


Mono<CosmosItemResponse<CustomPOJO>> createItemPub = asyncContainer.createItem(item);
createItemPub.subscribe(
        itemResponse -> {
            //this is executed on eventloop IO netty thread.
            //the eventloop thread is shared and is meant to return back quickly.
            //
            // DON'T do this on eventloop IO netty thread.
            veryCpuIntensiveWork();
        });


Wenn Sie nach dem Empfang des Ergebnisses CPU-intensive Arbeit am Ergebnis durchführen möchten, sollte diese nicht auf dem E/A-Eventloop-Thread in Netty erfolgen. Stattdessen können Sie einen eigenen Planer bereitstellen, um wie unten gezeigt einen eigenen Thread für die Ausführung Ihrer Arbeit zur Verfügung zu stellen (erfordert import reactor.core.scheduler.Schedulers).

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API


Mono<CosmosItemResponse<CustomPOJO>> createItemPub = asyncContainer.createItem(item);
createItemPub
        .subscribeOn(Schedulers.elastic())
        .subscribe(
                itemResponse -> {
                    //this is executed on eventloop IO netty thread.
                    //the eventloop thread is shared and is meant to return back quickly.
                    //
                    // DON'T do this on eventloop IO netty thread.
                    veryCpuIntensiveWork();
                });

Je nach Art der Arbeit müssen Sie den entsprechenden vorhandenen Reactor-Planer verwenden. Lesen Sie hier nach: Schedulers.

Weitere Informationen zum Azure Cosmos DB Java SDK v4 finden Sie im Azure Cosmos DB-Verzeichnis des Azure SDK für Java-Monorepos auf GitHub.

  • Optimieren der Protokollierungseinstellungen in Ihrer Anwendung

Aus verschiedenen Gründen kann es erforderlich sein, die Protokollierung in einem Thread hinzuzufügen, der einen hohen Anforderungsdurchsatz verursacht. Wenn das Ziel darin besteht, den bereitgestellten Durchsatz eines Containers mit den von diesem Thread generierten Anforderungen vollständig auszuschöpfen, kann die Leistung mithilfe von Protokollierungsoptimierungen erheblich verbessert werden.

  • Konfigurieren einer Async-Protokollierung

Die Wartezeit einer synchronen Protokollierung ist notwendigerweise ein Faktor der Berechnung der Gesamtwartezeit des Threads, der Anforderungen generiert. Eine asynchrone Protokollierung wie log4j2 wird empfohlen, um den Protokollierungsaufwand von Hochleistungsanwendungsthreads zu entkoppeln.

  • Deaktivieren der Netty-Protokollierung

Die Netty-Bibliotheksprotokollierung führt zu übermäßiger Kommunikation und muss deaktiviert werden (das Unterdrücken der Anmeldung in der Konfiguration reicht möglicherweise nicht aus), um zusätzliche CPU-Kosten zu vermeiden. Wenn Sie sich nicht im Debuggingmodus befinden, deaktivieren Sie die Protokollierung von Netty vollständig. Wenn Sie also „log4j“ verwenden, um die zusätzlichen CPU-Kosten zu verhindern, die durch org.apache.log4j.Category.callAppenders() von Netty anfallen, fügen Sie Ihrer Codebasis die folgende Zeile hinzu:

org.apache.log4j.Logger.getLogger("io.netty").setLevel(org.apache.log4j.Level.OFF);
  • Ressourcengrenzwert des Betriebssystems für geöffnete Dateien

Einige Linux-Systeme (z. B. Red Hat) haben eine Obergrenze für die Anzahl von offenen Dateien und damit für die Gesamtanzahl von Verbindungen. Führen Sie den folgenden Befehl aus, um die aktuellen Grenzwerte anzuzeigen:

ulimit -a

Die Anzahl von geöffneten Dateien (nofile) muss groß sein, damit ausreichend Platz für Ihre konfigurierte Verbindungspoolgröße und andere offene Dateien des Betriebssystem vorhanden ist. Sie kann geändert werden, um einen größeren Verbindungspool zu ermöglichen.

Öffnen Sie die Datei „limits.conf“:

vim /etc/security/limits.conf

Ändern Sie die folgenden Zeilen, bzw. fügen Sie sie hinzu:

* - nofile 100000
  • Angeben von Partitionsschlüsseln in Punktschreibvorgängen

Geben Sie beim API-Aufruf mit Punktschreibvorgängen wie unten gezeigt Elementpartitionsschlüssel an, um die Leistung zu verbessern:

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API

asyncContainer.createItem(item,new PartitionKey(pk),new CosmosItemRequestOptions()).block();

Geben Sie also nicht wie unten gezeigt nur die Elementinstanz an:

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API

asyncContainer.createItem(item).block();

Die letztere Option wird unterstützt, erhöht aber die Wartezeit Ihrer Anwendung. Das SDK muss das Element analysieren und den Partitionsschlüssel extrahieren.

Abfragevorgänge

Informationen zu Abfragevorgängen finden Sie in den Leistungstipps für Abfragen.

Indizierungsrichtlinie

  • Beschleunigen von Schreibvorgängen durch Ausschließen nicht verwendeter Pfade von der Indizierung

Die Indizierungsrichtlinie von Azure Cosmos DB ermöglicht auch die Verwendung von Indizierungspfaden („setIncludedPaths“ und „setExcludedPaths“), um anzugeben, welche Dokumentpfade in die Indizierung ein- bzw. von der Indizierung ausgeschlossen werden sollen. Der folgende Code zeigt beispielsweise, wie Sie ganze Abschnitte der Dokumente (auch als Unterstruktur bezeichnet) mit dem Platzhalter „*“ bei der Indizierung ein- und ausschließen.

Java SDK V4 (Maven com.azure::azure-cosmos)


CosmosContainerProperties containerProperties = new CosmosContainerProperties(containerName, "/lastName");

// Custom indexing policy
IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);

// Included paths
List<IncludedPath> includedPaths = new ArrayList<>();
includedPaths.add(new IncludedPath("/*"));
indexingPolicy.setIncludedPaths(includedPaths);

// Excluded paths
List<ExcludedPath> excludedPaths = new ArrayList<>();
excludedPaths.add(new ExcludedPath("/name/*"));
indexingPolicy.setExcludedPaths(excludedPaths);

containerProperties.setIndexingPolicy(indexingPolicy);

ThroughputProperties throughputProperties = ThroughputProperties.createManualThroughput(400);

database.createContainerIfNotExists(containerProperties, throughputProperties);
CosmosAsyncContainer containerIfNotExists = database.getContainer(containerName);

Weitere Informationen finden Sie unter Indizierungsrichtlinien für Azure Cosmos DB.

Throughput

  • Messen und Optimieren (Senken) der Anzahl von Anforderungseinheiten pro Sekunde

Azure Cosmos DB bietet vielfältige Datenbankvorgänge (einschließlich relationaler und hierarchischer Abfragen mit UDFs, gespeicherter Prozeduren und Trigger), die alle in den Dokumenten innerhalb einer Datenbanksammlung ausgeführt werden. Die Kosten im Zusammenhang mit diesen Vorgängen variieren basierend auf dem CPU-, E/A- und Speicheraufwand, der für den jeweiligen Vorgang erforderlich ist. Anstelle sich Gedanken über Hardwareressourcen und deren Verwaltung zu machen, können Sie sich eine Anforderungseinheit (RU) als alleinige Maßeinheit für die Ressourcen vorstellen, die für das Durchführen der verschiedenen Datenbankvorgänge und das Ausführen einer Anwendungsanforderung erforderlich sind.

Der Durchsatz wird basierend auf der für jeden Container festgelegten Anzahl von Anforderungseinheiten bereitgestellt. Der Verbrauch von Anforderungseinheiten wird als Rate pro Sekunde bemessen. Anwendungen, die die bereitgestellte Anforderungseinheitenrate für ihre Container überschreiten, werden begrenzt, bis die Rate wieder unter das bereitgestellte Niveau für den Container fällt. Wenn Ihre Anwendung einen höheren Durchsatz erfordert, können Sie ihn durch Bereitstellung zusätzlicher Anforderungseinheiten erhöhen.

Die Komplexität einer Abfrage wirkt sich darauf aus, wie viele Anforderungseinheiten für einen Vorgang verbraucht werden. Die Anzahl von Prädikaten, die Art der Prädikate, die Anzahl von UDFs und die Größe des Quelldatasets beeinflussen die Kosten von Abfragevorgängen.

Untersuchen Sie zum Ermitteln des Indizierungsaufwands für einen beliebigen Vorgang (Erstellen, Aktualisieren oder Löschen) den Header x-ms-request-charge. So ermitteln Sie die Anzahl von Anforderungseinheiten, die von diesen Vorgängen genutzt werden. Sie können sich außerdem die entsprechende RequestCharge-Eigenschaft in ResourceResponse<T> oder FeedResponse<T> ansehen.

Java SDK V4 (Maven com.azure::azure-cosmos) Async-API

CosmosItemResponse<CustomPOJO> response = asyncContainer.createItem(item).block();

response.getRequestCharge();

Bei der in diesem Header zurückgegebenen Anforderungsbelastung handelt es sich um einen Bruchteil Ihres bereitgestellten Durchsatzes. Falls Sie beispielsweise 2000 RU/s bereitgestellt und die obige Abfrage 1000 Dokumente mit einer Größe von 1 KB zurückgibt, fallen für den Vorgang Kosten in Höhe von 1000 an. Somit werden vom Server innerhalb einer Sekunde nur zwei solcher Anforderungen berücksichtigt, und für weitere Anforderungen wird die Rate begrenzt. Weitere Informationen finden Sie unter Anforderungseinheiten in DocumentDB sowie unter dem Rechner für Anforderungseinheiten.

  • Behandeln von Ratenbeschränkungen/zu hohen Anforderungsraten

Wenn ein Client versucht, den für ein Konto reservierten Durchsatz zu überschreiten, wird die Serverleistung nicht beeinträchtigt, und es wird kein über die reservierte Kapazität hinausgehender Durchsatz in Anspruch genommen. Der Server beendet die Anforderung präemptiv mit „RequestRateTooLarge“ (HTTP-Statuscode 429) und gibt den Header x-ms-retry-after-ms zurück. Darin ist die Zeitspanne (in Millisekunden) angegeben, die der Benutzer warten muss, bis ein neuer Anforderungsversuch unternommen werden kann.

HTTP Status 429,
Status Line: RequestRateTooLarge
x-ms-retry-after-ms :100

Alle SDKs fangen diese Antwort implizit ab, berücksichtigen den vom Server angegebenen Header vom Typ „retry-after“ und wiederholen die Anforderung. Wenn nicht mehrere Clients gleichzeitig auf Ihr Konto zugreifen, wird die nächste Wiederholung erfolgreich ausgeführt.

Falls mehrere Clients kumulativ und kontinuierlich die Anforderungsrate überschreiten, reicht die intern vom Client festgelegte Standardanzahl von neun Wiederholungen unter Umständen nicht aus. In diesem Fall löst der Client für die Anwendung eine CosmosClientException-Klasse mit dem Statuscode 429 aus. Die standardmäßige Wiederholungsanzahl kann durch Verwendung von „setRetryOptions“ für die ConnectionPolicy-Instanz geändert werden. Die CosmosClientException-Klasse mit dem Statuscode 429 wird standardmäßig nach einer kumulierten Wartezeit von 30 Sekunden zurückgegeben, wenn die Anforderung weiterhin die Anforderungsrate übersteigt. Dies gilt auch, wenn die aktuelle Wiederholungsanzahl unter der maximalen Wiederholungsanzahl liegt – ganz gleich, ob es sich dabei um den Standardwert (9) oder um einen benutzerdefinierten Wert handelt.

Das automatisierte Wiederholungsverhalten trägt zwar bei den meisten Anwendungen zur Verbesserung der Resilienz und Nutzbarkeit bei, kann bei Leistungsbenchmarks aber auch hinderlich sein (insbesondere beim Ermitteln der Latenz). Die Wartezeit für den Client nimmt stark zu, wenn das Experiment die Serverdrosselung erreicht und damit die automatische Wiederholung durch das Client-SDK auslöst. Ermitteln Sie zur Vermeidung von Latenzspitzenwerten bei Leistungsexperimenten die von den einzelnen Vorgängen zurückgegebene Belastung, und stellen Sie sicher, dass die Anforderungen die reservierte Anforderungsrate nicht überschreiten. Weitere Informationen finden Sie unter Anforderungseinheiten in DocumentDB.

  • Konzipieren für kleinere Dokumente und höheren Durchsatz

Die Anforderungsbelastung (die Kosten für die Anforderungsverarbeitung) eines Vorgangs hängt direkt mit der Größe des Dokuments zusammen. Vorgänge für große Dokumente sind teurer als Vorgänge für kleine Dateien. Im Idealfall sollten Sie Ihre Anwendung und Workflows so entwerfen, dass die Größe der Elemente etwa ein Kilobyte beträgt oder diese eine ähnliche Größe aufweisen. Bei Anwendungen, die hinsichtlich der Wartezeit empfindlich sind, sollten große Elemente vermieden werden. Dokumente mit mehreren Megabyte verlangsamen Ihre Anwendung.

Nächste Schritte

Weitere Informationen zum Entwerfen einer auf Skalierung und hohe Leistung ausgelegten Anwendung finden Sie unter Partitionieren und Skalieren in Azure Cosmos DB.

Versuchen Sie, die Kapazitätsplanung für eine Migration zu Azure Cosmos DB durchzuführen? Sie können Informationen zu Ihrem vorhandenen Datenbankcluster für die Kapazitätsplanung verwenden.