Najlepsze rozwiązania dotyczące zestawu .NET SDK usługi Azure Cosmos DB

DOTYCZY: NoSQL

W tym artykule przedstawiono najlepsze rozwiązania dotyczące korzystania z zestawu .NET SDK usługi Azure Cosmos DB. Zgodnie z tymi rozwiązaniami pomoże zwiększyć opóźnienie, dostępność i zwiększyć ogólną wydajność.

Obejrzyj poniższy film wideo, aby dowiedzieć się więcej o korzystaniu z zestawu SDK platformy .NET od inżyniera usługi Azure Cosmos DB!

Lista kontrolna

Zaznaczono Temat Szczegóły/linki
Wersja zestawu SDK Zawsze używaj najnowszej wersji zestawu SDK usługi Azure Cosmos DB dostępnej w celu uzyskania optymalnej wydajności.
Klient singleton Aby uzyskać lepszą wydajność, użyj pojedynczegoCosmosClient wystąpienia okresu istnienia aplikacji.
Regiony Upewnij się, że aplikacja jest uruchamiana w tym samym regionie świadczenia usługi Azure co konto usługi Azure Cosmos DB, jeśli to możliwe, aby zmniejszyć opóźnienie. Włącz 2–4 regiony i zreplikuj konta w wielu regionach, aby uzyskać najlepszą dostępność. W przypadku obciążeń produkcyjnych włącz tryb failover zarządzany przez usługę. W przypadku braku tej konfiguracji konto utraci dostępność zapisu przez cały czas trwania awarii regionu zapisu, ponieważ ręczne przejście w tryb failover nie powiedzie się z powodu braku łączności z regionem. Aby dowiedzieć się, jak dodać wiele regionów przy użyciu zestawu SDK platformy .NET, odwiedź tutaj
Dostępność i tryb failover Ustaw element ApplicationPreferredRegions lub ApplicationRegion w zestawie SDK w wersji 3, a element PreferredLocations w zestawie SDK w wersji 2 przy użyciu listy preferowanych regionów. Podczas pracy w trybie failover operacje zapisu są wysyłane do bieżącego regionu zapisu, a wszystkie operacje odczytu są wysyłane do pierwszego regionu na liście preferowanych regionów. Aby uzyskać więcej informacji na temat regionalnej mechaniki trybu failover, zobacz przewodnik rozwiązywania problemów z dostępnością.
Procesor CPU Problemy z łącznością/dostępnością mogą wystąpić z powodu braku zasobów na komputerze klienckim. Monitoruj użycie procesora CPU na węzłach z uruchomionym klientem usługi Azure Cosmos DB i skaluj w górę/w poziomie, jeśli użycie jest wysokie.
Hosting Użyj przetwarzania hosta w systemie Windows 64-bitowego , aby uzyskać najlepszą wydajność, jeśli jest to możliwe. W przypadku obciążeń produkcyjnych wymagających opóźnienia trybu bezpośredniego zdecydowanie zalecamy używanie co najmniej 4-rdzeniowych i 8 GB maszyn wirtualnych pamięci, gdy jest to możliwe.
Tryby łączności Użyj trybu bezpośredniego , aby uzyskać najlepszą wydajność. Aby uzyskać instrukcje dotyczące tego, jak to zrobić, zobacz dokumentację zestawu SDK w wersji 3 lub dokumentację zestawu SDK w wersji 2.
Sieć Jeśli używasz maszyny wirtualnej do uruchamiania aplikacji, włącz przyspieszoną sieć na maszynie wirtualnej, aby pomóc w wąskich gardłach z powodu dużego ruchu i zmniejszyć opóźnienia lub zakłócenia procesora CPU. Warto również rozważyć użycie wyższej maszyny wirtualnej, w której maksymalne użycie procesora CPU wynosi poniżej 70%.
Wyczerpanie efemerycznego portu W przypadku rozrzedzone lub sporadyczne połączenia ustawiamy wartość IdleConnectionTimeout i PortReuseMode na PrivatePortPool. Właściwość IdleConnectionTimeout pomaga kontrolować czas, po którym nieużywane połączenia są zamykane. Zmniejsza to liczbę nieużywanych połączeń. Domyślnie bezczynne połączenia są przechowywane przez czas nieokreślony. Zestaw wartości musi być większy lub równy 10 minutom. Zalecamy wartości z zakresu od 20 minut do 24 godzin. Właściwość PortReuseMode umożliwia zestawowi SDK używanie małej puli portów efemerycznych dla różnych punktów końcowych docelowych usługi Azure Cosmos DB.
Korzystanie z narzędzia Async/Await Unikaj blokowania wywołań: Task.Result, Task.Waiti Task.GetAwaiter().GetResult(). Cały stos wywołań jest asynchroniczny, aby korzystać z wzorców asynchronicznych/await . Wiele synchronicznych wywołań blokujących prowadzi do głodu puli wątków i obniżonych czasów odpowiedzi.
Limity czasu zakończenia Aby uzyskać limity czasu kompleksowego, należy użyć parametrów RequestTimeout i CancellationToken . Aby uzyskać więcej informacji , odwiedź nasz przewodnik rozwiązywania problemów z przekroczeniem limitu czasu.
Logika ponawiania próby Aby uzyskać więcej informacji na temat błędów, które należy ponowić i które z nich są ponawiane przez zestawy SDK, zobacz przewodnik projektowania. W przypadku kont skonfigurowanych w wielu regionach istnieją scenariusze , w których zestaw SDK będzie automatycznie ponawiać próby w innych regionach. Szczegółowe informacje dotyczące implementacji platformy .NET można znaleźć w repozytorium źródłowym zestawu SDK.
Buforowanie nazw baz danych/kolekcji Pobierz nazwy baz danych i kontenerów z konfiguracji lub buforuj je podczas uruchamiania. Wywołania takie jak ReadDatabaseAsync lub i ReadDocumentCollectionAsyncCreateDatabaseQuery lub CreateDocumentCollectionQuery spowodują wywołania metadanych do usługi, które korzystają z limitu jednostek RU zarezerwowanych przez system. CreateIfNotExist należy również używać tylko raz do konfigurowania bazy danych. Ogólnie rzecz biorąc, te operacje powinny być wykonywane rzadko.
Obsługa zbiorcza W scenariuszach, w których może nie być konieczne zoptymalizowanie pod kątem opóźnienia, zalecamy włączenie obsługi zbiorczej w przypadku dumpingu dużych ilości danych.
Zapytania równoległe Zestaw SDK usługi Azure Cosmos DB obsługuje równoległe uruchamianie zapytań w celu uzyskania lepszego opóźnienia i przepływności zapytań. Zalecamy ustawienie MaxConcurrency właściwości w obrębie QueryRequestsOptions liczby posiadanych partycji. Jeśli nie wiesz o liczbie partycji, zacznij od użycia polecenia int.MaxValue, co zapewni najlepsze opóźnienie. Następnie zmniejsz liczbę do momentu dopasowania do ograniczeń zasobów środowiska, aby uniknąć problemów z wysokim użyciem procesora CPU. Ponadto ustaw wartość na MaxBufferedItemCount oczekiwaną liczbę zwróconych wyników, aby ograniczyć liczbę wstępnie pobranych wyników.
Wycofywanie testów wydajnościowych Podczas testowania aplikacji należy zaimplementować wycofywanie w RetryAfter odstępach czasu. Przestrzeganie wycofywania pomaga zagwarantować, że spędzasz minimalny czas oczekiwania między ponawianiem prób.
Indeksowanie Zasady indeksowania usługi Azure Cosmos DB umożliwiają również określenie ścieżek dokumentów do uwzględnienia lub wykluczenia z indeksowania przy użyciu ścieżek indeksowania (IndexingPolicy.IncludedPaths i IndexingPolicy.ExcludedPaths). Upewnij się, że nieużywane ścieżki są wykluczane z indeksowania w celu szybszego zapisu. Aby uzyskać więcej informacji na temat tworzenia indeksów przy użyciu zestawu SDK, zobacz porady dotyczące wydajności zestawu SDK platformy .NET w wersji 3.
Rozmiar dokumentu Opłata za żądanie określonej operacji jest skorelowana bezpośrednio z rozmiarem dokumentu. Zalecamy zmniejszenie rozmiaru dokumentów, ponieważ operacje na dużych dokumentach kosztują więcej niż operacje na mniejszych dokumentach.
Zwiększanie liczby wątków/zadań Ponieważ wywołania usługi Azure Cosmos DB są wykonywane za pośrednictwem sieci, może być konieczne zmianę stopnia współbieżności żądań, aby aplikacja kliencka spędzała minimalny czas oczekiwania między żądaniami. Jeśli na przykład używasz biblioteki równoległej zadań platformy .NET, utwórz w kolejności setek zadań odczytywanych z usługi Azure Cosmos DB lub zapisu.
Włączanie metryk zapytań Aby uzyskać więcej rejestrowania wykonań zapytań zaplecza, możesz włączyć metryki zapytań SQL przy użyciu naszego zestawu .NET SDK. Aby uzyskać więcej informacji na temat zbierania metryk zapytań SQL, zobacz Metryki zapytań i wydajność zapytań.
Rejestrowanie zestawu SDK Diagnostyka zestawu SDK dzienników dla wybitnych scenariuszy, takich jak wyjątki lub gdy żądania wykraczają poza oczekiwane opóźnienie.
DefaultTraceListener Element DefaultTraceListener stwarza problemy z wydajnością w środowiskach produkcyjnych, co powoduje wysokie wąskie gardła procesora CPU i we/wy. Upewnij się, że używasz najnowszych wersji zestawu SDK lub usuń element DefaultTraceListener z aplikacji
Unikaj używania znaków specjalnych w identyfikatorach Niektóre znaki są ograniczone i nie można ich używać w niektórych identyfikatorach: '/', '\', '?', '#'. Ogólnie zaleca się, aby nie używać żadnych znaków specjalnych w identyfikatorach, takich jak nazwa bazy danych, nazwa kolekcji, identyfikator elementu lub klucz partycji, aby uniknąć nieoczekiwanego zachowania.

