تحقيق المرونة مع قوائم الانتظار: بناء نظام لا يتخطى المليار مرة
نشرت: 2018-12-21تعالج Braze المليارات والمليارات من الأحداث يوميًا نيابة عن عملائها ، مما يؤدي إلى إرسال مليارات الرسائل الشخصية شديدة التركيز إلى المستخدمين النهائيين. يترتب على الفشل في إرسال إحدى هذه الرسائل عواقب ، سواء كان ذلك إيصالًا فائتًا أو - أسوأ من ذلك - إشعار فائت يُعلم المستخدم أن طعامه جاهز. للتأكد من صحة هذه الرسائل الرئيسية دائمًا وفي الوقت المحدد دائمًا ، تتبع Braze نهجًا استراتيجيًا لكيفية الاستفادة من قوائم انتظار الوظائف.
ما هي قائمة انتظار العمل؟
قائمة انتظار الوظائف النموذجية عبارة عن نمط معماري حيث تقوم العمليات بإرسال مهام الحساب إلى قائمة انتظار بينما تقوم العمليات الأخرى بتنفيذ المهام فعليًا. عادة ما يكون هذا أمرًا جيدًا - عند استخدامه بشكل صحيح ، فإنه يمنحك درجات من التزامن وقابلية التوسع والتكرار التي لا يمكنك الحصول عليها من خلال نموذج الطلب والاستجابة التقليدي. يمكن للعديد من العمال تنفيذ وظائف مختلفة في وقت واحد في عمليات متعددة أو أجهزة متعددة أو حتى مراكز بيانات متعددة لتحقيق ذروة التزامن. يمكنك تعيين عقد عاملة معينة للعمل في قوائم انتظار معينة وإرسال مهام معينة إلى قوائم انتظار محددة ، مما يسمح لك بتوسيع نطاق الموارد حسب الحاجة. إذا تعطلت عملية العامل أو أصبح مركز البيانات غير متصل ، يمكن للعاملين الآخرين تنفيذ المهام المتبقية.
بينما يمكنك بالتأكيد تطبيق هذه المبادئ وتشغيل نظام انتظار الوظائف بسهولة على نطاق صغير ، تبدأ اللحامات بالظهور (وحتى تنفجر) عندما تقوم بمعالجة المليارات والمليارات من الوظائف. دعنا نلقي نظرة على بعض المشاكل التي واجهتها Braze مع تطورنا من معالجة الآلاف ، إلى الملايين ، والآن مليارات الوظائف يوميًا.
عدم الاتساق هو ضعف
ماذا يحدث إذا أرسلنا رسالة ، لكننا عطلنا قبل تسجيل حقيقة أننا أرسلنا هذه الرسالة للتو؟
من الممكن هنا نتيجتان سيئتان مختلفتان. أولاً ، يمكنك إعادة جدولة المهمة الفاشلة وإرسال الرسالة مرة أخرى. هذا ... ليس مثاليًا: لا أحد يريد أن يتلقى نفس الشيء مرتين. بدلاً من ذلك ، ضع في اعتبارك عدم إعادة الجدولة على الإطلاق. في هذه الحالة ، ستكون حساباتنا الداخلية غير صحيحة ، لذا فإن الإحالات والتحويلات وجميع أنواع الأشياء الأخرى لن تكون صحيحة في المضي قدمًا.
كيف يمكننا إصلاح ذلك؟ عند كتابة تعريفات وظيفتنا ، نفكر مليًا في عدم القدرة على العمل وإعادة محاولة السلوك.
عندما تتحدث عن قوائم الانتظار ، فإن idempotency يعني أنه يمكن إنهاء وظيفة واحدة عند نقطة تعسفية ، وإعادة تشغيل الوظيفة المعاد وضعها في قائمة الانتظار بالكامل ، وستكون النتيجة النهائية هي نفسها كما لو كنا قد أدرنا الوظيفة بنجاح واحدًا بالضبط زمن. يرتبط هذا ارتباطًا وثيقًا بسلوك إعادة المحاولة لدينا - التسليم مرة واحدة على الأقل. من خلال الأخذ في الاعتبار أنه سيتم تشغيل جميع وظائفنا مرة واحدة على الأقل ، وربما عدة مرات ، يمكننا كتابة تعريفات وظيفية غير فعالة تضمن الاتساق حتى في مواجهة حالات الفشل العشوائية.
بالعودة إلى مثال إرسال الرسائل ، كيف يمكننا استخدام هذه المفاهيم لضمان الاتساق؟ في هذه الحالة ، قد نقسم المهمة إلى جزأين ، الأولى ترسل الرسالة وتضع الثانية في قائمة الانتظار ، والثانية تكتب إلى قاعدة البيانات. في هذا السيناريو ، يمكننا إعادة محاولة أي من المرات كما نريد - إذا كان مزود إرسال الرسائل معطلاً ، أو كانت قاعدة بيانات المحاسبة الداخلية معطلة ، فسنقوم بإعادة المحاولة بشكل مناسب حتى ننجح!
الأسوار الجيدة تصنع جيرانا جيدين
ماذا يحدث لمعالجة بيانات شركة Consolidated Widgets الخاصة بنا كمثال عندما تكون قاعدة بيانات Global Gizmos معطلة؟
في هذا السيناريو ، إذا كانت إستراتيجية التسليم الخاصة بنا تعمل مرة واحدة على الأقل ، فإننا نتوقع أن تعيد جميع وظائف معالجة البيانات الخاصة بـ Global Gizmos المحاولة مرارًا وتكرارًا حتى تنجح. هذا رائع - لن نفقد أي بيانات حتى أثناء تعطل قاعدة البيانات الخاصة بهم. ومع ذلك ، بالنسبة لـ Consolidated Widgets ، قد لا يكون الأمر بهذه الروعة: إذا كان العمال يعيدون المحاولة باستمرار ويفشلون ، فقد يكونون مشغولين جدًا لمعالجة عمل Consolidated Widgets في الوقت المناسب.
يمكننا إصلاح ذلك باستخدام أسماء قائمة انتظار مختارة جيدًا وإيقاف بعض قوائم الانتظار مؤقتًا حسب الحاجة. باستخدام هذا في حزام الأدوات الخاص بنا ، يمكننا تخفيف الضغط على أجزاء من البنية التحتية بطريقة جراحية. في السيناريو أعلاه ، بمجرد أن نعلم أن قاعدة بيانات Global Gizmos معطلة ، يمكننا إيقاف قائمة انتظار معالجة البيانات مؤقتًا حتى نعلم أنها تعمل احتياطيًا ، مما يضمن أن انقطاعًا معينًا لا يؤثر على أي عملاء آخرين!
الانتظار مؤلم
ماذا لو قامت Consolidated Widgets و Global Gizmos بإرسال حملات عبر البريد الإلكتروني إلى 50 مليون مستخدم لكل منهما ، بفاصل زمني قدره 5 دقائق؟ الذي يذهب أولا؟
تتميز أنظمة قائمة انتظار الوظائف البسيطة بقائمة انتظار "عمل" بسيطة يسحب العمال منها وظائفهم. بمجرد أن يكون لديك مجموعة متنوعة لطيفة من الوظائف وأنواع الوظائف المختلفة ، فمن المحتمل أن تنتقل إلى أنواع متعددة من قوائم الانتظار ، ولكل منها أولويات مختلفة أو أنواع مختلفة من العمال الذين ينسحبون من قوائم الانتظار هذه. في هذا السياق ، لدينا مجموعة متنوعة من قوائم الانتظار البسيطة لمعالجة البيانات والرسائل ومهام الصيانة المتنوعة.
تقدم سريعًا عندما ترسل مليارات الرسائل الشخصية يوميًا ، فلن تؤدي قائمة انتظار واحدة "للمراسلة" إلى قطعها — ماذا يحدث عندما تصبح قائمة الانتظار كبيرة للغاية ، كما في المثال أعلاه؟ هل نعطي الأولوية للوظائف التي وصلت أولاً؟
يسعى نظام الطابور الديناميكي الخاص بنا إلى معالجة ظاهرة تسمى التجويع الوظيفي ، حيث تنتظر الوظيفة الجاهزة للتنفيذ لفترة طويلة قبل التنفيذ ، عادةً بسبب نوع من الأولوية. في قائمة انتظار "المراسلة" البسيطة ، تكون الأولوية ببساطة هي الوقت الذي تدخل فيه الوظيفة في قائمة الانتظار ، مما يعني أن الوظائف المضافة إلى نهاية قائمة انتظار كبيرة يمكن أن تنتهي بالانتظار لفترة طويلة جدًا.
عندما ننتقل إلى قائمة انتظار إحدى الحملات وجميع رسائلها ، بدلاً من إضافة الوظائف إلى قائمة انتظار كبيرة "للمراسلة" ، فإننا ننشئ قائمة انتظار جديدة تمامًا لهذه الحملة فقط ، مع استكمال اسم خاص حتى نعرف ما هي و كيف تجده. بعد إضافة الوظائف إلى قائمة الانتظار ، نحصل على قائمة "قوائم الانتظار الديناميكية" الخاصة بنا ونضيف اسم قائمة الانتظار الجديد هذا إلى النهاية.
من خلال استخدام هذه الإستراتيجية ، يمكننا توجيه العمال لاختيار اسم قائمة انتظار ديناميكية من قائمة "قوائم الانتظار الديناميكية" ، ثم معالجة جميع الوظائف الموجودة في قائمة الانتظار المحددة هذه. يتيح لنا ذلك ضمان إرسال الرسائل في أسرع وقت ممكن وأن يتم التعامل مع جميع عملائنا بأولوية متساوية.
وبالتالي ، فإن هذا له فوائد أخرى ، مثل ارتفاع معدلات دخول ذاكرة التخزين المؤقت وعدد أقل من اتصالات قاعدة البيانات ، بسبب الزيادة في مكان العمل لعمال معينين. الجميع يفوز!
لدينا دائما خطة احتياطية
ماذا يحدث عندما تكون قاعدة البيانات معطلة ، وتتوقف بعض قوائم الانتظار مؤقتًا ، وتبدأ قوائم انتظار الوظائف بالملء؟
في بعض الأحيان تموت عليك أجزاء مهمة من البنية التحتية. لدينا خدمات ثانوية ونسخ احتياطية ، ولكن الوقت المستغرق لتعزيز البنية التحتية للنسخ الاحتياطي لا يكاد يكون صفراً. يمكن أن يكون وجود طبقات متعددة من قوائم الانتظار عبر البنية الأساسية للتطبيق بالكامل مفيدًا جدًا في التخفيف من تأثير هذه الأنواع من الأحداث.
إحدى هذه الإستراتيجيات التي نستخدمها هي الانتظار على الأجهزة نفسها. الملايين والملايين من الأجهزة لها تطبيقات مختلفة باستخدام Braze SDK ، وفي هذه التطبيقات ، نستخدم قائمة انتظار لإرسال البيانات إلى واجهات برمجة التطبيقات الخاصة بنا.
عندما ينتقل SDK الخاص بنا لإرسال تلك البيانات ويفشل ، لأي سبب من الأسباب ، تنتظر SDK إعادة المحاولة باستخدام خوارزمية التراجع الأسية حتى تنجح. تقلل هذه الإستراتيجية من تأثير فشل البنية التحتية أو الكود ، نظرًا لأن الأجهزة ستضع بياناتها في قائمة الانتظار وترسلها إلى Braze عندما يعود كل شيء إلى الإنترنت.
السرعة في التحرك وعدم كسرها
في نهاية اليوم ، هدفنا هو إرسال رسائل شخصية شديدة التركيز بشكل أفضل من أي شخص آخر ، وهذا يتضمن التحرك بسرعة ، والتحلي بالمرونة ، والحصول على كل شيء بشكل صحيح. تعد قوائم انتظار الوظائف في قلب البنية التحتية لـ Braze ، لذلك نحن دائمًا نراقب أدائنا ، ونستخدم أفضل الممارسات ، ونختبر إستراتيجيات جديدة وتقنيات متقدمة لنكون الأفضل في اللعبة.
إذا كان هذا النوع من هندسة الأنظمة عالية الأداء وقليلة التأخير في مجال أتمتة التسويق يثيرك ، فعليك بالتأكيد التحقق من لوحة الوظائف لدينا!