نصائح حول أداء Azure Cosmos DB و.NET

ينطبق على: NoSQL

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

لكن نظراً لإمكانية الوصول إلى Azure Cosmos DB عبر استدعاءات الشبكة، يمكن إجراء تحسينات من جانب العميل لتحقيق أعلى أداء عند استخدام SQL .NET SDK.

إذا كنت تحاول تحسين أداء قاعدة البيانات، ففكر في الخيارات الموضحة في الأقسام التالية.

توصيات الاستضافة

تشغيل خدمة تجميع البيانات المهملة من جانب الخادم

يمكن أن يساعد تقليل وتيرة تجميع البيانات المهملة في بعض الحالات. في .NET، عيِّن gcServer على true.

توسيع نطاق أعباء عمل العميل

إذا كنت تختبر بمستويات إنتاجية عالية، أو بمعدلات تزيد عن 50000 وحدة طلب في الثانية (وحدات الطلب/ثانية)، فقد يصبح تطبيق العميل مزدحماً بعبء العمل. نظراً لأن الجهاز يحد من استخدام وحدة المعالجة المركزية أو الشبكة. إذا وصلت إلى هذه النقطة، يمكنك الاستمرار في دفع حساب Azure Cosmos DB بشكل أكبر عن طريق توسيع نطاق تطبيقات العميل عبر خوادم متعددة.

إشعار

يمكن أن يؤدي الاستخدام العالي لوحدة المعالجة المركزية إلى زيادة زمن الانتقال وطلب استثناءات للمهلة.

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

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

التسجيل والتتبع.

تحتوي بعض البيئات على .NET DefaultTraceListener ممكن. يطرح DefaultTraceListener مشكلات الأداء على بيئات التشغيل ما يسبب ازدحامات عالية في CPU والإدخال/إخراج. تحقق من تعطيل DefaultTraceListener في تطبيقك وتأكد من ذلك عن طريق إزالته من TraceListeners على بيئات التشغيل.

تقوم أحدث إصدارات SDK (أكبر من 3.23.0) بإزالتها تلقائياً عند اكتشافها، مع الإصدارات القديمة، يمكنك إزالتها عن طريق:

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

الشبكات

نهج الاتصال: استخدم وضع الاتصال المباشر

وضع الاتصال الافتراضي .NET V3 SDK يكون مباشراً مع بروتوكول تحكم الإرسال. تكوِّن وضع الاتصال عند إنشاء المثيل CosmosClient في CosmosClientOptions. لمعرفة مزيد حول خيارات الاتصال المختلفة، راجع مقالة أوضاع الاتصال.

string connectionString = "<your-account-connection-string>";
CosmosClient client = new CosmosClient(connectionString,
new CosmosClientOptions
{
    ConnectionMode = ConnectionMode.Gateway // ConnectionMode.Direct is the default
});

استنفاد المنفذ المؤقت

في حالة ملاحظة ارتفاع حجم اتصال أو استخدام منفذ في مثيلاتك، تأكد أولاً من أن مثيلات عميلك هي قاعدة بيانات أحادية. بمعنى آخر، يجب أن تكون مثيلات العميل فريدة طوال مدة بقاء التطبيق.

عند تشغيله على بروتوكول TCP، يُحسِّن العميل زمن الانتقال باستخدام الاتصالات طويلة الأمد. هذا على عكس بروتوكول HTTPS الذي ينهي الاتصالات بعد دقيقتين من عدم النشاط.

في السيناريوهات التي تتضمن إمكانية وصول ضئيلة، وإذا لاحظت ارتفاع عدد الاتصالات مقارنة بالوصول إلى وضع البوابة، يمكنك:

  • تكوين خاصية CosmosClientOptions.PortReuseMode إلى PrivatePortPool(فعال مع إصدارات إطار العمل 4.6.1 والإصدارات الأحدث والإصدار 2.0 من .NET Core والإصدارات الأحدث). تسمح هذه الخاصية لـ SDK باستخدام تجمع صغيرة من المنافذ المؤقتة لمجموعة مختلفة من نقاط نهاية وجهة Azure Cosmos DB.
  • تكوين الخاصية CosmosClientOptions.IdleTcp الاتصال ionTimeout أكبر من أو تساوي 10 دقائق. القيم الموصى بها تتراوح ما بين 20 دقيقة إلى 24 ساعة.

للحصول على أداء مميز، رتِّب العملاء في منطقة Azure نفسها

