Aracılığıyla paylaş


Azure Cosmos DB .NET SDK'sında yavaş istekleri tanılama ve sorunlarını giderme

UYGULANANLAR: NoSQL

Azure Cosmos DB'de yavaş istekler fark edebilirsiniz. İstek azaltma veya uygulamanızın tasarlanma şekli gibi çeşitli nedenlerle gecikmeler oluşabilir. Bu makalede, bu sorunun farklı kök nedenleri açıklanmaktadır.

İstek oranı fazla yüksek

İstek azaltma, yavaş isteklerin en yaygın nedenidir. Azure Cosmos DB, veritabanı veya kapsayıcı için ayrılan istek birimlerini aşarsa istekleri kısıtlar. SDK'nın bu istekleri yeniden denemek için yerleşik mantığı vardır. İstek oranı çok büyük sorun giderme makalesi, isteklerin kısıtlanmış olup olmadığını denetlemeyi açıklar. Makalede ayrıca gelecekte bu sorunlardan kaçınmak için hesabınızın nasıl ölçeklendirilecekleri de anlatılmaktadır.

Uygulama tasarımı

Uygulamanızı tasarlarken en iyi performans için .NET SDK en iyi yöntemlerini izleyin. Uygulamanız SDK'nın en iyi yöntemlerini izlemiyorsa, yavaş veya başarısız istekler alabilirsiniz.

Uygulamanızı geliştirirken aşağıdakileri göz önünde bulundurun:

  • Uygulama, Azure Cosmos DB hesabınızla aynı bölgede olmalıdır.
  • ApplicationRegion veya ApplicationPreferredRegions bölge tercihinizi yansıtmalı ve uygulamanızın dağıtılacağı bölgeye işaret etmelidir.
  • Yüksek trafik nedeniyle Ağ arabiriminde bir performans sorunu olabilir. Uygulama Azure Sanal Makineler üzerinde çalışıyorsa olası geçici çözümler vardır:
  • Doğrudan bağlantı modunu tercih edin.
  • Yüksek CPU kullanmaktan kaçının. Çoğu günlük sistemi için varsayılan olan ortalamaya değil maksimum CPU'ya baktığından emin olun. Yaklaşık yüzde 40'ın üzerindeki herhangi bir şey gecikme süresini artırabilir.

Meta veri işlemleri

Bir veritabanının veya kapsayıcının var olduğunu doğrulamanız gerekiyorsa, öğe işlemini çağırarak Create...IfNotExistsAsync veya Read...Async yapmadan önce bunu yapmayın. Doğrulama yalnızca uygulama başlatma sırasında gerekli olduğunda , bunların silinmesini bekliyorsanız yapılmalıdır. Bu meta veri işlemleri ek gecikme süresi oluşturur, hizmet düzeyi sözleşmesi (SLA) yoktur ve kendi ayrı sınırlamaları vardır. Veri işlemleri gibi ölçeklendirilemezler.

Toplu modda yavaş istekler

Toplu mod , gecikme süresi için iyileştirilmiş mod değil, yüksek veri hacmi işlemleri için kullanılan aktarım hızı için iyileştirilmiş bir moddur; kullanılabilir aktarım hızını doygunluğa taşımaya yöneliktir. Toplu modu kullanırken yavaş isteklerle karşılaşıyorsanız aşağıdakilerden emin olun:

  • Uygulamanız Yayın yapılandırmasında derlenmiştir.
  • Uygulamada hata ayıklarken gecikme süresini ölçemezsiniz (hata ayıklayıcı eklenmez).
  • İşlem hacmi yüksektir, 1000'den az işlem için toplu kullanmayın. Sağlanan aktarım hızınız saniyede kaç işlem işleyebileceğinizi belirler; toplu olarak hedefiniz mümkün olduğunca çok işlem kullanmaktır.
  • Azaltma senaryoları için kapsayıcıyı izleyin. Kapsayıcı büyük ölçüde kısıtlanıyorsa bu, veri hacminin sağlanan aktarım hızınızdan daha büyük olduğu anlamına gelir. Kapsayıcının ölçeğini artırmanız veya veri hacmini azaltmanız gerekir (bir kerede daha küçük veri toplu işleri oluşturabilirsiniz).
  • Tüm eş zamanlı Görevleri işlemek için deseni async/await doğru bir şekilde kullanıyorsunuz ve zaman uyumsuz işlemleri engellemezsiniz.

Tanılamaları yakalama

