Bewährte Methoden für Azure Cosmos DB .NET SDK

GILT FÜR: NoSQL

In diesem Artikel werden die bewährten Methoden für die Verwendung des Azure Cosmos DB .NET SDK beschrieben. Wenn Sie diese Vorgehensweisen befolgen, lassen sich Wartezeiten reduzieren, die Verfügbarkeit verbessern und die Gesamtleistung steigern.

Sehen Sie sich das folgende Video an, um von einem Azure Cosmos DB-Experten mehr über die Verwendung des .NET SDK zu erfahren!

Checkliste

Überprüft Subject Details/Links
SDK-Version Verwenden Sie für eine optimale Leistung stets die aktuelle Version des Azure Cosmos DB SDK.
Singleton-Client Verwenden Sie für eine bessere Leistung eine Einzelinstanz von CosmosClient für die Lebensdauer Ihrer Anwendung.
Regions Führen Sie Ihre Anwendung nach Möglichkeit in der gleichen Azure-Region aus wie Ihr Azure Cosmos DB-Konto. Durch diese Vorgehensweise lassen sich Wartezeiten reduzieren. Aktivieren Sie 2–4 Regionen, und replizieren Sie Ihre Konten in mehreren Regionen, um die beste Verfügbarkeit zu erzielen. Aktivieren Sie für Produktionsworkloads ein vom Dienst verwaltetes Failover. Ohne diese Konfiguration verliert das Konto für die gesamte Dauer des Ausfalls der Schreibregion die Schreibverfügbarkeit, da das manuelle Failover aufgrund der fehlenden Regionskonnektivität nicht erfolgreich verläuft. Informationen zum Hinzufügen mehrerer Regionen mit dem .NET SDK finden Sie hier
Verfügbarkeit und Failover Legen Sie ApplicationPreferredRegions oder ApplicationRegion im v3-SDK und PreferredLocations im v2-SDK über die Liste der bevorzugten Regionen fest. Während eines Failovers werden Schreibvorgänge an die aktuelle Schreibregion gesendet, und alle Lesevorgänge werden an die erste Region in der Liste der bevorzugten Regionen gesendet. Weitere Informationen zu regionalen Failovermechanismen finden Sie im Leitfaden zur Problembehandlung bei der Verfügbarkeit.
CPU Aufgrund fehlender Ressourcen auf Ihrem Clientcomputer kann es zu Verbindungs-/Verfügbarkeitsproblemen kommen. Überwachen Sie die CPU-Auslastung auf Knoten, auf denen der Azure Cosmos DB-Client ausgeführt wird, und führen Sie bei einer sehr hohen Auslastung eine Hoch- bzw. Aufskalierung durch.
Hosting Verwenden Sie für eine maximale Leistung nach Möglichkeit die Windows-64-Bit-Hostverarbeitung. Für latenzempfindliche Produktionsworkloads im direkten Modus wird dringend empfohlen, nach Möglichkeit mindestens 4 Kerne und VMs mit 8 GB Arbeitsspeicher zu verwenden.
Konnektivitätsmodi Verwenden Sie für eine optimale Leistung den direkten Modus. Entsprechende Anweisungen finden Sie in der Dokumentation zum v3-SDK oder in der Dokumentation zum v2-SDK.
Netzwerk Wenn Sie einen virtuellen Computer zum Ausführen Ihrer Anwendung verwenden, aktivieren Sie den beschleunigten Netzwerkbetrieb auf Ihrem virtuellen Computer, um Engpässen aufgrund von hohem Datenverkehrsaufkommen entgegenzuwirken und Wartezeiten oder CPU-Jitter zu reduzieren. Darüber hinaus sollten Sie die Verwendung eines leistungsstärkeren virtuellen Computers in Betracht ziehen, bei dem die maximale CPU-Auslastung unter 70 % liegt.
Kurzfristige Portauslastung Für eine geringe Anzahl von Verbindungen oder sporadische Verbindungen legen wir IdleConnectionTimeout und PortReuseMode auf PrivatePortPool fest. Mithilfe der IdleConnectionTimeout-Eigenschaft lässt sich die Zeit steuern, nach der nicht verwendete Verbindungen geschlossen werden. Dadurch wird die Anzahl der nicht verwendeten Verbindungen reduziert. Standardmäßig werden Verbindungen im Leerlauf unbegrenzt geöffnet gehalten. Dieser Wert muss auf 10 Minuten oder mehr festgelegt werden. Empfohlen werden Werte zwischen 20 Minuten und 24 Stunden. Über die Eigenschaft PortReuseMode kann das SDK einen kleinen Pool von kurzlebigen Ports für verschiedene Azure Cosmos DB-Zielendpunkte verwenden.
Verwenden von async/await-Mustern Vermeiden Sie blockierende Aufrufe: Task.Result, Task.Wait und Task.GetAwaiter().GetResult(). Die gesamte Aufrufliste ist asynchron, um von async/await-Mustern zu profitieren. Viele synchrone blockierende Aufrufe führen zu einer Blockierung des Threadpools und längeren Antwortzeiten.
End-to-End-Timeouts Für End-to-End-Timeouts müssen Sie sowohl RequestTimeout- als auch CancellationToken-Parameter verwenden. Weitere Informationen finden Sie in unserem Leitfaden zur Problembehandlung bei Timeouts.
Wiederholungslogik Weitere Informationen darüber, bei welchen Fehlern ein erneuter Versuch unternommen werden soll und welche Fehler von den SDKs wiederholt werden, finden Sie im Entwurfsleitfaden. Für Konten, die mit mehreren Regionen konfiguriert sind, gibt es einige Szenarien, in denen das SDK automatisch einen neuen Versuch in anderen Regionen unternimmt. Details zur .NET-spezifischen Implementierung finden Sie im SDK-Quellrepository.
Zwischenspeichern von Datenbank-/Sammlungsnamen Rufen Sie die Namen Ihrer Datenbanken und Container aus der Konfiguration ab, oder speichern Sie sie beim Starten zwischen. Aufrufe wie ReadDatabaseAsync oder ReadDocumentCollectionAsync sowie CreateDatabaseQuery oder CreateDocumentCollectionQuery führen zu Metadatenaufrufen an den Dienst. Dabei wird die für das System reservierte RU-Kapazität genutzt. CreateIfNotExist sollte ebenfalls nur einmal zum Einrichten der Datenbank verwendet werden. Diese Vorgänge sollten insgesamt selten ausgeführt werden.
Unterstützung für Massenvorgänge In Szenarios, in denen keine Optimierung der Wartezeiten erforderlich ist, empfiehlt es sich, die Unterstützung für Massenvorgänge zum Sichern großer Datenmengen zu aktivieren.
Parallele Abfragen Für geringere Wartezeiten und einen höheren Durchsatz bei Ihren Abfragen unterstützt das Azure Cosmos DB SDK das parallele Ausführen von Abfragen. Es wird empfohlen, die MaxConcurrency-Eigenschaft innerhalb von QueryRequestsOptions auf die Anzahl Ihrer Partitionen festzulegen. Wenn Sie die Anzahl von Partitionen nicht kennen, beginnen Sie mit int.MaxValue, um eine möglichst geringe Wartezeit zu erhalten. Verringern Sie dann die Anzahl, bis sie den Ressourceneinschränkungen der Umgebung entspricht, um Probleme aufgrund einer hohen CPU-Auslastung zu vermeiden. Legen Sie außerdem MaxBufferedItemCount auf die erwartete Anzahl von zurückgegebenen Ergebnissen fest, um die Anzahl von vorab abgerufenen Ergebnissen zu begrenzen.
Backoffs bei Leistungstests Wenn Sie Leistungstests für Ihre Anwendung durchführen, sollten Sie Backoffs mit RetryAfter-Intervallen implementieren. Durch das Aussetzen wird die geringstmögliche Wartezeit zwischen den Wiederholungsversuchen gewährleistet.
Indizierung Die Indizierungsrichtlinie von Azure Cosmos DB ermöglicht auch die Verwendung von Indizierungspfaden („IndexingPolicy.IncludedPaths“ und „IndexingPolicy.ExcludedPaths“), um anzugeben, welche Dokumentpfade in die Indizierung ein- bzw. ausgeschlossen werden sollen. Stellen Sie für schnellere Schreibvorgänge sicher, dass nicht verwendete Pfade von der Indizierung ausgeschlossen sind. Weitere Informationen zum Erstellen von Indizes mit dem SDK finden Sie unter Leistungstipps .NET SDK v3.
Dokumentgröße Der Anforderungsaufwand eines bestimmten Vorgangs hängt direkt mit der Größe des Dokuments zusammen. Es wird empfohlen, die Größe Ihrer Dokumente zu reduzieren, da Vorgänge für große Dokumente mehr kosten als Vorgänge für kleinere Dokumente.
Erhöhen der Anzahl von Threads/Aufgaben Da Azure Cosmos DB-Aufrufe über das Netzwerk erfolgen, müssen Sie eventuell den Parallelitätsgrad Ihrer Anforderungen variieren, um die Wartezeit für die Clientanwendung zwischen Anforderungen auf ein Minimum zu reduzieren. Erstellen Sie bei Verwendung der .NET Task Parallel Library beispielsweise mehrere Hundert Aufgaben für Lese- und Schreibvorgänge in Azure Cosmos DB.
Aktivieren von Abfragemetriken Für eine zusätzliche Protokollierung Ihrer Back-End-Abfrageausführungen können Sie SQL-Abfragemetriken mit unserem .NET SDK aktivieren. Weitere Informationen zum Sammeln von SQL-Abfragemetriken finden Sie unter Abfragemetriken und Leistung.
SDK-Protokollierung Protokollieren Sie die SDK-Diagnose für außergewöhnliche Szenarien, z. B. Ausnahmen oder die Überschreitung einer erwarteten Latenz durch Anforderungen.
DefaultTraceListener DefaultTraceListener führt in Produktionsumgebungen zu Leistungsproblemen, die eine hohe CPU-Auslastung und E/A-Engpässe bewirken. Stellen Sie sicher, dass Sie die neuesten SDK-Versionen verwenden, oder entfernen Sie den DefaultTraceListener aus Ihrer Anwendung.
Vermeiden der Verwendung von Sonderzeichen in Bezeichnern Einige Zeichen sind nur eingeschränkt erlaubt und können in einigen Bezeichnern nicht verwendet werden: „/“, „\“, „?“, „#“. Generell wird empfohlen, keine Sonderzeichen in Bezeichnern wie Datenbankname, Sammlungsname, Objekt-ID oder Partitionsschlüssel zu verwenden, um ein unerwartetes Verhalten zu vermeiden.