ضع أي تطبيقات تستدعي Azure Cosmos DB في المنطقة نفسها الموجودة بها قاعدة بيانات Azure Cosmos DB إن أمكن. فيما يلي مقارنة تقريبية: تكتمل استدعاءات Azure Cosmos DB في داخل المنطقة نفسها في غضون مدة من 1 مللي ثانية (ms) إلى 2 مللي ثانية، لكن زمن الانتقال بين الساحل الغربي والشرقي للولايات المتحدة يزيد على 50 مللي ثانية. يمكن أن يختلف وقت الاستجابة هذا من طلب إلى آخر، اعتماداً على المسار الذي يسلكه الطلب أثناء انتقاله من العميل إلى حد مركز بيانات Azure.

يمكنك الحصول على أقل زمن انتقال ممكن عن طريق التأكد من وجود تطبيق الاستدعاء في داخل منطقة Azure نفسها التي توجد فيها نقطة نهاية Azure Cosmos DB المتوفرة. للحصول على قائمة بالمناطق المتوفرة، راجع مناطق Azure.

ترتيب العملاء في المنطقة نفسها.

زيادة عدد مؤشرات الترابط/المهام

نظراً لإجراء الاستدعاءات لـ Azure Cosmos DB عبر الشبكة، قد تحتاج إلى تغيير درجة تزامن طلباتك بحيث ينتظر تطبيق العميل أدنى فترة ممكنة بين الطلبات. على سبيل المثال، إذا كنت تستخدم .NET Task Parallel Library، فأنشئ مئات المهام التي تُقرأ من Azure Cosmos DB أو تُكتب فيه.

تمكين الشبكات المتسارعة لتقليل زمن الانتقال وتشويه وحدة المعالجة المركزية

من المستحسن اتباع الإرشادات لتمكين الشبكات المتسارعة في Windows ( انقر للحصول على الإرشادات) أو Linux (انقر للحصول على إرشادات) Azure VM، من أجل تحقيق أقصى قدر من الأداء.

دون تسريع الشبكة، قد يتم توجيه الإدخال / الإخراج الذي ينتقل بين Azure VM وموارد Azure الأخرى بشكل غير ضروري عبر مضيف ومحول ظاهري يقع بين الجهاز الظاهري وبطاقة الشبكة الخاصة به. لا يؤدي وجود المضيف والمفتاح الظاهري المضمَّن في مسار البيانات إلى زيادة زمن الوصول والارتعاش في قناة الاتصال فحَسْب، بل يسرق أيضاً دورات وحدة المعالجة المركزية من الجهاز الظاهري. مع الشبكات المتسارعة، واجهات الجهاز الظاهري مباشرة مع NIC دون وسطاء؛ أي تفاصيل سياسة الشبكة التي كان يتم التعامل معها من قبل المضيف والمحول الظاهري يتم التعامل معها الآن في الأجهزة في NIC؛ يتم تجاوز المضيف والمحول الظاهري. بشكل عام، يمكنك توقع وقت استجابة أقل، وإنتاجية أعلى، فضلاً على زيادة اتساق زمن الانتقال، وانخفاض استخدام وحدة المعالجة المركزية عند تمكين تسريع الشبكة.

القيود: يجب دعم الشبكات المتسارعة على نظام تشغيل VM، ولا يمكن تمكينها إلا عند إيقاف الجهاز الظاهري وإلغاء تخصيصه. لا يمكن نشر الجهاز الظاهري مع Azure Resource Manager. لم يتم تمكين الشبكة المسرعة ل App Service .

الرجاء مراجعة إرشادات Windows وLinux للحصول على مزيد من التفاصيل.

استخدام SDK

تثبيت أحدث إصدار من SDK

يتم تحسين حزم Azure Cosmos DB SDK باستمرار لتوفير أفضل أداء. لتحديد أحدث إصدار من SDK ومراجعة التحسينات، راجع صفحات أداة SDK لـ Azure Cosmos DB.

استخدام واجهات برمجة التطبيقات للتدفق

يحتوي .الإصدار الثالث من NET SDK على واجهات برمجة تطبيقات التدفق التي يمكنها تلقي البيانات وإرجاعها دون تسلسل.

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

استخدم عميل قاعدة بيانات أحادية Azure Cosmos DB طوال عمر تطبيقك

كل مثيل CosmosClient هو مؤشر ترابط آمن ويجري إدارة فعالة للاتصال وتخزيناً مؤقتاً للعنوان عند التشغيل في الوضع المباشر. للسماح بإدارة اتصال فعالة وأداء عميل SDK أفضل، نوصي باستخدام مثيل واحد لكل AppDomain مدة بقاء التطبيق لكل حساب يتفاعل معه تطبيقك.