DAHIL olmak üzere CosmosExceptionSDK'daki tüm yanıtların bir Diagnostics özelliği vardır. Bu özellik, yeniden denemeler veya geçici hatalar olup olmadığı dahil olmak üzere tek istekle ilgili tüm bilgileri kaydeder.

Tanılama bir dize olarak döndürülür. Farklı senaryolarda sorun gidermeye yönelik geliştirilmiş olduğundan, dize her sürümde değişir. SDK'nın her sürümünde, dize biçimlendirmede hataya neden olan değişikliklere sahip olur. Hataya neden olan değişiklikleri önlemek için dizeyi ayrıştırmayın. Aşağıdaki kod örneğinde .NET SDK'sını kullanarak tanılama günlüklerinin nasıl okunduğu gösterilmektedir:

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

3.19 ve sonraki sürümlerde tanılama

JSON yapısında SDK'nın her sürümünde hataya neden olan değişiklikler vardır. Bu, ayrıştırılma için güvenli olmasını sağlar. JSON, SDK üzerinden geçen isteğin ağaç yapısını temsil eder. Aşağıdaki bölümlerde dikkate alınacak birkaç önemli konu ele alınıyor.

CPU geçmişi

Yüksek CPU kullanımı, yavaş isteklerin en yaygın nedenidir. En uygun gecikme süresi için CPU kullanımı kabaca yüzde 40 olmalıdır. Maksimum (ortalama değil) CPU kullanımını izlemek için 10 saniyelik bir zaman aralığı kullanın. CPU ani artışları, isteklerin tek bir sorgu için birden çok bağlantı gerçekleştirebileceği bölümler arası sorgularda daha yaygındır.

Zaman aşımları aşağıdakileri içeren tanılamaları içerir, örneğin:

