عملية تشخيص واستكشاف أخطاء الطلبات البطيئة Azure Cosmos DB بواسطة SDK.NET وإصلاحها

ينطبق على: NoSQL

في قاعدة بيانات Azure Cosmos، قد تلاحظ الطلبات البطيئة. يمكن أن تكون طلبات قاعدة بيانات Azure Cosmos بطيئة لأسباب متعددة مثل تقييد الطلب أو نتيجة الطريقة نفسها التي صممت بها طلبك. تعرض هذه المقالة الأسباب الجذرية المختلفة لهذه المشكلة.

معدل الطلب كبير جداً

تقييد الطلب هو السبب الأكثر شيوعا للطلبات البطيئة. تقيد قاعدة بيانات Azure Cosmos منظم حمل العمل الطلبات إذا تجاوزت هذه الطلبات وحدات الطلب RUs المخصصة لقاعدة البيانات أو الحاوية. SDK لديه منطق مدمج لإعادة المحاولة مع هذه الطلبات. توضح مقالة استكشاف أخطاء معدل الطلب كبير جداً وإصلاحها طريقة التحقق في حالة كانت الطلبات مقيدة وطريقة تغير سعة حسابك لتجنب هذه المشكلات في المستقبل. تتناول المقالة أيضا كيفية تغير سعة حسابك لتجنب هذه المشكلات في المستقبل.

تصميم التطبيق

عند تصميم التطبيق الخاص بك، اتبع أفضل الممارسات .NET SDK للحصول على أفضل أداء. إذا كان تطبيقك لا يتبع أفضل ممارسات SDK ، فقد تحصل على طلبات بطيئة أو فاشلة.

عند تطوير تطبيقك، راعي التالي ذكره:

عمليات بيانات التعريف

في حالة كنت بحاجة إلى التحقق من وجود قاعدة بيانات أو حاوية، فلا تقم بذلك عن طريق الاتصال Create...IfNotExistsAsync أو Read...Async قبل إجراء عملية العنصر. يجب أن يتم التحقق من الصحة فقط عند بدء تشغيل التطبيق عند الضرورة، في حالة كنت تتوقع حذفها. تولد عمليات البيانات الوصفية هذه زمن انتقال إضافي وليست تملك اتفاقية على مستوى الخدمة (SLA)، ولها قيود منفصلة خاصة بها. فهي لا تغير السعة مثل عمليات البيانات.

الطلبات بطيئة في الوضع المجمع

الوضع المجمع هو معدل النقل محسن للإنتاجية مخصص لعمليات حجم البيانات العالية وليس وضعا محسنا لزمن الانتقال؛ الغرض منه هو تشبع معدل النقل المتاح. في حالة كنت تواجه طلبات بطيئة عند استخدام الوضع المجمع، فتأكد مما يلي:

  • يتم تجميع التطبيق الخاص بك في التكوين الخاص بالإصدار.
  • أنت لا تقيس زمن الوصول أثناء تصحيح الأخطاء الخاصة بالتطبيق (لا توجد مصححات مرفقة).
  • حجم العمليات مرتفع، تجنب استخدام كميات كبيرة لأقل من 1000 عملية. يملي معدل النقل المتوفر لديك عدد العمليات في الثانية التي يمكنك معالجتها وسيكون هدفك بالجملة هو الاستفادة من أكبر قدر ممكن منها.
  • راقب الحاوية بحثا عن سيناريوهات التقييد. إذا كانت الحاوية تتعرض للتقييد الشديد، فهذا يعني أن حجم البيانات أكبر من معدل النقل الذي تم توفيره، فأنت بحاجة إما إلى توسيع نطاق الحاوية أو تقليل حجم البيانات (ربما إنشاء دفعات أصغر من البيانات في وقت واحد).
  • أنت تستخدم النمط async/await بشكل صحيح لمعالجة كافة المهام المتزامنة وتجنب حظر أي عملية غير متزامنة.

تسجيل التشخيص