بالنسبة للتطبيقات متعددة المستأجرين التي تتعامل مع حسابات متعددة، راجع أفضل الممارسات ذات الصلة.

عند العمل على وظائف Azure، يجب أن تتبع المثيلات أيضاً الإرشادات الحالية وتحتفظ بمثيل واحد.

تجنب الاستدعاءات المحظورة

يجب تصميم Azure Cosmos DB SDK لمعالجة العديد من الطلبات في وقت واحد. تسمح واجهات برمجة التطبيقات غير المتزامنة للتجمع الصغير لمؤشرات الترابط بمعالجة آلاف الطلبات المتزامنة من خلال عدم الانتظار في الاستدعاءات المحظورة. بدلاً من الانتظار لإكمال مهمة متزامنة طويلة الأمد، يمكن أن يعمل مؤشر الترابط على طلب آخر.

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

لا تنفِّذ ما يلي:

  • منع التنفيذ غير المتزامن من خلال استدعاء Task.Wait أو Task.Result.
  • استخدام Task.Run لمنع تزامن واجهة برمجة التطبيقات المتزامنة.
  • احصل على تأمين في مسارات التعليمات البرمجية الشائعة. Azure Cosmos DB .NET SDK هو الأكثر أداء عند تصميمه لتشغيل التعليمات البرمجية بالتوازي.
  • استدعِ Task.Run وانتظرها على الفور. يقوم ASP.NET Core بالفعل بتشغيل تعليمات برمجية للتطبيق على مؤشرات ترابط تجمع مؤشرات الترابط العادية، لذا فإن استدعاء Task.Run يؤدي فقط إلى جدولة Thread Pool إضافية غير ضرورية. حتى إذا كانت التعليمات البرمجية المجدولة تحظر أي مؤشر ترابط، فإن Task.Run لا يمنع ذلك.
  • لا تستخدم ToList() في Container.GetItemLinqQueryable<T>() الذي يستخدم الاستدعاءات المحظورة لاستنزاف الاستعلام بشكل متزامن. استخدم ToFeedIterator () لاستنزاف الاستعلام بشكل غير متزامن.

من المستحسن القيام بما يلي:

  • استدعاء واجهات برمجة تطبيقات Azure Cosmos DB .NET بشكل غير متزامن.
  • مكدس الاستدعاءات بأكمله غير متزامن للاستفادة من أنماط غير متزامن/الانتظار.

يمكن استخدام محلل ملفات التعريف، مثل PerfView، للعثور على مؤشرات الترابط التي تُضاف بشكل متكرر إلى تجمع مؤشرات الترابط. يشير الحدث Microsoft-Windows-DotNETRuntime/ThreadPoolWorkerThread/Start إلى مؤشر ترابط مُضاف إلى تجمع مؤشرات الترابط.

تعطيل استجابة المحتوى في عمليات الكتابة

بالنسبة لعمليات سير العمل التي تحتوي على أعباء إنشاء كبيرة، عيِّن خيار الطلب EnableContentResponseOnWrite على false. لن تقوم الخدمة بعد الآن بإرجاع المورد الذي تم إنشاؤه أو تحديثه إلى SDK. عادة بسبب احتواء التطبيق على الكائن المُكوَن، لن يحتاج إلى الخدمة لإعادته. لا يزال الوصول إلى قيم العنوان ممكناً مثل رسوم الطلب. يمكن أن يساعد تعطيل استجابة المحتوى في تحسين الأداء، لأن SDK لا تحتاج إلى تخصيص الذاكرة أو تحديد تسلسل نص الاستجابة بعد الآن. كما أنه يقلل من استخدام النطاق الترددي للشبكة للمساعدة في الأداء بشكل أكبر.

ItemRequestOptions requestOptions = new ItemRequestOptions() { EnableContentResponseOnWrite = false };
ItemResponse<Book> itemResponse = await this.container.CreateItemAsync<Book>(book, new PartitionKey(book.pk), requestOptions);
// Resource will be null
itemResponse.Resource

تمكين المجمّع لتحسين معدل النقل بدلاً من زمن الانتقال

مكِّن المجمّع للسيناريوهات التي يتطلب فيها حمل العمل قدراً كبيراً من معدل النقل، ولا يمثل زمن الانتقال الأهمية نفسها. لمزيد من المعلومات عن كيفية تمكين ميزة المجمّع، ولمعرفة السيناريوهات التي يجب استخدامها فيها، راجع مقدمة إلى دعم المجمّع.

زيادة System.Net MaxConnections لكل مضيف عند استخدام وضع البوابة