Capture-Diagnose

Alle Antworten im SDK, einschließlich CosmosException, haben eine Diagnostics-Eigenschaft. In dieser Eigenschaft werden alle Informationen zu einer einzelnen Anforderung aufgezeichnet, unter anderem auch, ob es Wiederholungsversuche oder vorübergehende Fehler gab.

Die Diagnosen werden als Zeichenfolge zurückgegeben. Der String ändert sich mit jeder Version, da er für die Fehlersuche in verschiedenen Szenarien verbessert wurde. Mit jeder Version des SDK wird die Formatierung der Zeichenfolge geändert. Analysieren Sie die Zeichenfolge nicht, um Breaking Changes zu vermeiden. Das folgende Codebeispiel zeigt, wie Diagnoseprotokolle mit dem .NET SDK gelesen werden:

try
{
    ItemResponse<Book> response = await this.Container.CreateItemAsync<Book>(item: testItem);
    if (response.Diagnostics.GetClientElapsedTime() > ConfigurableSlowRequestTimeSpan)
    {
        // Log the response.Diagnostics.ToString() and add any additional info necessary to correlate to other logs 
    }
}
catch (CosmosException cosmosException)
{
    // Log the full exception including the stack trace with: cosmosException.ToString()
    
    // The Diagnostics can be logged separately if required with: cosmosException.Diagnostics.ToString()
}

