Azure Cosmos DB ve .NET SDK v2 için performans ipuçları

UYGULANANLAR: NoSQL

Azure Cosmos DB, garantili gecikme süresi ve aktarım hızı ile sorunsuz bir şekilde ölçeklendirilen hızlı ve esnek bir dağıtılmış veritabanıdır. Azure Cosmos DB ile veritabanınızı ölçeklendirmek için büyük mimari değişiklikleri yapmanız veya karmaşık kod yazmanız gerekmez. Ölçeği artırma ve azaltma, tek bir API çağrısı yapmak kadar kolaydır. Daha fazla bilgi edinmek için bkz . Kapsayıcı aktarım hızını sağlama veya veritabanı aktarım hızı sağlama. Ancak Azure Cosmos DB'ye ağ çağrıları aracılığıyla erişildiğinden, SQL .NET SDK'sını kullanırken en yüksek performansı elde etmek için istemci tarafı iyileştirmeleri yapabilirsiniz.

Bu nedenle, veritabanınızın performansını geliştirmeye çalışıyorsanız şu seçenekleri göz önünde bulundurun:

.NET V3 SDK'sına yükseltme

.NET v3 SDK'sı yayınlanır. .NET v3 SDK'sını kullanıyorsanız, aşağıdaki bilgiler için .NET v3 performans kılavuzuna bakın:

  • Varsayılan olarak Doğrudan TCP moduna geçer
  • Stream API desteği
  • System.Text.JSON kullanımına izin vermek için özel seri hale getiriciyi destekleme
  • Tümleşik toplu iş ve toplu destek

Barındırma önerileri

Sunucu tarafı çöp toplamayı (GC) açma

Çöp toplama sıklığını azaltmak bazı durumlarda yardımcı olabilir. .NET'te gcServer'ı olarak trueayarlayın.

İstemci iş yükünüzün ölçeğini genişletme