تتضمن جميع الاستجابات في SDK على CosmosExceptionخاصية التشخيصDiagnostics. تسجل هذه الخاصية كل المعلومات الخاصة بالطلب المفرد بما في ذلك إذا كانت هناك إعادة محاولة أو أي فشل مؤقت.

يتم إرجاع التشخيصات كسلسلة. تتغير السلسلة مع كل إصدار كما يتم العمل على تحسينها لاستكشاف أفضل سيناريوهات اكتشاف الأخطاء وإصلاحها. مع كل إصدار من SDK، يكون للسلسة تغيرات جذرية في التنسيق. تجنب توزيع السلسلة حتى تتجنب التغيرات الجذرية. توضح عينة التعليمات البرمجية التالية كيفية قراءة السجلات الخاصة بالتشخيص باستخدام SDK.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()
}

التشخيص موجود في الإصدار 3.19 والإصدارت الأحدث

تحتوي بنية JSON على التغييرات الجذرية الصادرة مع كل إصدار من SDK. وهذا يجعل من غير الأمن توزيعها. تمثل JSON بنية شجرة الطلب التي تمر عبر SDK. تغطي الأقسام التالية بعض الأشياء الأساسية التي يجب النظر إليها.

سجل معالج CPU

استخدام CPU عالية هو السبب الأكثر شيوعا لمشكلة الطلبات البطيئة. للحصول على زمن انتقال مثالي، يجب أن يكون استخدام وحدة المعالجة المركزية حوالي 40 بالمائة. استخدم 10 ثوانٍ كفاصل زمني لمراقبة الحد الأقصى (وليس المتوسط) لاستخدام وحدة المعالجة المركزية. تعد الارتفاعات الحادة في CPU تكون أكثر شيوعاً مع استعلامات القسم المتقاطع؛ حيث يمكن أن تجري الطلبات اتصالات متعددة عن استعلام واحد.

تحتوي مهلات التشخيصات، التي تحتوي على ما يلي، على سبيل المثال:

"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 70٪، فمن المحتمل أن يكون سبب انتهاء المهلة هو استنفاد CPU. في هذه الحالة، يتمثل الحل في التحقق من مصدر الاستخدام العالي لوحدة المعالجة المركزية وتقليله، أو توسيع نطاق الجهاز إلى حجم مورد أكبر.
  • إذا كانت قيمة العقد threadInfo/isThreadStarving هي True، يرجع السبب إلى نقص مؤشر ترابط. في هذه الحالة، يكون الحل هو التحقيق في مصدر / مصادر محادثة نصية (المحادثة النصية التي يحتمل أن تكون مقفلة)، أو تغير سعة مؤشر ترابط الجهاز / الأجهزة إلى حجم مورد أكبر.
  • إذا لم تصل المدة dateUtc بين القياسات إلى 10 ثوانٍ تقريباً، يشير ذلك أيضاً إلى وجود اختلاف في تجمع المحادثة النصية. يتم قياس وحدة المعالجة المركزية كمهمة مستقلة يتم أدراجها في قائمة الانتظار في تجمع مؤشرات محادثة نصية كل 10 ثوان. في حالة كان الوقت بين القياسات أطول، فهذا يشير إلى أن المهام غير المتزامنة غير قابلة للمعالجة في الوقت المناسب. السيناريو الأكثر شيوعا هو عندما يقوم تعليمة برمجية التطبيق بحظر المكالمات عبر التعليمات البرمجية غير المتزامنة.

حل

يجب توسيع نطاق تطبيق العميل الذي يستخدم SDK أو زيادة حجمه.

HttpResponseStats

HttpResponseStatsتعد الطلبات التي تذهب إلى البوابة. حتى في الوضع المباشر تحصل SDK على كل معلومات بيانات الخاصة بالتعريف من البوابة.

في حالة كان الطلب بطيئا، فتحقق أولا من عدم تحقيق أي من الاقتراحات السابقة النتائج المرجوة. في حالة كان الطلب لا يزال بطيئاً، أشارت الأنماط المختلفة إلى مشكلات مختلفة: يوفر الجدول التالي تفاصيل.