// When using Stream APIs
ResponseMessage response = await this.Container.CreateItemStreamAsync(partitionKey, stream);
if (response.Diagnostics.GetClientElapsedTime() > ConfigurableSlowRequestTimeSpan || !response.IsSuccessStatusCode)
{
    // Log the diagnostics and add any additional info necessary to correlate to other logs with: response.Diagnostics.ToString()
}

Best Practices für HTTP-Verbindungen

Das .NET SDK verwendet HttpClient, um HTTP-Anforderungen unabhängig vom konfigurierten Konnektivitätsmodus auszuführen. Im direkten Modus wird HTTP für Metadatenvorgänge verwendet, im Gatewaymodus sowohl für Vorgänge auf Datenebene als auch für Metadatenvorgänge. Eine der Grundlagen von HttpClient besteht darin, sicherzustellen, dass der HttpClient auf DNS-Änderungen in Ihrem Konto reagieren kann, indem Sie die Lebensdauer der Poolverbindung anpassen. Solange Poolverbindungen geöffnet bleiben, reagieren sie nicht auf DNS-Änderungen. Diese Einstellung erzwingt das regelmäßige Schließen von Poolverbindungen, um sicherzustellen, dass Ihre Anwendung auf DNS-Änderungen reagiert. Wir empfehlen, dass Sie diesen Wert entsprechend Ihrem Konnektivitätsmodus und Ihrer Workload anpassen, um die Leistungsauswirkungen, die sich aus dem häufigen Aufbau neuer Verbindungen ergeben, und die Notwendigkeit, auf DNS-Änderungen zu reagieren (Verfügbarkeit), abzuwägen. Ein Wert von 5 Minuten wäre ein guter Anfang, der erhöht werden kann, wenn er sich insbesondere im Gatewaymodus auf die Leistung auswirkt.