Yüksek aktarım hızı düzeylerinde (50.000 RU/sn'den fazla) test ediyorsanız, makinenin CPU veya ağ kullanımına odaklanması nedeniyle istemci uygulaması performans sorununa neden olabilir. Bu noktaya ulaşırsanız istemci uygulamalarınızın ölçeğini birden çok sunucu arasında genişleterek Azure Cosmos DB hesabını daha fazla göndermeye devam edebilirsiniz.

Not

Yüksek CPU kullanımı gecikme süresinin artmasına ve istek zaman aşımı özel durumlarına neden olabilir.

Meta veri işlemleri

Ve/veya sık erişimli yolda ve/veya öğe işlemi yapmadan önce veritabanının Create...IfNotExistsAsync ve/veya Read...Async Koleksiyonun mevcut olduğunu doğrulamayın. Doğrulama yalnızca gerekli olduğunda, bunların silinmesini bekliyorsanız (aksi takdirde gerekli değildir) uygulama başlangıcında yapılmalıdır. Bu meta veri işlemleri fazladan uçtan uca gecikme süresi oluşturur, SLA içermez ve veri işlemleri gibi ölçeklendirilmeyen kendi ayrı sınırlamaları vardır.

Günlüğe kaydetme ve izleme

Bazı ortamlarda .NET DefaultTraceListener etkindir. DefaultTraceListener, yüksek CPU ve G/Ç performans sorunlarına neden olan üretim ortamlarında performans sorunları oluşturur. Üretim ortamlarında TraceListeners'dan kaldırarak uygulamanız için DefaultTraceListener'ın devre dışı bırakıldığından emin olun.

En son SDK sürümleri (2.16.2'den büyük) algıladığında otomatik olarak kaldırır, eski sürümlerle şu şekilde kaldırabilirsiniz:

if (!Debugger.IsAttached)
{
    Type defaultTrace = Type.GetType("Microsoft.Azure.Documents.DefaultTrace,Microsoft.Azure.DocumentDB.Core");
    TraceSource traceSource = (TraceSource)defaultTrace.GetProperty("TraceSource").GetValue(null);
    traceSource.Listeners.Remove("Default");
    // Add your own trace listeners
}

Bağlan ilkesi: Doğrudan bağlantı modunu kullanma

.NET V2 SDK varsayılan bağlantı modu ağ geçididir. Örneğin oluşturulması DocumentClient sırasında bağlantı modunu parametresini ConnectionPolicy kullanarak yapılandırabilirsiniz. Doğrudan modu kullanıyorsanız parametresini Protocol kullanarak ConnectionPolicy da ayarlamanız gerekir. Farklı bağlantı seçenekleri hakkında daha fazla bilgi edinmek için bağlantı modları makalesine bakın.

Uri serviceEndpoint = new Uri("https://contoso.documents.net");
string authKey = "your authKey from the Azure portal";
DocumentClient client = new DocumentClient(serviceEndpoint, authKey,
new ConnectionPolicy
{
   ConnectionMode = ConnectionMode.Direct, // ConnectionMode.Gateway is the default
   ConnectionProtocol = Protocol.Tcp
});

Kısa ömürlü bağlantı noktası tükenmesi

Örneklerinizde yüksek bağlantı hacmi veya yüksek bağlantı noktası kullanımı görürseniz, önce istemci örneklerinizin tekil olduğunu doğrulayın. Başka bir deyişle, istemci örnekleri uygulamanın ömrü boyunca benzersiz olmalıdır.

TCP protokolünde çalıştırılırken istemci, HTTPS protokolü yerine uzun süreli bağlantıları kullanarak gecikme süresini iyileştirir ve bu da bağlantıları 2 dakika etkinlik dışı kaldıktan sonra sonlandırır.

Seyrek erişime sahip olduğunuz senaryolarda ve ağ geçidi modu erişimine kıyasla daha yüksek bir bağlantı sayısı fark ederseniz şunları yapabilirsiniz:

  • Bağlan ionPolicy.PortReuseMode özelliğini olarak PrivatePortPool yapılandırın (çerçeve sürümü>= 4.6.1 ve .NET core sürüm >= 2.0 ile etkindir): Bu özellik SDK'nın farklı Azure Cosmos DB hedef uç noktaları için kısa ömürlü küçük bir bağlantı noktası havuzu kullanmasına olanak tanır.
  • Bağlan ionPolicy.Idle Bağlan ionTimeout özelliğinin 10 dakikadan büyük veya buna eşit olması gerekir. Önerilen değerler 20 dakika ile 24 saat arasındadır.

İlk istekte başlatma gecikmesini önlemek için OpenAsync'i çağır

Varsayılan olarak, adres yönlendirme tablosunu getirmesi gerektiğinden ilk istek daha yüksek gecikme süresine sahiptir. SDK V2 kullandığınızda, ilk istekte bu başlatma gecikmesini önlemek için başlatma sırasında bir kez arayınOpenAsync(). Çağrı şöyle görünür: await client.OpenAsync();

Not

OpenAsync , hesaptaki tüm kapsayıcılar için adres yönlendirme tablosunu almak için istekler oluşturur. Çok sayıda kapsayıcısı olan ancak uygulaması bunların bir alt kümesine OpenAsync erişen hesaplar için gereksiz miktarda trafik oluşturarak başlatmayı yavaşlatır. Bu nedenle, uygulama başlatmayı yavaşlattığı için kullanmak OpenAsync bu senaryoda yararlı olmayabilir.

Performans için istemcileri aynı Azure bölgesinde birlikte yerleştirin

Mümkün olduğunda, Azure Cosmos DB'yi çağıran tüm uygulamaları Azure Cosmos DB veritabanıyla aynı bölgeye yerleştirin. Yaklaşık bir karşılaştırma: Aynı bölge içinde Azure Cosmos DB'ye yapılan çağrılar 1 ms ile 2 ms arasında tamamlanır, ancak ABD'nin Batı ve Doğu kıyısı arasındaki gecikme süresi 50 ms'den fazladır. Bu gecikme süresi, istemciden Azure veri merkezi sınırına geçerken istek tarafından alınan yola bağlı olarak istekten isteğe farklılık gösterebilir. Çağıran uygulamanın sağlanan Azure Cosmos DB uç noktasıyla aynı Azure bölgesinde bulunduğundan emin olarak mümkün olan en düşük gecikme süresini alabilirsiniz. Kullanılabilir bölgelerin listesi için bkz . Azure bölgeleri.

Azure Cosmos DB bağlantı ilkesi

İş parçacığı/görev sayısını artırma

Azure Cosmos DB'ye yapılan çağrılar ağ üzerinden yapıldığından, istemci uygulamasının istekler arasında beklemeye en az zaman harcaması için isteklerinizin paralellik derecesini değiştirmeniz gerekebilir. Örneğin, .NET Görev Paralel Kitaplığı'nı kullanıyorsanız, Azure Cosmos DB'den okunan veya Azure Cosmos DB'ye yazılan yüzlerce görev sırasına göre oluşturun.

Hızlandırılmış ağı etkinleştirme

Gecikme süresini ve CPU değişimini azaltmak için, istemci sanal makinelerinde hızlandırılmış ağı etkinleştirmenizi öneririz. Bkz. Hızlandırılmış ağ ile Windows sanal makinesi oluşturma veya Hızlandırılmış ağ ile Linux sanal makinesi oluşturma.

SDK kullanımı

En son SDK'sını yükleme

Azure Cosmos DB SDK'ları en iyi performansı sağlayacak şekilde sürekli geliştirilmektedir. En son SDK'yı belirlemek ve iyileştirmeleri gözden geçirmek için Azure Cosmos DB SDK sayfalarına bakın.

Uygulamanızın ömrü boyunca tek bir Azure Cosmos DB istemcisi kullanma

Her DocumentClient örnek iş parçacığı açısından güvenlidir ve doğrudan modda çalışırken verimli bağlantı yönetimi ve adres önbelleğe alma işlemi gerçekleştirir. Verimli bağlantı yönetimine ve daha iyi SDK istemci performansına izin vermek için uygulamanın kullanım ömrü boyunca tek AppDomain bir örnek kullanmanızı öneririz.

Aramaları engellemekten kaçının

Azure Cosmos DB SDK'sı, birçok isteği aynı anda işlenecek şekilde tasarlanmalıdır. Zaman uyumsuz API'ler, küçük bir iş parçacığı havuzunun çağrıları engellemeyi beklemeyerek binlerce eşzamanlı isteği işlemesine olanak sağlar. İş parçacığı, uzun süre çalışan bir zaman uyumlu görevin tamamlanmasını beklemek yerine başka bir istekte çalışabilir.

Azure Cosmos DB SDK'sını kullanan uygulamalarda sık karşılaşılan bir performans sorunu, zaman uyumsuz olabilecek çağrıları engelliyor. Birçok zaman uyumlu engelleme çağrısı, İş Parçacığı Havuzu aç kalmasına ve yanıt sürelerinin düşmesine yol açar.

Aşağıdakileri yapma:

  • Task.Wait veya Task.Result çağrısı yaparak zaman uyumsuz yürütmeyi engelleyin.
  • Zaman uyumlu API'yi zaman uyumsuz yapmak için Task.Run kullanın.
  • Ortak kod yollarında kilitleri alma. Azure Cosmos DB .NET SDK'sı, kod paralel olarak çalıştırılacak şekilde tasarlandığında en yüksek performansı gösterir.
  • Task.Run'ı çağırıp hemen beklemeye devam edin. ASP.NET Core, uygulama kodunu normal İş Parçacığı Havuzu iş parçacıklarında zaten çalıştırdığından Task.Run çağrısı yalnızca gereksiz İş Parçacığı Havuzu zamanlaması sağlar. Zamanlanan kod bir iş parçacığını engellese bile Task.Run bunu engellemez.
  • Sorguyu zaman uyumlu bir şekilde boşaltmak için engelleme çağrılarını kullanan ToList() DocumentClient.CreateDocumentQuery(...) kullanın. Sorguyu zaman uyumsuz olarak boşaltmak için AsDocumentQuery() kullanın.

Yap:

  • Azure Cosmos DB .NET API'lerini zaman uyumsuz olarak çağırın.
  • Zaman uyumsuz/await desenlerinden yararlanmak için çağrı yığınının tamamı zaman uyumsuzdur.

PerfView gibi bir profil oluşturucu, İş Parçacığı Havuzuna sık sık eklenen iş parçacıklarını bulmak için kullanılabilir. Olay, Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start iş parçacığı havuzuna eklenen bir iş parçacığını gösterir.

Ağ geçidi modu kullanılırken konak başına en fazla System.Net Bağlan sayısını artırın

Ağ geçidi modunu kullandığınızda Azure Cosmos DB istekleri HTTPS/REST üzerinden yapılır. Ana bilgisayar adı veya IP adresi başına varsayılan bağlantı sınırına tabi tutulurlar. İstemci kitaplığının Azure Cosmos DB'ye birden çok eşzamanlı bağlantı kullanabilmesi için daha yüksek bir değere (100 - 1.000) ayarlamanız MaxConnections gerekebilir. .NET SDK 1.8.0 ve sonraki sürümlerinde, ServicePointManager.Default Bağlan ionLimit için varsayılan değer 50'dir. Değeri değiştirmek için Documents.Client.BağlanionPolicy.Max Bağlan ionLimit değerini daha yüksek bir değere yazın.

RetryAfter aralıklarında geri alma uygulama

Performans testi sırasında, az sayıda istek azaltılana kadar yükü artırmanız gerekir. İstekler kısıtlanırsa istemci uygulaması, sunucu tarafından belirtilen yeniden deneme aralığı için kısıtlamayı geri çekmelidir. Geri alma işlemine saygı duymanız, yeniden denemeler arasında en az miktarda beklemenizi sağlar.

Yeniden deneme ilkesi desteği şu SDK'lara dahildir:

Daha fazla bilgi için bkz . RetryAfter.

.NET SDK'sının 1.19 ve sonraki sürümlerinde, aşağıdaki örnekte gösterildiği gibi ek tanılama bilgilerini günlüğe kaydetmeye ve gecikme süresi sorunlarını gidermeye yönelik bir mekanizma vardır. Okuma gecikmesi daha yüksek olan istekler için tanılama dizesini günlüğe kaydedebilirsiniz. Yakalanan tanılama dizesi, belirli bir istek için kaç kez 429 hata aldığınızı anlamanıza yardımcı olur.

ResourceResponse<Document> readDocument = await this.readClient.ReadDocumentAsync(oldDocuments[i].SelfLink);
readDocument.RequestDiagnosticsString 

Daha düşük okuma gecikmesi için belge URI'lerini önbelleğe alma

En iyi okuma performansı için mümkün olduğunca belge URI'lerini önbelleğe alın. Kaynak oluştururken kaynak kimliğini önbelleğe almak için mantık tanımlamanız gerekir. Kaynak kimliklerini temel alan aramalar ad tabanlı aramalardan daha hızlıdır, bu nedenle bu değerleri önbelleğe almak performansı artırır.

İş parçacığı/görev sayısını artırma

Bu makalenin ağ bölümündeki İş parçacığı/görev sayısını artırma bölümüne bakın.

Sorgu işlemleri

Sorgu işlemleri için sorgular için performans ipuçlarına bakın.

Dizin oluşturma ilkesi

Daha hızlı yazma işlemleri için, kullanılmayan yolları dizin oluşturmanın dışında bırakma

Azure Cosmos DB dizin oluşturma ilkesi, dizin oluşturma yollarını (IndexingPolicy.IncludedPaths ve IndexingPolicy.ExcludedPaths) kullanarak dizin oluşturmada hangi belge yollarının ekleneceğini veya dizin oluşturmanın dışında tutulacağını belirtmenize de olanak tanır. Dizin oluşturma yolları, sorgu desenlerinin önceden bilindiği senaryolar için yazma performansını geliştirebilir ve dizin depolama alanını azaltabilir. Bunun nedeni, dizin oluşturma maliyetlerinin doğrudan dizine alınan benzersiz yol sayısıyla bağıntılı olmasıdır. Örneğin, bu kod "*" joker karakteri kullanılarak belgelerin (bir alt ağaç) tüm bölümünün dizin oluşturmadan nasıl dışlandığını gösterir:

var collection = new DocumentCollection { Id = "excludedPathCollection" };
collection.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
collection.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
collection = await client.CreateDocumentCollectionAsync(UriFactory.CreateDatabaseUri("db"), collection);

Daha fazla bilgi için bkz . Azure Cosmos DB dizin oluşturma ilkeleri.

Aktarım hızı

Daha düşük İstek Birimleri/saniye kullanımı için ölçme ve ayarlama

Azure Cosmos DB zengin bir veritabanı işlemleri kümesi sunar. Bu işlemler arasında UDF'ler, saklı yordamlar ve tetikleyiciler içeren ilişkisel ve hiyerarşik sorgular bulunur ve bunların tümü bir veritabanı koleksiyonundaki belgeler üzerinde çalışır. Bu işlemlerin her biriyle ilişkili maliyet, işlemi tamamlamak için gereken CPU, GÇ ve belleğe bağlı olarak değişir. Donanım kaynakları hakkında düşünmek ve bunları yönetmek yerine, çeşitli veritabanı işlemlerini gerçekleştirmek ve uygulama isteğine hizmet sağlamak için gereken kaynaklar için İstek Birimi'ni (RU) tek ölçü olarak düşünebilirsiniz.

Aktarım hızı, her kapsayıcı için ayarlanan İstek Birimi sayısına göre sağlanır. İstek Birimi tüketimi saniye başına hız olarak değerlendirilir. Kapsayıcıları için sağlanan İstek Birimi hızını aşan uygulamalar, hız kapsayıcı için sağlanan düzeyin altına düşene kadar sınırlıdır. Uygulamanız daha yüksek bir aktarım hızı düzeyi gerektiriyorsa, ek İstek Birimleri sağlayarak aktarım hızınızı artırabilirsiniz.

Bir sorgunun karmaşıklık düzeyi, işlem için kullanılan istek birimi sayısını etkiler. Koşul sayısı, koşulların yapısı, UDF sayısı ve kaynak veri kümesinin boyutu sorgu işlemlerinin maliyetini etkiler.

Herhangi bir işlemin (oluşturma, güncelleştirme veya silme) yükünü ölçmek için x-ms-request-charge üst bilgisini (veya .NET SDK'sında ResourceResponse\<T> veya FeedResponse\<T> içindeki eşdeğer RequestCharge özelliği) inceleyerek işlemler tarafından kullanılan İstek Birimi sayısını ölçün:

// Measure the performance (Request Units) of writes
ResourceResponse<Document> response = await client.CreateDocumentAsync(collectionSelfLink, myDocument);
Console.WriteLine("Insert of document consumed {0} request units", response.RequestCharge);
// Measure the performance (Request Units) of queries
IDocumentQuery<dynamic> queryable = client.CreateDocumentQuery(collectionSelfLink, queryString).AsDocumentQuery();
while (queryable.HasMoreResults)
    {
        FeedResponse<dynamic> queryResponse = await queryable.ExecuteNextAsync<dynamic>();
        Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
    }

Bu üst bilgide döndürülen istek ücreti, sağlanan aktarım hızınızın (yani 2.000 RU / saniye) bir bölümüdür. Örneğin, önceki sorgu 1.000 1 KB belge döndürürse, işlemin maliyeti 1.000'dir. Bu nedenle sunucu, sonraki istekleri sınırlamadan önce bir saniye içinde bu tür iki isteği kabul eder. Daha fazla bilgi için bkz . İstek Birimleri ve İstek Birimi hesaplayıcısı.

İşleme hızı sınırlama/istek hızı çok büyük

İstemci bir hesap için ayrılmış aktarım hızını aşmaya çalıştığında, sunucuda performans düşüşü olmaz ve ayrılmış düzeyin ötesinde aktarım hızı kapasitesi kullanılamaz. Sunucu isteği RequestRateTooLarge (HTTP durum kodu 429) ile önceden sonlandıracaktır. Kullanıcının isteği yeniden denemeden önce beklemesi gereken süreyi milisaniye cinsinden belirten bir x-ms-retry-after-ms üst bilgisi döndürür.

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

SDK'ların tümü bu yanıtı örtük olarak yakalar, sunucuda belirtilen retry-after üst bilgisine saygı gösterir ve isteği yeniden dener. Hesabınıza birden çok istemci tarafından eşzamanlı olarak erişilmediği sürece sonraki yeniden deneme başarılı olur.

İstek oranının üzerinde tutarlı bir şekilde çalışan birden fazla istemciniz varsa, varsayılan yeniden deneme sayısı şu anda istemci tarafından dahili olarak 9 olarak ayarlanmayabilir. Bu durumda istemci, uygulamaya 429 durum koduna sahip bir DocumentClientException oluşturur.

Örneğini ayarlayarak RetryOptionsConnectionPolicy varsayılan yeniden deneme sayısını değiştirebilirsiniz. Varsayılan olarak, istek istek hızının üzerinde çalışmaya devam ederse 30 saniyelik bir toplu bekleme süresinden sonra durum kodu 429 olan DocumentClientException döndürülür. Bu hata, geçerli yeniden deneme sayısı en yüksek yeniden deneme sayısı değerinden küçük olsa bile (geçerli değerin varsayılan değer olarak 9 veya kullanıcı tanımlı bir değer olması fark etmeksizin) döndürür.

Otomatik yeniden deneme davranışı, çoğu uygulama için dayanıklılığı ve kullanılabilirliği geliştirmeye yardımcı olur. Ancak bu, özellikle gecikme süresini ölçerken performans karşılaştırmaları yaparken en iyi davranış olmayabilir. Deneme sunucu kısıtlamasına isabet ederse ve istemci SDK'sının sessizce yeniden denemesine neden olursa istemci tarafından gözlemlenen gecikme süresi artar. Performans denemeleri sırasında gecikme süresi artışlarını önlemek için her işlem tarafından döndürülen ücreti ölçün ve isteklerin ayrılmış istek oranının altında çalıştığından emin olun. Daha fazla bilgi için bkz . İstek Birimleri.

Daha yüksek aktarım hızı için, daha küçük belgeler için tasarım

Belirli bir işlemin istek ücreti (yani istek işleme maliyeti), doğrudan belgenin boyutuyla ilişkilendirilir. Büyük belgelerdeki işlemler, küçük belgelerdeki işlemlerden daha pahalıdır.

Sonraki adımlar

Azure Cosmos DB'yi birkaç istemci makinesinde yüksek performanslı senaryolar için değerlendirmek için kullanılan örnek bir uygulama için bkz . Azure Cosmos DB ile performans ve ölçek testi.

Uygulamanızı ölçeklendirme ve yüksek performans için tasarlama hakkında daha fazla bilgi edinmek için bkz . Azure Cosmos DB'de bölümleme ve ölçeklendirme.