Speculative Execution in Hadoop MapReduce

از سال 2004 که گوگل MapReduce رو به عنوان یک پلتفرم پردازش موازی معرفی کرد, افراد و کمپانی ها در تلاش بودند ابزار هایی برای مدیریت job ها و task های MapReduce پیاده سازی کنن, که Yarn و JobTracker و TaskTracker محبوبش از جمله این ابزار ها بودن, یکی از مشکلاتی که اجرای تسک ها باهاش مواجه میشن straggler یا علاف شدن تسک هست به این صورت که ممکنه یک تسک بیش از حد یا برای همیشه طول بکشه و اتمام اجرای job رو با مشکل مواجه کنه, اینجاست که از روشی به نام Speculative Execution برای حل مشکل استفاده میکنیم;

هدوپ درک و دیدی از کدی که داخل تسک ها در حال اجراست نداره, فقط کد جاوا رو در کانتینر های جاوا اجرا میکنه و ورودی و خروجی اونها رو تعیین و هدایت میکنه, بنابراین تنها ابزاری که برای تشخیص تسک های straggler داره مدت اجرا و مقدار پیشرفت اجرای تسکه (بر اساس تعداد خروجی هایی که تحویل داده)

حالا چه عواملی ممکنه موجب علاف شدن یه تسک بشن؟

میتونه عوامل داخلی داشته باشه از جمله:

  • ظرفیت ناهمگون ماشین های مختلف (یعنی منابع سرور هایی که تسک رو اجرا میکنن متفاوت باشه و باعث بشه روی ماشین ضعیف تر اجرای تسک بیشتر طول بکشه)
  • تسک های Map و Reduce که روی یک ماشین در حال اجرا هستن موجب کند شدن یک ماشین بشن (ممکنه به خاطر Data Locality یکی از ماشین ها تسک های بیشتری نسبت به بقیه متحمل بشه)

و عوامل خارجی از جمله:

  • رقابت بر سر منابع در شرایطی که منابع به صورت اشتراکی به کار میروند (یه تیم دیگه داره پدر سرور رو در میاره)
  • چولگی داده :) یا data skew. یعنی ممکنه دیتای شما یکنواخت نباشه, یه بخشی از داده بار پردازشی خیلی بیشتری نسبت به بقیه بخش های داده داشته باشه و پردازشش بیشتر طول بکشه
  • کندی ورودی و خروجی, ممکنه جایی که دیتا ازش خونده یا روش نوشته میشه به دلایل مختلف شبکه ای و فنی خیلی کند باشه.
  • مشکلات سخت افزاری, وقتی کلاستری متشکل از چند صد یا چند هزار ماشین در اختیار دارید, احتمال اینکه یکی از ماشین ها به مشکل سخت افزاری بخوره و کارشو درست انجام نده بیشتر میشه.

چطور تسک های کند رو پیدا کنیم؟

هدوپ به صورت پیش فرض روش خیلی ساده ای رو در پیش میگیره, اگه یه تسک زیر ۲۰ درصد پیشرفت کرده باشه و بیشتر از ۱ دقیقه طول کشیده باشه به عنوان تسک straggler شناسایی میشه. اما هرچیزی رو در جاوا میشه از نو نوشت و مقاله های زیادی در مورد شناسایی هوشمند تسک های کند نوشته شده.

پیداش کردیم, چیکارش کنیم؟

هدوپ وقتی تسک کند یا گیر کرده رو پیدا کرد, سریع یه نسخه دیگه از همون تسک رو یجای دیگه اجرا میکنه بعد نگاه میکنه کدومش زودتر تموم میشه, اونی که زودتر تموم کرد خروجیش رو ذخیره میکنه و تسک های replica رو kill میکنه.

مزایا:

در کل اگه Speculative Execution با سیاست درستی به کار گرفته بشه موجب میشه سرعت کلی اجرای job ها افزایش پیدا کنه و کلی ماشین بیکار معطل یه تسک که به دلایل مختلف گیر کرده نمیشن حتی اگه به قیمت اجرای موازی یکی دوتا تسک باشه.