تُجرى طلبات Azure Cosmos DB عبر بروتوكول HTTPS/RESTREST عند استخدام وضع البوابة. إنها تخضع لحد الاتصال الافتراضي لكل اسم مضيف أو عنوان IP. قد تحتاج إلى تعيين MaxConnections على قيمة أعلى (من 100 إلى 1000) حتى تتمكن مكتبة العميل من استخدام اتصالات متزامنة متعددة مع Azure Cosmos DB. في الإصدار 1.8.0 من .NET SDK والإصدارات الأحدث، تكون القيمة الافتراضية لـ ServicePointManager.DefaultConnectionLimit‏ 50. لتغيير القيمة، يمكنك تعيين Documents.Client.ConnectionPolicy.MaxConnectionLimit على قيمة أعلى.

زيادة عدد مؤشرات الترابط/المهام

راجع زيادة عدد مؤشرات الترابط/المهام في قسم الشبكات في هذه المقالة.

عمليات الاستعلام

لعمليات الاستعلام، راجع نصائح أداء الاستعلامات.

سياسة الفهرسة

استبعاد المسارات غير المستخدمة من الفهرسة لعمليات كتابة أسرع

يسمح لك نهج الفهرسة Azure Cosmos DB أيضاً بتحديد مسارات المستندات المراد تضمينها أو استبعادها من الفهرسة باستخدام مسارات الفهرسة (IndexingPolicy.IncludedPaths and IndexingPolicy.ExcludedPaths).

يمكن أن تؤدي فهرسة المسارات التي تحتاجها فقط إلى تحسين أداء الكتابة وتقليل رسوم وحدة الطلب على عمليات الكتابة وتقليل تخزين الفهرس للسيناريوهات التي تُعرف فيها أنماط الاستعلام مسبقاً. وذلك لأن تكاليف الفهرسة ترتبط مباشرة بعدد المسارات الفريدة المفهرسة. على سبيل المثال، توضح التعليمة البرمجية التالية كيفية استبعاد قسم كامل من المستندات (شجرة فرعية) من الفهرسة باستخدام حرف البدل "*":