Przechwytywanie danych diagnostycznych

Wszystkie odpowiedzi w zestawie SDK, w tym CosmosException, mają Diagnostics właściwość . Ta właściwość rejestruje wszystkie informacje związane z pojedynczym żądaniem, w tym w przypadku ponownych prób lub błędów przejściowych.

Diagnostyka jest zwracana jako ciąg. Ciąg zmienia się wraz z każdą wersją, ponieważ został ulepszony w celu rozwiązywania problemów z różnymi scenariuszami. W przypadku każdej wersji zestawu SDK ciąg będzie miał zmiany powodujące niezgodność w formatowaniu. Nie analizujej ciągu, aby uniknąć zmian powodujących niezgodność. Poniższy przykładowy kod pokazuje, jak odczytywać dzienniki diagnostyczne przy użyciu zestawu SDK platformy .NET:

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()
}

Najlepsze rozwiązania dotyczące połączeń HTTP

Zestaw SDK platformy .NET używa HttpClient do wykonywania żądań HTTP niezależnie od skonfigurowanego trybu łączności. W trybie bezpośrednim http jest używany do operacji metadanych i w trybie bramy jest używany zarówno dla płaszczyzny danych, jak i operacji metadanych. Jedną z podstaw klienta HttpClient jest upewnienie się, że HttpClient może reagować na zmiany DNS na koncie, dostosowując okres istnienia połączenia w puli. Tak długo, jak połączenia w puli są otwarte, nie reagują na zmiany DNS. To ustawienie wymusza okresowe zamykanie połączeń w puli, zapewniając, że aplikacja reaguje na zmiany DNS. Zalecamy dostosowanie tej wartości zgodnie z trybem łączności i obciążeniem, aby zrównoważyć wpływ wydajności często tworzonych nowych połączeń z koniecznością reagowania na zmiany DNS (dostępność). Wartość 5-minutowa byłaby dobrym początkiem, który można zwiększyć, jeśli ma to wpływ na wydajność szczególnie w przypadku trybu bramy.