معایب:

  • گفتیم که هدوپ درک درستی از ماهیت تسکی که داره انجام میده نداره, پس اگه با همین سیاست کورکورانه ای که بهش اشاره شد بزنه تعداد زیادی از تسک ها رو به عنوان straggler شناسایی کنه, به جای افزایش سرعت کار رو برای تسک هایی که واقعا دارن اجرا میشن و طول کشیدنشون کاملا نرماله سخت تر میشه.
  • علاوه بر اون وقتی یه reducer میخواد تسکی رو اجرا کنه باید خروجی mapper رو دریافت کنه, پس اگه یهو هدوپ تصمیم بگیره چندین تسک reducer رو replicate کنه, شبکه باید مقدار زیادی دیتا رو جابجا کنه و در اختیار reducer های موازی قرار بده.

--- به روز رسانی 17 دی 99:

  • یه وقتایی خروجی, از جمله خروجی Reducer صرفا در فایل نوشته نمیشه بلکه Output Committer شما دیتا رو یه جای خاصی مثل دیتابیس مینویسه (به عنوان مثال رجوع کنید به TableOutputFormat ) و اصطلاحا Idempotent نیست, اینجا هندل کردن Redundancy ای که در اثر Spec-exec ایجاد میشه گاهی اونقدر دردسرساز هست که ترجیح بدید حداقل روی Reducer این ویژگی رو غیر فعال کنید تا نتیجه ای که از دیتا میگیرید اشتباه نباشه.
  • و اینکه همونطور که در قسمت عوامل خارجی straggler شدن اشاره کردیم ممکنه چندین job مختلف در کلاستر در حال انجام باشن, در این صورت اجرا شدن spec-exec مربوط به یه job دیگه میتونه باعث کند شدن تسک های job ای بشه که قرار بوده خیلی عادی کارشو انجام بده, و اگه اشتباه نکنم چنین اتفاقی در بدترین حالت میتونه موجب cascading effect بشه و اون یکی job هم کند بشه و دوباره بره سراغ spec-exec.

میشه غیر فعالش کرد؟

دیدیم که Speculative Execution همیشه هم محبوب قلب ها نیست, و ممکنه مشکلات غیر قابل پیش بینی ایجاد کنه, برای همین خیلی وقتا تیم تصمیم میگیره این قابلیت رو برای reducer, mapper یا هردو غیر فعال کنه و اگر کسی این قابلیت رو نیاز داره در کانفیگ تسک جداگانه خودش این قابلیت رو فعال کنه.

برای غیر فعال کردن Speculative Execution در تسک های map از کانفیگ:

  • mapreduce.map.speculative

استفاده میکنیم که مقدارش به صورت پیش فرض true هست

برای reduce هم از کانفیگ

  • mapreduce.reduce.speculative

برای فعال یا غیر فعال کردن این ویژگی در کل job:

  • setSpeculativeExecution

این کانفیگ در فایل mapred-site.xml و یا کانفیگ های خود Job صورت میگیره.


نتیجه گیری:

در کل اگر کلاستر یکنواختی دارید و جاب ها با روال مشخصی روی کلاستر اجرا میشن شاید این قابلیت جلوی خیلی از تاخیر ها رو بگیره اما اگر فکر میکنید دردسر های این ویژگی بیشتر از مزایاش برای شما هزینه ایجاد میکنه میتونید به راحتی غیر فعالش کنید, یا اینکه وقت بزارید و الگوریتم های پیچیده تر و هوشمند تری برای شناسایی تسک های straggler بنویسید.


نکته: اصطلاح خلاصه شده spec-exec در ادبیات هدوپ خیلی رایج نیست و صرفا از سر تنبلی نویسنده استفاده شده, ولی در ادبیات طراحی پردازنده برای مفهومی تقریبا با همین ویژگی ها ازش استفاده میشه.

منابع:

https://data-flair.training/blogs/speculative-execution-in-hadoop-mapreduce/

https://techvidvan.com/tutorials/speculative-execution-in-hadoop/

http://zhenxiao.com/papers/TC-2012-07-0457.R1_Chen.pdf

https://hadoop.apache.org/docs/r1.2.1/api/org/apache/hadoop/mapreduce/Job.html#setGroupingComparatorClass(java.lang.Class)