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 true
ayarlayı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
}
Ağ
Bağlantı 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:
- ConnectionPolicy.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 geçerlidir): Bu özellik SDK'nın farklı Azure Cosmos DB hedef uç noktaları için kısa ömürlü bağlantı noktaları havuzunu kullanmasına olanak tanır. - ConnectionPolicy.IdleConnectionTimeout ö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.
İş 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 System.Net MaxConnections'ı 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.DefaultConnectionLimit için varsayılan değer 50'dir. Değeri değiştirmek için Documents.Client.ConnectionPolicy.MaxConnectionLimit değerini daha yüksek bir değere ayarlayabilirsiniz.
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:
- SQL için .NET SDK ve SQL için Java SDK'sının 1.8.0 ve sonraki sürümleri
- SQL için Node.js SDK'sının ve SQL için Python SDK'sının 1.9.0 ve sonraki sürümleri
- .NET Core SDK'larının desteklenen tüm sürümleri
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 RetryOptions
ConnectionPolicy
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.