عدد الطلبات السيناريو الوصف
فردي للجميع طلب المهلة أو HttpRequestExceptions يشير إلى استنزاف منفذ SNAT أو النقص في موارد الجهاز اللازمة لمعالجة الطلب في الوقت المناسب.
النسبة المئوية أحادية أو صغيرة (لا تنتهك اتفاقية مستوى الخدمة) الكل من الممكن أن يكون سبب ظهور نسبة مئوية أحادية أو صغيرة من الطلبات البطيئة العديد من المشكلات المؤقتة المختلفة التي يجب توقعها.
الكل الكل تشير إلى مشكلة في البنية الأساسية أو الشبكات.
انتهاك الاتفاقية على مستوى الخدمة لم يتم إسقاط أي تغييرات على التطبيق وعلى SLA يشير إلى مشكلة في خدمة قاعدة بيانات Azure Cosmos.
"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يمثل StoreResult طلب واحد إلى قاعدة بيانات AzureCosmos باستخدام وضع الاتصال المباشر مع بروتوكول TCP.

في حالة كان الطلب لا يزال بطيئاً، أشارت الأنماط المختلفة إلى مشكلات مختلفة: يوفر الجدول التالي تفاصيل.

عدد الطلبات السيناريو الوصف
فردي للجميع StoreResultالمحتوياتTransportException يشير إلى استنزاف منفذ SNAT أو النقص في موارد الجهاز اللازمة لمعالجة الطلب في الوقت المناسب.
النسبة المئوية أحادية أو صغيرة (لا تنتهك اتفاقية مستوى الخدمة) الكل من الممكن أن يكون سبب ظهور نسبة مئوية أحادية أو صغيرة من الطلبات البطيئة العديد من المشكلات المؤقتة المختلفة التي يجب توقعها.
الكل الكل مشكلة في البنية الأساسية أو الشبكات.
انتهاك الاتفاقية على مستوى الخدمة تحتوي الطلبات على رموز خطأ فشل متعددة، مثل 410 يشير إلى مشكلة في خدمة Azure Cosmos DB أو جهاز العميل.
انتهاك الاتفاقية على مستوى الخدمة StorePhysicalAddressهو نفسه مع عدم وجود تعليمة برمجية حالة الفشل. من المحتمل أن تكون هناك مشكلة في قاعدة بيانات Azure Cosmos .
انتهاك الاتفاقية على مستوى الخدمة StorePhysicalAddressلها نفس معرف القسم مع اختلاف معرفات النسخ المتماثلة وعدم وجود أي تعليمة برمجية لحالة الفشل. من المحتمل أن تكون هناك مشكلة في قاعدة بيانات Azure Cosmos .
انتهاك الاتفاقية على مستوى الخدمة StorePhysicalAddressعشوائي، مع عدم وجود تعليمة برمجية حالة الفشل. تشير إلى مشكلة في الجهاز.

للحصول على نتائج تخزين متعددة لطلب واحد، كن على علم بما يلي:

  • الاتساق القوي والمحدود سيكون له دائماً نتيجتان على الأقل في نتائج التخزين.
  • التحقق من تعليمة برمجية لحالة الكلStoreResult. تعيد SDK المحاولة تلقائياً على عدة إخفاقات مؤقتة . يستمر التحسين في SDK لتغطية المزيد من السيناريوهات.

سطر وقت الطلب