var containerProperties = new ContainerProperties(id: "excludedPathCollection", partitionKeyPath: "/pk" );
containerProperties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });
containerProperties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/nonIndexedContent/*");
Container container = await this.cosmosDatabase.CreateContainerAsync(containerProperties);

للحصول على مزيد من المعلومات، راجع خدمة Azure Cosmos DB: نهج الفهرسة.

الإنتاجية

القياس والضبط لأقل وحدات طلب/الثانية

تقدم Azure Cosmos DB مجموعة كبيرة من عمليات قاعدة البيانات. تتضمن هذه العمليات استعلامات بشأن العلاقات والتسلسلات الهرمية مع ملفات تنسيق القرص العالمي (UDF) والإجراءات المخزنة والمشغلات، وجميعها يعمل على المستندات داخل مجموعة قاعدة بيانات.

تختلف التكلفة المرتبطة بكل من هذه العمليات اعتماداً على CPU وIO والذاكرة المطلوبة لإكمال العملية. بدلاً من التفكير في موارد الأجهزة وإدارتها، يمكنك التفكير في وحدة الطلب كمقياس واحد للموارد المطلوبة لتنفيذ عمليات قاعدة بيانات متنوعة وخدمة طلب تطبيق.

يتوفر معدل النقل بناءً على عدد وحدات الطلب المُعيَنة في كل حاوية. يُقيَم استهلاك وحدة الطلب كمعدل وحدة لكل الثانية. التطبيقات التي تتجاوز معدل وحدة الطلب المخصص لحاوياتها محدودة حتى ينخفض ​​المعدل إلى ما دون المستوى المخصص للحاوية. إذا كان تطبيقك يتطلب مستوى أعلى من الإنتاجية، فيمكنك زيادة الإنتاجية من خلال توفير وحدات طلب إضافية.

يؤثر تعقيد الاستعلام في عدد وحدات الطلب المستهلكة لعملية ما. يؤثر عدد دالات التقييم وطبيعتها وعدد ملفات UDF وحجم مجموعة البيانات المصدر في تكلفة عمليات الاستعلام.

لقياس النفقات العامة لأي عملية (إنشاء أو تحديث أو حذف)، افحص العنوان x-ms-request-charge (أو خاصية RequestCharge المكافئة في ResourceResponse<T> أو FeedResponse<T> في NET SDK) لقياس عدد وحدات الطلب التي تستهلكها العمليات:

// Measure the performance (Request Units) of writes
ItemResponse<Book> response = await container.CreateItemAsync<Book>(myBook, new PartitionKey(myBook.PkValue));
Console.WriteLine("Insert of item consumed {0} request units", response.RequestCharge);
// Measure the performance (Request Units) of queries
FeedIterator<Book> queryable = container.GetItemQueryIterator<ToDoActivity>(queryString);
while (queryable.HasMoreResults)
    {
        FeedResponse<Book> queryResponse = await queryable.ExecuteNextAsync<Book>();
        Console.WriteLine("Query batch consumed {0} request units", queryResponse.RequestCharge);
    }

تُعد رسوم الطلب التي يتم إرجاعها في هذا ال عنوان جزءاً صغيراً من سرعة النقل المقدمة (أي 2000 وحدة طلب / ثانية). على سبيل المثال، إذا أنتج الاستعلام السابق 1000 مستند بحجم 1 كيلوبايت، فإن تكلفة العملية هي 1،000. لذلك، في غضون ثانية واحدة، ينفِّذ الخادم طلبَيْن فقط من هذا القبيل قبل أن يحدد معدل الطلبات اللاحقة. لمزيد من المعلومات، راجع وحدات الطلب وحاسبة وحدات الطلب.

تقييد معدل المعالجة/معدل الطلب كبير جدًّا

عندما يحاول أحد العملاء تجاوز معدل النقل المحجوز لحساب ما، لا يحدث انخفاض في الأداء على الخادم، ولا تُستخدَم سعة معدل نقل تتجاوز المستوى المحجوز. ينهي الخادم الطلب بشكل استباقي باستخدام RequestRateTooLarge (رمز حالة HTTP ‏429). يعيد العنوان x-ms-retry-after-ms الذي يشير إلى مقدار الوقت بالملّي ثانية الذي يجب على المستخدم انتظاره قبل محاولة تنفيذ الطلب مرة أخرى.

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

تلتقط جميع حزم SDK هذه الاستجابة ضمنياً، وتحترم عنواناً بعد إعادة المحاولة المحدد من الخادم، ثم تعيد محاولة الطلب. ما لم يتم الوصول إلى حسابك بشكل متزامن من قبل عدة عملاء، فستنجح المحاولة التالية.

في حالة تجاوز أكثر من عميل واحد معدل الطلب على نحو تراكمي ومتسق، فقد لا يكفي عدد مرات إعادة المحاولة الافتراضي المعين حالياً على 9 داخلياً بواسطة العميل. في هذه الحالة، يدخل العميل CosmosException مع رمز الحالة 429 في التطبيق.

يمكنك تغيير عدد مرات إعادة المحاولة الافتراضي عن طريق تعيين RetryOptions على مثيل CosmosClientOptions. يُنتَج CosmosException برمز الحالة 429 افتراضياً بعد مدة انتظار تراكمية قدرها 30 ثانية إذا استمر الطلب في تجاوز معدل الطلب. ينتج هذا الخطأ حتى عندما يكون عدد عمليات إعادة المحاولة الحالية أقل من الحد الأقصى لعدد مرات إعادة المحاولة، سواء كانت القيمة الحالية هي القيمة الافتراضية المقدرة بـ 9 أو قيمة يحددها المستخدم.

تساعد طريقة عمل إعادة المحاولة التلقائية في تحسين مرونة معظم التطبيقات وسهولة استخدامها. ولكن قد لا يكون هذا هو السلوك الأفضل عند إجراء معايير الأداء، خاصةً عند قياس زمن الوصول. سوف يرتفع وقت الانتقال الذي يَلْحَظه العميل إذا وصلت التجربة إلى تقييد الخادم وتسببت في إعادة محاولة SDK للعميل بصمت. لتجنب ارتفاع وقت الاستجابة أثناء تجارب الأداء، قم بقياس الرسوم التي يتم إرجاعها بواسطة كل عملية، وتأكد من أن الطلبات تعمل بأقل من معدل الطلب المحجوز.

لمزيد من المعلومات، راجع وحدات الطلب.

لمعدل نقل أعلى، صمم مستندات أصغر حجماً

ترتبط رسوم الطلب (أي تكلفة معالجة الطلب) لعملية محددة مباشرةً بحجم المستند. تكلِّف عمليات معالجة المستندات الكبيرة رسوماً أكثر من عمليات معالجة المستندات الصغيرة.

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

للحصول على نموذج تطبيق يُستخدم لتقييم Azure Cosmos DB للسيناريوهات عالية الأداء على عدد قليل من أجهزة العميل، راجع اختبار الأداء والقياس باستخدام Azure Cosmos DB.

لمعرفة مزيد حول تصميم تطبيقك بحيث يتناسب مع الحجم والأداء العالي، راجع التقسيم والقياس في Azure Cosmos DB.