أفضل طريقة للمهندس المعماري Azure Worker دور معالجة البيانات من ~ 10 قوائم الانتظار

StackOverflow https://stackoverflow.com/questions/4084499

سؤال

لديّ دور عامل واحد يلقي البيانات في حوالي 10 قوائم قوائم تحتاج إلى معالجتها. هناك الكثير من البيانات - ربما حوالي 10-100 رسائل في الثانية التي يتم تصويرها في قوائم الانتظار المختلفة.

تحتوي قوائم الانتظار على بيانات مختلفة وتعالجها بشكل منفصل. هناك قائمة انتظار واحدة على وجه الخصوص نشطة للغاية.

بالطريقة التي أجري بها إعدادها الآن ، أنا دور عامل منفصل يولد 10 مؤشرات ترابط مختلفة ، يقوم كل مؤشر ترابط بتنفيذ طريقة لها بعض الوقت (صحيح) {الحصول على رسالة من قائمة الانتظار ومعالجةها}. كلما تم دعم البيانات الموجودة في قائمة الانتظار ، فإننا ببساطة نطلق المزيد من هذه العمليات للمساعدة في تسريع معالجة البيانات من قائمة الانتظار. أيضًا ، نظرًا لأن قائمة انتظار واحدة أكثر نشاطًا ، فأنا أقوم بالفعل بتشغيل عدد من المواضيع التي تشير إلى نفس الطريقة لمعالجة البيانات من قائمة الانتظار هذه.

ومع ذلك ، أرى استخدام وحدة المعالجة المركزية عالية للنشر. تقريبا في أو بالقرب من 100 ٪ باستمرار.

أنا أتساءل عما إذا كان هذا بسبب الجوع في الموضوع؟ أو لأن الوصول إلى قائمة الانتظار مريحة وينتهي الأمر بتعبئة بعضها البعض عن طريق إجراء الاتصال وتباطؤ الأشياء؟ أو هل هذا لأنني أستخدم:

while(true)
{
   var message = get message from queue;
   if(message != null)
   {
       //process message
   }
}

ويتم تنفيذ ذلك بسرعة كبيرة؟

كل معالجة الرسالة تنقذها أيضًا إلى تخزين جدول Azure أو DB - لذلك قد تكون عملية حفظ هذه البيانات التي تتناول وحدة المعالجة المركزية.

في الواقع ، كان من الصعب حقًا تصحيح حمل وحدة المعالجة المركزية العالية. لذا ، سؤالي هو: هل هناك تغييرات في الهندسة المعمارية العامة التي يمكنني إجراؤها ستساعد على تخفيف + منع أي مشكلة محتملة قد تكون هناك؟ (على سبيل المثال ، بدلاً من استخدام (صحيح) باستخدام نوع مختلف من الاقتراع - على الرغم من أنني أتخيل أنه هو نفسه في النهاية لهذا المثال).

ربما ببساطة وضع مؤشرات ترابط جديدة باستخدام Thread () الجديد ليس هو أفضل طريقة للذهاب.

هل كانت مفيدة؟

المحلول

أود أن أقترح وضع بيان نوم في حلقتك ... ليس فقط تلك الحلقة الضيقة على الأرجح توخّص موارد وحدة المعالجة المركزية ، ولكنك تدفع أيضًا مقابل معاملات التخزين. كل عشرة آلاف مرة تقوم فيها بفحص قائمة الانتظار ، يكلف بنسًا. هذه تكلفة صغيرة ، لكنها قد تضيف مع مرور الوقت لتكون مهمة.

غالبًا ما استخدمت رمزًا مثل هذا:

while(true) { var msg = q1.GetMessage(); if (msg != null) { ... } msg = q2.GetMessage(); if (msg != null) { ... } }

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

نصائح أخرى

كان نفس المشكلة مع وحدة المعالجة المركزية. يمكن أن يكون ناتج عن التنفيذ المحلي غير الفعال لقوائم Azure.

في النهاية أضفت سياسة النوم الأسية (للتنفيذ - تحقق من lokad.cqrs ل Azure Project) ، حيث يتم استطلاع قوائم الانتظار بشكل متكرر ، ولكن إذا لم تكن هناك رسائل في أي منها ، فإننا نبدأ تدريجياً في زيادة فاصل النوم حتى يصل إلى بعض الحدود العليا. إذا تم اكتشاف الرسالة - فإننا نسقط الفاصل الزمني على الفور.

وبهذه الطريقة ، لا يضيع النظام بشكل عام معاملات التخزين (ووحدة المعالجة المركزية DEV المحلية) ، ولكنها تظل مستجيبة للغاية ، إذا كانت هناك رسائل متعددة في صف واحد.

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

أعتقد أن مشكلتك تأتي من تطبيق الحلقة. يجب تباطؤ الاقتراع بسبب شيء مثل النوم (). خلاف ذلك ، لن يمنع أي شيء الحلقة من استهلاك CPU بنسبة 100 ٪ (وهو السلوك الطبيعي في الواقع).

هناك مقال رائع MSDN يغطي كل هذا

MSDN - أفضل الممارسات لزيادة قابلية التوسع وفعالية التكلفة لحلول الرسائل القائمة على قائمة الانتظار على Windows Azure

يتحدث عن إضافة مؤشرات ترابط وحالات عندما يكون هناك عمل للقيام به - والتراجع عندما لا يكون هناك حتى أنك لا تقم باستمرار بقوائم الاقتراع من خيوط وحالات mutliple ، وتثبيت تكاليف المعاملات وتحويل وحدة المعالجة المركزية إلى سخان مع مستمر 100 ٪ استخدام وحدة المعالجة المركزية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top