Niestandardowy obiekt HttpClient można wstrzyknąć za pomocą CosmosClientOptions.HttpClientFactoryelementu , na przykład:

// 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);

Jeśli używasz iniekcji zależności platformy .NET, możesz uprościć proces singleton:

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);
});

Najlepsze rozwiązania dotyczące korzystania z trybu bramy

Zwiększ System.Net MaxConnections liczbę hostów w przypadku korzystania z trybu bramy. Żądania usługi Azure Cosmos DB są wykonywane za pośrednictwem protokołu HTTPS/REST podczas korzystania z trybu bramy. Podlegają one domyślnemu limitowi połączeń na nazwę hosta lub adres IP. Może być konieczne ustawienie MaxConnections wartości wyższej (od 100 do 1000), aby biblioteka kliencka mogła używać wielu równoczesnych połączeń z usługą Azure Cosmos DB. W zestawie .NET SDK 1.8.0 lub nowszym wartość ServicePointManager.DefaultConnectionLimit domyślna to 50. Aby zmienić wartość, możesz ustawić CosmosClientOptions.GatewayModeMaxConnectionLimit wartość wyższą.

Najlepsze rozwiązania dotyczące obciążeń z dużą liczbą operacji zapisu

W przypadku obciążeń, które mają duże ładunki tworzenia, ustaw EnableContentResponseOnWrite opcję żądania na false. Usługa nie zwróci już utworzonego lub zaktualizowanego zasobu do zestawu SDK. Zwykle, ponieważ aplikacja ma tworzony obiekt, nie potrzebuje usługi, aby ją zwrócić. Wartości nagłówka są nadal dostępne, takie jak opłata za żądanie. Wyłączenie odpowiedzi na zawartość może pomóc zwiększyć wydajność, ponieważ zestaw SDK nie musi już przydzielać pamięci ani serializować treści odpowiedzi. Zmniejsza również użycie przepustowości sieci w celu zwiększenia wydajności.