Sie können Ihren benutzerdefinierten HttpClient über CosmosClientOptions.HttpClientFactoryeinfügen, z. B.:

// Use a Singleton instance of the SocketsHttpHandler, which you can share across any HttpClient in your application
SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler();
// Customize this value based on desired DNS refresh timer
socketsHttpHandler.PooledConnectionLifetime = TimeSpan.FromMinutes(5);

CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
{
    // Pass your customized SocketHttpHandler to be used by the CosmosClient
    // Make sure `disposeHandler` is `false`
    HttpClientFactory = () => new HttpClient(socketsHttpHandler, disposeHandler: false)
};

// Use a Singleton instance of the CosmosClient
return new CosmosClient("<connection-string>", cosmosClientOptions);

Wenn Sie die .NET-Abhängigkeitsinjektion verwenden, können Sie den Singleton-Prozess vereinfachen:

SocketsHttpHandler socketsHttpHandler = new SocketsHttpHandler();
// Customize this value based on desired DNS refresh timer
socketsHttpHandler.PooledConnectionLifetime = TimeSpan.FromMinutes(5);
// Registering the Singleton SocketsHttpHandler lets you reuse it across any HttpClient in your application
services.AddSingleton<SocketsHttpHandler>(socketsHttpHandler);

// Use a Singleton instance of the CosmosClient
services.AddSingleton<CosmosClient>(serviceProvider =>
{
    SocketsHttpHandler socketsHttpHandler = serviceProvider.GetRequiredService<SocketsHttpHandler>();
    CosmosClientOptions cosmosClientOptions = new CosmosClientOptions()
    {
        HttpClientFactory = () => new HttpClient(socketsHttpHandler, disposeHandler: false)
    };

    return new CosmosClient("<connection-string>", cosmosClientOptions);
});

Bewährte Methoden bei Verwendung des Gatewaymodus

Erhöhen Sie System.Net MaxConnections pro Host, wenn Sie den Gatewaymodus verwenden. Azure Cosmos DB-Anforderungen erfolgen im Gatewaymodus über HTTPS/REST. Sie unterliegen dem Standardverbindungslimit pro Hostname oder IP-Adresse. Unter Umständen müssen Sie einen höheren Wert für MaxConnections festlegen (100 bis 1.000), damit die Clientbibliothek mehrere Verbindungen mit Azure Cosmos DB gleichzeitig nutzen kann. In .NET SDK 1.8.0 und höher ist der Standardwert für ServicePointManager.DefaultConnectionLimit 50. Zum Ändern des Werts können Sie CosmosClientOptions.GatewayModeMaxConnectionLimit auf einen höheren Wert festlegen.

Bewährte Methoden für schreibintensive Workloads