"systemHistory": [
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
{
"dateUtc": "2021-11-17T23:38:38.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
...
]
  • cpu Değerler yüzde 70'in üzerindeyse, zaman aşımına CPU tükenmesi neden olabilir. Bu durumda çözüm, yüksek CPU kullanımının kaynağını araştırmak ve kullanımı azaltmak veya makineyi daha büyük bir kaynak boyutuna ölçeklendirmektir.
  • Düğümlerin threadInfo/isThreadStarvingTrue değerleri varsa, bunun nedeni iş parçacığı açlığıdır. Bu durumda çözüm, iş parçacığının kaynak veya kaynaklarını araştırmak (potansiyel olarak kilitlenmiş iş parçacıkları) veya makineyi veya makineleri daha büyük bir kaynak boyutuna ölçeklendirmektir.
  • Ölçümler dateUtc arasındaki süre yaklaşık 10 saniye değilse, iş parçacığı havuzunda çekişme olduğunu da gösterir. CPU, her 10 saniyede bir iş parçacığı havuzunda sıralanan bağımsız bir görev olarak ölçülür. Ölçümler arasındaki sürenin daha uzun olması, zaman uyumsuz görevlerin zamanında işlenemeyeceğini gösterir. En yaygın senaryo, uygulama kodunuzun zaman uyumsuz kod üzerinden çağrıları engellemesidir.

Çözüm

SDK'yı kullanan istemci uygulamasının ölçeği artırılmalı veya genişletilmelidir.

HttpResponseStats

HttpResponseStatsağ geçidine giden isteklerdir. Doğrudan modda bile SDK tüm meta veri bilgilerini ağ geçidinden alır.

İstek yavaşsa, önce önceki önerilerden hiçbirinin istenen sonuçları vermediğini doğrulayın. Hala yavaşsa, farklı desenler farklı sorunlara işaret eder. Aşağıdaki tabloda daha fazla ayrıntı sağlanmaktadır.

İstek sayısı Senaryo Açıklama
Tümüne tek İstek zaman aşımı veya HttpRequestExceptions SNAT bağlantı noktası tükenmesine veya isteği zamanında işlemek için makinede kaynak eksikliğine işaret eden bir durum.
Tek veya küçük yüzde (SLA ihlal edilmez) Tümünü Yavaş isteklerin tek veya küçük bir yüzdesi birkaç farklı geçici sorundan kaynaklanabilir ve beklenmelidir.
Tümü Tümü Altyapı veya ağ ile ilgili bir soruna işaret ediyor.
SLA ihlal edildi Uygulamada değişiklik yapılmaz ve SLA bırakılır. Azure Cosmos DB hizmetiyle ilgili bir soruna işaret eder.
"HttpResponseStats": [
    {
        "StartTimeUTC": "2021-06-15T13:53:09.7961124Z",
        "EndTimeUTC": "2021-06-15T13:53:09.7961127Z",
        "RequestUri": "https://127.0.0.1:8081/dbs/347a8e44-a550-493e-88ee-29a19c070ecc/colls/4f72e752-fa91-455a-82c1-bf253a5a3c4e",
        "ResourceType": "Collection",
        "HttpMethod": "GET",
        "ActivityId": "e16e98ec-f2e3-430c-b9e9-7d99e58a4f72",
        "StatusCode": "OK"
    }
]

StoreResult

StoreResult , TCP protokolüyle doğrudan modu kullanarak Azure Cosmos DB'ye yönelik tek bir isteği temsil eder.

Hala yavaşsa, farklı desenler farklı sorunlara işaret eder. Aşağıdaki tabloda daha fazla ayrıntı sağlanmaktadır.

İstek sayısı Senaryo Açıklama
Tümüne tek StoreResult Içerir TransportException SNAT bağlantı noktası tükenmesine veya isteği zamanında işlemek için makinede kaynak eksikliğine işaret eden bir durum.
Tek veya küçük yüzde (SLA ihlal edilmez) Tümünü Yavaş isteklerin tek veya küçük bir yüzdesi birkaç farklı geçici sorundan kaynaklanabilir ve beklenmelidir.
Tümü Tümü Altyapı veya ağ ile ilgili bir sorun.
SLA ihlal edildi İstekler birden çok hata kodu içerir, örneğin 410 Azure Cosmos DB hizmeti veya istemci makinesiyle ilgili bir soruna işaret eder.
SLA ihlal edildi StorePhysicalAddress hata durum kodu olmadan aynıdır. Büyük olasılıkla Azure Cosmos DB ile ilgili bir sorun.
SLA ihlal edildi StorePhysicalAddress aynı bölüm kimliğine, ancak hata durum kodu olmayan farklı çoğaltma kimliklerine sahiptir. Büyük olasılıkla Azure Cosmos DB ile ilgili bir sorun.
SLA ihlal edildi StorePhysicalAddress rastgeledir ve hata durum kodu yoktur. Makineyle ilgili bir sorunu gösterir.

Tek bir isteğin birden çok mağaza sonucu için aşağıdakilere dikkat edin:

  • Güçlü tutarlılık ve sınırlanmış eskime tutarlılığı her zaman en az iki depo sonucuna sahiptir.
  • Her StoreResultbirinin durum kodunu denetleyin. SDK, birden çok farklı geçici hatada otomatik olarak yeniden denenir. SDK, daha fazla senaryoyu kapsayacak şekilde sürekli geliştirilmiştir.

RequestTimeline

Aktarım katmanında istek gönderme ve alma işleminin farklı aşamalarının süresini gösterin.

  • ChannelAcquisitionStarted: Yeni bir bağlantı edinme veya oluşturma zamanı. Bağlantılar çeşitli nedenlerle oluşturulabilir: CosmosClientOptions.IdleTcpConnectionTimeout kullanılarak işlem yapılmadığından önceki bağlantı kapatıldı, eşzamanlı isteklerin hacmi CosmosClientOptions.MaxRequestsPerTcpConnection'ı aşıyor, bağlantı bir ağ hatası nedeniyle kapatıldı veya uygulama Tekil desenini kullanmıyor ve yeni örnekler sürekli olarak oluşturuluyor. Bağlantı kurulduktan sonra, sonraki istekler için yeniden kullanılır, bu nedenle daha önce bahsedilen sorunlar gerçekleşmediği sürece bu durum P99 gecikme süresini etkilememelidir.
  • Pipelined büyük bir istek nedeniyle zaman büyük olabilir.
  • Transit time büyük olduğundan ağ sorununa yol açar. Bu sayıyı ile karşılaştırın BELatencyInMs. Küçükse BELatencyInMs , zaman Azure Cosmos DB hizmetinde değil ağda harcandı.
  • Received zaman büyük bir iş parçacığı açlıktan kaynaklanabilir. Bu, yanıtın olmasıyla sonucun döndürüleceği zamandır.

ServiceEndpointStatistics

Belirli bir arka uç sunucusu hakkında bilgi. SDK, bekleyen isteklerin sayısına ve MaxConcurrentRequestsPerConnection'a bağlı olarak tek bir arka uç sunucusuna birden çok bağlantı açabilir.

  • inflightRequests Arka uç sunucusuna yönelik bekleyen isteklerin sayısı (farklı bölümlerden olabilir). Yüksek bir sayı daha fazla trafiğe ve daha yüksek gecikme sürelerine yol açabilir.
  • openConnections , tek bir arka uç sunucusuna açık toplam bağlantı sayısıdır. Bu sayı çok yüksekse SNAT bağlantı noktası tükenmesini göstermek için bu yararlı olabilir.

ConnectionStatistics

İsteğin atandığı belirli bağlantı (yeni veya eski) hakkında bilgiler.

  • waitforConnectionInit: Geçerli istek yeni bağlantı başlatmanın tamamlanmasını bekliyordu. Bu, daha yüksek gecikme sürelerine yol açar.
  • callsPendingReceive: Bu çağrı gönderilmeden önce almayı bekleyen çağrıların sayısı. Yüksek bir numara, bu çağrıdan önce birçok çağrı olduğunu ve daha yüksek gecikme sürelerine yol açabileceğini gösterebilir. Bu sayı yüksekse, büyük olasılıkla işlenmesi uzun süren sorgu veya akış işlemi gibi başka bir isteğin neden olduğu bir satır başı engelleme sorununa işaret eder. Kanal sayısını artırmak için CosmosClientOptions.MaxRequestsPerTcpConnection'ı azaltmayı deneyin.
  • LastSentTime: Bu sunucuya gönderilen son isteğin saati. Bu, LastReceivedTime ile birlikte bağlantı veya uç nokta sorunlarını görmek için kullanılabilir. Örneğin, çok fazla alma zaman aşımı varsa, Gönderilen süre Alma süresinden çok daha büyük olur.
  • lastReceive: Bu sunucudan alınan son isteğin saati
  • lastSendAttempt: Son gönderme denemesinin zamanı

İstek ve yanıt boyutları

  • requestSizeInBytes: Azure Cosmos DB'ye gönderilen isteğin toplam boyutu
  • responseMetadataSizeInBytes: Azure Cosmos DB'den döndürülen üst bilgilerin boyutu
  • responseBodySizeInBytes: Azure Cosmos DB'den döndürülen içeriğin boyutu
"StoreResult": {
    "ActivityId": "bab6ade1-b8de-407f-b89d-fa2138a91284",
    "StatusCode": "Ok",
    "SubStatusCode": "Unknown",
    "LSN": 453362,
    "PartitionKeyRangeId": "1",
    "GlobalCommittedLSN": 0,
    "ItemLSN": 453358,
    "UsingLocalLSN": true,
    "QuorumAckedLSN": -1,
    "SessionToken": "-1#453362",
    "CurrentWriteQuorum": -1,
    "CurrentReplicaSetSize": -1,
    "NumberOfReadRegions": 0,
    "IsValid": true,
    "StorePhysicalAddress": "rntbd://127.0.0.1:10253/apps/DocDbApp/services/DocDbServer92/partitions/a4cb49a8-38c8-11e6-8106-8cdcd42c33be/replicas/1s/",
    "RequestCharge": 1,
    "RetryAfterInMs": null,
    "BELatencyInMs": "0.304",
    "transportRequestTimeline": {
        "requestTimeline": [
            {
                "event": "Created",
                "startTimeUtc": "2022-05-25T12:03:36.3081190Z",
                "durationInMs": 0.0024
            },
            {
                "event": "ChannelAcquisitionStarted",
                "startTimeUtc": "2022-05-25T12:03:36.3081214Z",
                "durationInMs": 0.0132
            },
            {
                "event": "Pipelined",
                "startTimeUtc": "2022-05-25T12:03:36.3081346Z",
                "durationInMs": 0.0865
            },
            {
                "event": "Transit Time",
                "startTimeUtc": "2022-05-25T12:03:36.3082211Z",
                "durationInMs": 1.3324
            },
            {
                "event": "Received",
                "startTimeUtc": "2022-05-25T12:03:36.3095535Z",
                "durationInMs": 12.6128
            },
            {
                "event": "Completed",
                "startTimeUtc": "2022-05-25T12:03:36.8621663Z",
                "durationInMs": 0
            }
        ],
        "serviceEndpointStats": {
            "inflightRequests": 1,
            "openConnections": 1
        },
        "connectionStats": {
            "waitforConnectionInit": "False",
            "callsPendingReceive": 0,
            "lastSendAttempt": "2022-05-25T12:03:34.0222760Z",
            "lastSend": "2022-05-25T12:03:34.0223280Z",
            "lastReceive": "2022-05-25T12:03:34.0257728Z"
        },
        "requestSizeInBytes": 447,
        "responseMetadataSizeInBytes": 438,
        "responseBodySizeInBytes": 604
    },
    "TransportException": null
}

Hata oranı Azure Cosmos DB SLA'sını ihlal ediyor

Azure desteği ile iletişime geçin.

Sonraki adımlar