Ważne

Ustawienie na EnableContentResponseOnWritefalse wartość spowoduje również wyłączenie odpowiedzi z operacji wyzwalacza.

Najlepsze rozwiązania dotyczące aplikacji z wieloma dzierżawami

Aplikacje, które dystrybuują użycie w wielu dzierżawach, w których każda dzierżawa jest reprezentowana przez inną bazę danych, kontener lub klucz partycji w ramach tego samego konta usługi Azure Cosmos DB , powinna używać pojedynczego wystąpienia klienta. Pojedyncze wystąpienie klienta może współdziałać ze wszystkimi bazami danych, kontenerami i kluczami partycji na koncie. Najlepszym rozwiązaniem jest użycie wzorca pojedynczego.

Jednak gdy każda dzierżawa jest reprezentowana przez inne konto usługi Azure Cosmos DB, wymagane jest utworzenie oddzielnego wystąpienia klienta na konto. Wzorzec pojedynczy nadal ma zastosowanie dla każdego klienta (jeden klient dla każdego konta w okresie istnienia aplikacji), ale jeśli liczba dzierżaw jest wysoka, liczba klientów może być trudna do zarządzania. Połączenia mogą zwiększać się poza limity środowiska obliczeniowego i powodować problemy z łącznością.

W takich przypadkach zaleca się:

  • Omówienie ograniczeń środowiska obliczeniowego (zasobów procesora CPU i połączenia). Zalecamy używanie maszyn wirtualnych z co najmniej 4 rdzeniami i pamięcią 8 GB, jeśli jest to możliwe.
  • Na podstawie ograniczeń środowiska obliczeniowego określ liczbę wystąpień klienta (a w związku z tym liczbę dzierżaw) pojedynczego wystąpienia obliczeniowego, które może obsłużyć. W zależności od wybranego trybu połączenia można oszacować liczbę połączeń , które zostaną otwarte dla każdego klienta.
  • Ocena dystrybucji dzierżawy między wystąpieniami. Jeśli każde wystąpienie obliczeniowe może pomyślnie obsłużyć pewną ograniczoną liczbę dzierżaw, równoważenie obciążenia i routing dzierżawców do różnych wystąpień obliczeniowych pozwoliłoby na skalowanie w miarę wzrostu liczby dzierżaw.
  • W przypadku obciążeń rozrzedzone rozważ użycie pamięci podręcznej co najmniej często używanej jako struktury do przechowywania wystąpień klienta i usuwania klientów dla dzierżaw, do których nie uzyskiwano dostępu w przedziale czasu. Jedną z opcji na platformie .NET jest MemoryCacheEntryOptions, gdzie można użyć funkcji RegisterPostEvictionCallback do usuwania nieaktywnych klientów i funkcji SetSlidingExpiration można użyć do zdefiniowania maksymalnego czasu przechowywania nieaktywnych połączeń.
  • Oceń użycie trybu bramy , aby zmniejszyć liczbę połączeń sieciowych.
  • W przypadku korzystania z trybu bezpośredniego należy rozważyć dostosowanie opcji CosmosClientOptions.IdleTcpConnectionTimeout i CosmosClientOptions.PortReuseMode w konfiguracji trybu bezpośredniego , aby zamknąć nieużywane połączenia i zachować ilość połączeń pod kontrolą.

Następne kroki

Aby zapoznać się z przykładową aplikacją używaną do oceny usługi Azure Cosmos DB w przypadku scenariuszy o wysokiej wydajności na kilku komputerach klienckich, zobacz Performance and scale testing with Azure Cosmos DB (Testowanie wydajności i skalowania za pomocą usługi Azure Cosmos DB).

Aby dowiedzieć się więcej na temat projektowania aplikacji pod kątem skalowania i wysokiej wydajności, zobacz Partycjonowanie i skalowanie w usłudze Azure Cosmos DB.

Próbujesz zaplanować pojemność na potrzeby migracji do usługi Azure Cosmos DB? Informacje o istniejącym klastrze bazy danych można użyć do planowania pojemności.