Udostępnij za pośrednictwem


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 klip wideo, aby dowiedzieć się więcej o korzystaniu z zestawu .NET SDK od inżyniera usługi Azure Cosmos DB!

Lista kontrolna

Zaznaczone Temat Szczegóły/łącza
Wersja zestawu SDK Zawsze używaj najnowszej wersji zestawu SDK usługi Azure Cosmos DB dostępnej w celu uzyskania optymalnej wydajności.
Klient pojedynczy Użyj pojedynczego CosmosClient wystąpienia dla okresu istnienia aplikacji, aby uzyskać lepszą wydajność.
Regiony Pamiętaj, aby uruchomić aplikację 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 wartość ApplicationPreferredRegions lub ApplicationRegion w zestawie SDK w wersji 3, a pozycję 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 maszynie klienckiej. 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 wrażliwych na opóźnienia trybu bezpośredniego zdecydowanie zalecamy używanie co najmniej 4 rdzeni i 8 GB maszyn wirtualnych pamięci, jeśli 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 portów efemerycznych W przypadku rozrzedzonego lub sporadycznych połączeń ustawiamy IdleConnectionTimeout wartości 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 docelowych punktów końcowych usługi Azure Cosmos DB.
Korzystanie z 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ń blokowania prowadzi do głodu puli wątków i obniżonych czasów odpowiedzi.
Limity czasu zakończenia Aby uzyskać limity czasu zakończenia, należy użyć parametrów RequestTimeout i CancellationToken . Aby uzyskać więcej informacji , odwiedź nasz przewodnik rozwiązywania problemów z limitem czasu.
Logika ponowień 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ą pewne scenariusze , w których zestaw SDK będzie automatycznie ponawiać próby w innych regionach. Szczegóły implementacji specyficzne dla 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 ReadDocumentCollectionAsync i CreateDatabaseQuery lub CreateDocumentCollectionQuery spowodują wywołania metadanych do usługi, które zużywają limit 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óźnień, zalecamy włączenie obsługi zbiorczej w celu zrzucenie 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 lepszych opóźnień i przepływności zapytań. Zalecamy ustawienie MaxConcurrency właściwości w obrębie QueryRequestsOptions wartości na liczbę posiadanych partycji. Jeśli nie wiesz o liczbie partycji, zacznij od użycia metody int.MaxValue, co zapewni najlepsze opóźnienie. Następnie zmniejsz liczbę, dopóki nie pasuje do ograniczeń zasobów środowiska, aby uniknąć problemów z wysokim użyciem procesora CPU. Ponadto ustaw MaxBufferedItemCount wartość na 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 zostały wykluczone 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 .NET SDK 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 je 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 SDK platformy .NET. 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 powodujących 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ólne zalecenie polega na tym, 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 do 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 analizuj 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 protokół HTTP jest używany na potrzeby operacji metadanych i w trybie bramy, który jest używany zarówno dla płaszczyzny danych, jak i operacji metadanych. Jedną z podstaw klienta HttpClient jest upewnienie się, że HttpClient program 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 na wydajność często tworzonych nowych połączeń, przy czym konieczne jest reagowanie 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.HttpClientFactorypolecenia , 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 liczbę System.Net MaxConnections hostów w przypadku korzystania z trybu bramy. Żądania usługi Azure Cosmos DB są wysyłane za pośrednictwem protokołu HTTPS/REST w przypadku 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ść domyślna to ServicePointManager.DefaultConnectionLimit 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 falsewartość . Usługa nie zwróci już utworzonego ani 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, na przykład 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 EnableContentResponseOnWrite false spowoduje również wyłączenie odpowiedzi z operacji wyzwalacza.

Najlepsze rozwiązania dotyczące aplikacji wielodostępnych

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, powinny używać jednego wystąpienia klienta. Pojedyncze wystąpienie klienta może wchodzić w interakcje ze wszystkimi bazami danych, kontenerami i kluczami partycji w ramach konta. 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 pojedynczego oprogramowania nadal dotyczy każdego klienta (jednego klienta 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ę:

  • Zapoznaj się z ograniczeniami środowiska obliczeniowego (procesor CPU i zasoby połączenia). Zalecamy używanie maszyn wirtualnych z co najmniej 4 rdzeniami i 8 GB pamięci, jeśli jest to możliwe.
  • Na podstawie ograniczeń środowiska obliczeniowego określ liczbę wystąpień klienta (i w związku z tym liczbę dzierżaw), które może obsłużyć pojedyncze wystąpienie obliczeniowe. 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żaw do różnych wystąpień obliczeniowych pozwoliłoby na skalowanie w miarę wzrostu liczby dzierżaw.
  • W przypadku obciążeń rozrzedzone należy rozważyć użycie pamięci podręcznej o najmniejszej często używanej pamięci podręcznej 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 funkcja RegisterPostEvictionCallback może służyć do usuwania nieaktywnych klientów, a funkcja SetSlidingExpiration może służyć do definiowania 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 parametrów CosmosClientOptions.IdleTcpConnectionTimeout i CosmosClientOptions.PortReuseMode w konfiguracji trybu bezpośredniego, aby zamknąć nieużywane połączenia i zachować kontrolę nad woluminem połączeń.

Następne kroki

Aby zapoznać się z przykładową aplikacją używaną do oceny usługi Azure Cosmos DB pod kątem scenariuszy o wysokiej wydajności na kilku maszynach klienckich, zobacz Performance and scale testing with Azure Cosmos DB (Wydajność i skalowanie przy użyciu 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ść migracji do usługi Azure Cosmos DB? Informacje o istniejącym klastrze bazy danych można użyć do planowania pojemności.