إظهار الوقت المستغرق للمراحل المختلفة لإرسال واستلام الطلب في طبقة النقل.

  • ChannelAcquisitionStarted: الوقت للحصول على اتصال جديد أو إنشائه. يمكن إنشاء الاتصالات لأسباب عديدة مثل: تم إغلاق الاتصال السابق بسبب عدم النشاط باستخدام CosmosClientOptions.IdleTcpConnectionTimeout، أو تجاوز حجم الطلبات المتزامنة CosmosClientOptions.MaxRequestsPerTcpConnection، أو تم إغلاق الاتصال بسبب خطأ في الشبكة، أو أن التطبيق لا يتبع نمط Singleton ويتم إنشاء مثيلات جديدة باستمرار. بمجرد إنشاء اتصال، تتم إعادة استخدامه للطلبات اللاحقة، لذلك يجب ألا يؤثر هذا على زمن انتقال P99 ما لم تحدث المشكلات المذكورة سابقا.
  • Pipelined قد يكون الوقت كبيرا بسبب طلب كبير.
  • Transit time كبير، مما يؤدي إلى مشكلة في الشبكات. قارن هذا الرقم بـ BELatencyInMs. إذا كانتBELatencyInMs BELatencyInMs صغيرة، يتم استهلاك الوقت على الشبكة بدلاً من استهلاكه على خدمة قاعدة البياناتAZURE Cosmos .
  • Received قد يكون الوقت كبيرا بسبب مشكلة تجويع مؤشر الترابط. إنه الوقت بين وجود الإستجابة وإرجاع النتيجة.

ServiceEndpointStatistics

معلومات حول خادم خلفي عين. يمكن لـ SDK فتح اتصالات متعددة إلى خادم خلفية واحد اعتمادًا على عدد الطلبات المعلقة وMaxConcurrentRequestsPerConnection.

  • inflightRequests عدد الطلبات المعلقة إلى الخادم الخلفي (ربما من أقسام مختلفة). قد يؤدي العدد المرتفع إلى زيادة نسبة استخدام الشبكة وزمن انتقال أعلى.
  • openConnections هو إجمالي عدد الاتصالات المفتوحة لخادم خلفي واحد. يمكن أن يكون هذا مفيدًا لإظهار إخراج منفذ SNAT إذا كان هذا الرقم مرتفعًا جدًا.

ConnectionStatistics

معلومات حول الاتصال المعين (الجديد أو القديم) الذي يتم تعيين الطلب إليه.

  • waitforConnectionInit: كان الطلب الحالي ينتظر اكتمال تهيئة الاتصال الجديدة. سيؤدي هذا إلى زمن انتقال أعلى.
  • callsPendingReceive: عدد الاستدعاءات التي كانت معلقة قبل إرسال هذا الاستدعاء. يمكن أن يظهر لنا عدد كبير أنه كان هناك الكثير من الاستدعاءات قبل هذا الاستدعاء وقد يؤدي ذلك إلى زمن انتقال أعلى. إذا كان هذا الرقم مرتفعًا، فإنه يشير إلى مشكلة حظر السطر الرئيسية ربما بسبب طلب آخر مثل الاستعلام أو عملية الموجز التي تستغرق وقتًا طويلا لمعالجتها. حاول خفض CosmosClientOptions.MaxRequestsPerTcpConnection لزيادة عدد القنوات.
  • LastSentTime: وقت آخر طلب تم إرساله إلى هذا الخادم. يمكن استخدام هذا جنبًا إلى جنب مع LastReceivedTime لعرض مشكلات الاتصال أو نقطة النهاية. على سبيل المثال، إذا كان هناك الكثير من مهلات الاستلام، فسيكون وقت الإرسال أكبر بكثير من وقت الاستلام.
  • lastReceive: وقت آخر طلب تم تلقيه من هذا الخادم
  • lastSendAttempt: وقت آخر محاولة إرسال

أحجام الطلب والاستجابة

  • requestSizeInBytes: الحجم الإجمالي للطلب المرسل إلى Azure Cosmos DB
  • responseMetadataSizeInBytes: حجم العناوين التي تم إرجاعها من Azure Cosmos DB
  • responseBodySizeInBytes: حجم المحتوى الذي تم إرجاعه من Azure Cosmos DB
"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
}

معدل الفشل ينتهك Azure Cosmos DB SLA

اتصل بالدعم Azure .

الخطوات التالية

  • تشخيص واستكشاف مشاكل وإصلاحها عند استخدامك قاعدة بيانات Azure Cosmos .NET لعدة الخاصة بتطوير البرامج.
  • تعرف على إرشادات الأداء الخاصة بـ .NET SDK.
  • تعرف على أفضل الممارسات الخاصة بـ .NET SDK