Legen Sie für Workloads mit hohen Erstellungsnutzlasten die Anforderungsoption EnableContentResponseOnWrite auf false fest. Der Dienst gibt die erstellte oder aktualisierte Ressource nicht mehr an das SDK zurück. Normalerweise verfügt die Anwendung über das zu erstellende Objekt, sodass sie den Dienst nicht benötigt, um es zurückzugeben. Die Headerwerte sind nach wie vor zugänglich wie etwa eine Anforderungsgebühr. Die Deaktivierung der Inhaltsantwort kann die Leistung verbessern, da das SDK keinen Speicher mehr zuweisen oder den Hauptteil der Antwort nicht mehr serialisieren muss. Dies reduziert auch die Auslastung der Netzwerkbandbreite, um die Leistung weiter zu steigern.

Wichtig

Wenn Sie EnableContentResponseOnWrite auf false festlegen, wird auch die Antwort von einem Triggervorgang deaktiviert.

Bewährte Methoden für mehrinstanzenfähige Anwendungen

Anwendungen, die die Nutzung auf mehrere Mandanten verteilen, wobei jeder Mandant durch eine andere Datenbank, einen anderen Container oder einen anderen Partitionsschlüssel innerhalb desselben Azure Cosmos DB-Kontos dargestellt wird, sollten eine einzelne Clientinstanz verwenden. Eine einzelne Clientinstanz kann mit allen Datenbanken, Containern und Partitionsschlüsseln in einem Konto interagieren, und es empfiehlt sich, das Singletonmuster zu verwenden.

Wenn jedoch jeder Mandant durch ein anderes Azure Cosmos DB-Konto dargestellt wird, muss eine separate Clientinstanz pro Konto erstellt werden. Das Singletonmuster gilt weiterhin für jeden Client (ein Client für jedes Konto für die Lebensdauer der Anwendung), aber bei einer hohen Anzahl von Mandanten kann die Anzahl der Clients schwer zu verwalten sein. Verbindungen können über die Grenzen der Computeumgebung hinausgehen und Konnektivitätsprobleme verursachen.

In diesen Fällen wird Folgendes empfohlen:

  • Machen Sie sich mit den Einschränkungen der Compute-Umgebung (CPU- und Verbindungsressourcen) vertraut. Es wird empfohlen, nach Möglichkeit VMs mit mindestens 4 Kernen und 8 GB Arbeitsspeicher zu verwenden.
  • Bestimmen Sie basierend auf den Einschränkungen der Compute-Umgebung die Anzahl der Clientinstanzen (und damit die Anzahl der Mandanten), die eine einzelne Compute-Instanz verarbeiten kann. Sie können die Anzahl der Verbindungen schätzen, die pro Client abhängig vom gewählten Verbindungsmodus geöffnet werden.
  • Bewerten Sie die Mandantenverteilung auf Instanzen. Wenn jede Compute-Instanz eine bestimmte begrenzte Anzahl von Mandanten erfolgreich verarbeiten kann, ermöglichen der Lastenausgleich und das Routing von Mandanten an verschiedene Compute-Instanzen eine Skalierung, wenn sich die Anzahl von Mandanten erhöht.
  • Erwägen Sie bei Workloads mit geringer Dichte die Verwendung eines am wenigsten häufig verwendeten Cache als Struktur, um die Clientinstanzen zu speichern und Clients für Mandanten zu verwerfen, auf die innerhalb eines bestimmten Zeitfensters nicht zugegriffen wurde. Eine Option in .NET ist MemoryCacheEntryOptions. Dabei kann RegisterPostEvictionCallback verwendet werden, um inaktive Clients zu verwerfen, und SetSlidingExpiration kann verwendet werden, um den maximalen Zeitraum zum Speichern inaktiver Verbindungen zu definieren.
  • Verwenden Sie den Gatewaymodus, um die Anzahl der Netzwerkverbindungen zu reduzieren.
  • Passen Sie bei Verwendung des direkten Modus ggf. CosmosClientOptions.IdleTcpConnectionTimeout und CosmosClientOptions.PortReuseMode in der Konfiguration des direkten Modus an, um nicht verwendete Verbindungen zu schließen und die Kontrolle über die Anzahl der Verbindungen zu behalten.

Nächste Schritte

Eine Beispielanwendung zur Evaluierung von Azure Cosmos DB für Hochleistungsszenarien auf einigen Clientcomputern finden Sie unter Leistungs- und Skalierungstests mit Azure Cosmos DB.

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.