كيفية جدولة المهام المخصصة باستخدام DynamoDB TTL و Lambda

الصورة من قبل إيما ماثيوز على Unsplash

تتيح لك CloudWatch Events إنشاء وظائف cron بسهولة مع Lambda. ومع ذلك ، فهي غير مصممة لتشغيل الكثير من المهام المخصصة ، بحيث يتم تنفيذ كل منها مرة واحدة ، في وقت محدد. الحد الافتراضي لأحداث CloudWatch هو 100 قواعد منخفضة لكل منطقة لكل حساب. إنه حد ضعيف ، لذلك من الممكن طلب زيادة الحد. لكن الحد الأدنى الأولي يوحي بأنه غير مصمم لحالات الاستخدام حيث تحتاج إلى جدولة ملايين المهام المخصصة.

تم تصميم CloudWatch Events لتنفيذ المهام المتكررة.

https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/cloudwatch_limits_cwe.html

المشكلة

من الممكن القيام بذلك في كل لغة برمجة تقريبًا. على سبيل المثال ، .Net لديه فئة Timer وجافا سكريبت لديه وظيفة setInterval. لكنني غالباً ما أجد نفسي أرغب في الحصول على خدمة تجريدية للعمل معها. هناك العديد من حالات الاستخدام لمثل هذه الخدمة ، على سبيل المثال:

  • قد يحتاج نظام المسابقات للألعاب إلى تنفيذ منطق العمل عندما تبدأ البطولة وتنتهي.
  • سيحتاج نظام الأحداث (أعتقد eventbrite.com أو meetup.com) إلى آلية لإرسال رسائل تذكير في الوقت المناسب للحضور.
  • يحتاج متتبع المهام (اعتقد قائمة wunderlist) إلى آلية لإرسال رسائل تذكير عندما تكون مهمة المهام واجبة.

ومع ذلك ، لا تقدم AWS خدمة لهذا النوع من أعباء العمل. أحداث CloudWatch هي الأقرب ، ولكن كما نوقش أعلاه ، فإنه ليس مخصصًا لحالات الاستخدام أعلاه. ومع ذلك ، يمكنك تنفيذها باستخدام وظائف cron. لكن هذه التطبيقات لها تحديات أخرى.

لقد نفذت تجريد هذه الخدمة عدة مرات في حياتي المهنية بالفعل. لقد جربت عددًا من الطرق المختلفة:

  • وظيفة cron (مع CloudWatch الأحداث)
  • التفاف فئة .Net Timer كنقطة نهاية HTTP
  • استخدام SQS Visibility Timeout لإخفاء المهام حتى يحين موعد استحقاقها

ومؤخراً ، رأيت عددًا من الأشخاص يستخدمون DynamoDB Time-To-Live (TTL) لتنفيذ هذه المهام المخصصة. في هذا المنشور ، سوف نلقي نظرة على هذا النهج ونرى أين يمكن تطبيقه عليك.

كيف نقيس النهج؟

بالنسبة لهذا النوع من المهام المخصصة ، فإننا نهتم عادةً بما يلي:

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

DynamoDB TTL كآلية جدولة

من المستوى العالي ، يبدو هذا النهج كما يلي:

  • جدول Dyn_Dems Schedule_items الذي يحتفظ بكافة المهام المجدولة للتنفيذ.
  • دالة جدولة تكتب المهمة المجدولة في جدول sched_items ، مع ضبط TTL على وقت التنفيذ المجدول.
  • دالة تنفيذ على الجدول الزمني تشترك في DynamoDB Stream من أجل Schedule_items وتتفاعل مع أحداث REMOVE. تتوافق هذه الأحداث عند حذف العناصر من الجدول.

قابلية التوسع (عدد المهام المفتوحة)

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

DynamoDB يمكن التعامل مع الإنتاجية الكبيرة (الآلاف من TPS) أيضا. لذلك يمكن أيضًا تطبيق هذا النهج على السيناريوهات حيث يتم جدولة آلاف العناصر في الثانية.

قابلية التوسع (النقاط الساخنة)

عندما يتم حذف العديد من العناصر في نفس الوقت ، يتم ببساطة وضعها في قائمة الانتظار في DynamoDB Stream. يقوم AWS أيضًا تلقائيًا بتقليص عدد القطع في الدفق ، بحيث تزيد الإنتاجية من أن عدد القطع يرتفع وفقًا لذلك.

ولكن ، تتم معالجة الأحداث في التسلسل. لذلك قد يستغرق الأمر بعض الوقت حتى تقوم وظيفتك بمعالجة الحدث وفقًا لما يلي:

  • موقعها في الدفق ، و
  • كم من الوقت يستغرق لمعالجة كل حدث.

لذلك ، على الرغم من أن هذا النهج يمكن توسيع نطاقه لدعم العديد من المهام التي تنتهي صلاحيتها جميعها في نفس الوقت ، إلا أنه لا يضمن أن يتم تنفيذ المهام في الوقت المحدد.

الاحكام

هذا سؤال كبير حول هذا النهج. وفقًا للوثائق الرسمية ، يتم حذف العناصر منتهية الصلاحية في غضون 48 ساعة. هذا هو هامش خطأ كبير!

كتجربة ، قمت بإعداد جهاز حالة "وظائف الخطوة" ل:

  1. أضف عددًا من العناصر القابلة للتكوين إلى جدول sched_items ، مع انتهاء فترة صلاحية TTL بين 1 و 10 دقائق
  2. تتبع الوقت المقرر للمهمة وعندما يتم التقاطها فعليًا بواسطة وظيفة التنفيذ على الجدول الزمني
  3. انتظر حتى يتم حذف جميع العناصر

جهاز الدولة يشبه هذا:

قمت بإجراء العديد من الاختبارات. النتائج متسقة بغض النظر عن عدد العناصر في الجدول. يخبرك لمحة سريعة على الطاولة أنه ، في المتوسط ​​، يتم تنفيذ المهمة على مدى 11 دقيقة بعد الوقت المحدد لها.

الولايات المتحدة EAST-1

كررت التجارب في العديد من مناطق AWS الأخرى:

لا أعرف لماذا يوجد هذا الفرق الملحوظ بين US-EAST-1 والمناطق الأخرى. أحد التفسيرات هو أن عملية TTL تتطلب بعض الوقت للبدء بعد إنشاء جدول. منذ أن كنت أطور ضد منطقة US-EAST-1 مبدئيًا ، أصبحت عملية TTL "دافئة" مقارنة بالمناطق الأخرى.

الاستنتاجات

استنادًا إلى نتيجة تجربتي ، سيظهر أن استخدام DynamoDB TTL كآلية جدولة لا يمكن أن يضمن دقة معقولة.

من ناحية ، فإن المقياس جيد للغاية. ولكن من ناحية أخرى ، يتم تنفيذ المهام المجدولة لعدة دقائق على الأقل ، مما يجعلها غير مناسبة للعديد من حالات الاستخدام.