در این فصل به برخی قابلیت‌های پیشرفته‌تر MapReduce شامل شمارنده‌ها و مرتب‌سازی (sorting) و به هم پیوستن (joining) دیتاست‌ها پرداخته شده است. همچنین توزیع داده‌های جانبی و کلاس‌های کتابخانه MapReduce معرفی شده‌اند که در ادامه به طور خلاصه به هر یک از آنها می‌پردازیم.

  1. شمارنده‌ها:

انواع شمارنده‌هایی که در این قسمت معرفی شده‌اند عبارتند از شمارنده‌های Built-in، شمارنده‌های جاوا تعریف شده توسط کاربر، شمارنده‌های جریان تعریف شده توسط کاربر.

  • Built-in Counters:

هدوپ دارای شمارنده‌های built-in برای هر job می‌باشد که متریک‌های مختلفی را گزارش می‌دهند. به طور مثال شمارنده‌هایی برای تعداد بایت‌ها و رکوردهایی که پردازش می‌شوند و به شما اجازه می‌دهند تا مقدار مورد انتظار از ورودی و خروجی را تأیید نمایید. شمارنده‌های built-in یا شمارنده task هستند یا شمارنده job.

  • شمارنده‌های Task:

این شمارنده‌ها اطلاعاتی در مورد task ها در مسیر اجرای آنها جمع‌آوری کرده و نتایج بر روی تمامی taskهای یک job تجمیع می‌شود. به طور مثال شمارنده MAP_INPUT_RECORDS تعداد رکوردهای ورودی خوانده شده توسط هر map task را می‌شمارد و بر روی همه map taskها در یک job تجمیع میکند. هنگامی که job با موفقیت به اتمام برسد، مقادیر شمارنده نهایی می‌گردد. با این حال برخی از شمارنده‌ها اطلاعات مفیدی را در حین پیشرفت task ارائه میدهند که میتواند برای پایش آنها با web UI مفید باشد.

 به طور مثال PHYSICAL_MEMORY_BYTES، VIRTUAL_MEMORY_BYTES و COMMITED_HEAP_BYTES بیانگر چگونگی تغییرات مصرف حافظه در جریان انجام یک task خاص می‌باشند. سایر شمارنده‌های task عبارتند از شمارنده‌های فایل سیستم، FileInputFormat و FileOutputFormat.

  • شمارنده‌های Job:

همانطور که ذکر شد، از دیگر شمارنده‌های built-in شمارنده‌های job میباشند که توسط application master نگهداری می‌شوند. این شمارنده‌ها آمار مربوطه را در سطح job اندازه‌گیری میکنند و نه مقادیری که در حین اجرای task تغییر میکند. به طور مثال TOTAL_LAUNCHED_MAPS، تعداد map taskهایی را که در مسیر یک job آغاز شدند می‌شمارد.

User-Defined Java Counters -2-1:

MapReduce این امکان را فراهم می‌نماید که کاربر یک مجموعه از شمارنده‌ها را تعریف نماید که میتوانند به دلخواه در mapper یا reducer افزایش یابند و این شمارنده‌ها توسط Java enum تعریف می‌شوند. شمارنده‌ها به صورت سراسری هستند. به این معنا که چارچوب MapReduce شمارنده‌ها را در تمامی mapها و reduceها تجمیع میکند تا در انتهای یک job، مجموع کل را ایجاد نماید.

User-Defined Streaming Counters -3-1:

یک برنامه Streaming MapReduce میتواند شمارنده‌ها را با ارسال یک خط با فرمت مشخص به جریان خطای استاندارد، افزایش دهد. این خط باید دارای فرمت زیر باشد:

reporter:counter:group,counter,amount

  1. مرتب سازی (Sorting):

توانایی مرتب‌سازی داده‌ها در مرکز MapReduce قرار دارد. حتی اگر کاربرد مورد نظر شما فی‌نفسه مرتبط با مرتب‌سازی نباشد، میتواند از مرحله مرتب‌سازی که MapReduce فراهم می‌نماید جهت سازماندهی داده‌ها استفاده نماید.

1-2- مرتب‌سازی جزئی

به صورت پیش‌فرض MapReduce رکوردهای ورودی را بر اساس کلیدهای آنها مرتب می‌کند. ترتیب برای کلیدها توسط RawComparator کنترل می‌شود. به طور مثال کد زیر با به‌کارگیری 30 reducers اجرا می‌شود:

% hadoop jar hadoop-examples.jar SortByTemperatureUsingHashPartitioner \

-D mapreduce.job.reduces=30 input/ncdc/all-seq output-hashsort

این دستور 30 فایل خروجی تولید میکند که هریک از آنها مرتب شده‌اند. با این حال، راه ساده‌ای برای ترکیب فایل‌ها وجود ندارد (یعنی یک فایل مرتب شده به صورت global) که این موضوع در بسیاری از کاربردها اهمیت چندانی ندارد.

2-2- مرتب‌سازی کلی

پاسخ ساده به این سوال که چگونه می‌توان با استفاده از هدوپ یک فایل مرتب شده به صورت کلی را ایجاد نمود استفاده از یک پارتیشن یا به عبارت بهتر استفاده از Pig، Hive، Crunch یا Spark است که می‌توانند با یک دستور مرتب‌سازی را انجام دهند. اما برای فایل‌های بزرگ این روش ناکارآمد است چرا که یک ماشین باید تمام خروجی‌ها را پردازش نماید و بنابراین از مزایای معماری موازی که MapReduce ارائه می‌دهد، استفاده‌ای نمی‌شود. به جای آن میتوان مجموعه‌ای از فایل‌های مرتب شده ایجاد نمود که اگر به یکدیگر متصل شوند، یک فایل مرتب شده کلی را شکل میدهند و نکته این روش استفاده از پارتیشنری (partitioner) است که ترتیب کلی خروجی را رعایت نماید و البته لازم است سایز پارتیشن به دقت انتخاب شود. در این بخش مثال‌هایی در خصوص استفاده از TotalOrderPartitioner برای مرتب‌سازی کلی دیتا ارائه شده است.

3-2- مرتب‌سازی ثانویه (secondary sort)

چارچوب MapReduce رکوردها را بر اساس کلید پیش از اینکه به reducerها برسند مرتب می‌کند. با این حال برای هر کلید بخصوص مقادیر مرتب شده نیستند. ترتیبی که بر اساس آن مقادیر ظاهر می‌شوند، حتی از یک اجرا به اجرای دیگر نیز ثابت نبوده چرا که از map taskهای متفاوتی می‌آیند که میتوانند در زمان‌های متفاوتی از یک اجرا به اجرای دیگر به اتمام برسند. به طور معمول اغلب برنامه‌های MapReduce به نحوی نوشته می‌شوند که وابسته به ترتیبی که مقادیر برای تابع reduce ظاهر میشوند، نیستند. با این حال، میتوان توسط مرتب‌سازی و گروه‌بندی کلیدها به شیوه‌ای خاص، ترتیبی را بر روی مقادیر(values) اعمال نمود.

به طور خلاصه می‌توان گفت:

  • کلید را ترکیبی از کلید طبیعی و مقدار طبیعی قرار می‌دهد.
  • مقایسه کننده برای مرتب‌سازی باید بر اساس کلید ترکیبی مرتب‌سازی را انجام دهد.
  • پارتیشنر و مقایسه کننده گروه برای کلید ترکیبی باید فقط کلید طبیعی را برای پارتیشن‌بندی و گروه‌بندی در نظر بگیرد.

در این بخش نیز مثال‌هایی از جمله مرتب‌سازی ثانویه استریم‌ها، تابع Map برای مرتب‌سازی ثانویه در پایتون و ... ارائه شده است.

  1. Joins

MapReduce امکان اتصال یا پیوستن میان دیتاست‌های بزرگ را ایجاد می‌نماید. اما نوشتن کد برای join از ابتدا نسبتاً پیچیده است و به جای نوشتن برنامه‌های MapReduce میتوان از چارچوب‌های سطح بالاتر نظیر Pig، Hive، Cascading، Cruc یا Spark استفاده نمود که در آنها عملیات join بخش محوری پیاده‌سازی به شمار می‌رود. چگونگی پیاده‌سازی join وابسته به میزان بزرگی دیتاست‌هاست و اینکه چگونه پارتیشن‌بندی شده‌اند. اگر join توسط mapper انجام شود به آن map-side join گفته می‌شود و اگر توسط reducer انجام گردد، reduce-side-join نامیده می‌شود. Join در سمت reduce معمول‌تر از سمت map می‌باشد چرا که نیازی به این نیست که دیتاست‌های ورودی به نوعی ساختاریافته باشند اما در عین حال کارایی آن کمتر است.

  1. توزیع داده‌های جانبی (Side Data Distribution)

داده‌های جانبی به داده‌های فقط خواندنی اضافه‌ای گفته می‌شود که مورد نیاز توسط یک job جهت پردازش دیتاست اصلی هستند. چالش مورد بررسی عبارتست از در دسترس قرار دادن داده‌های جانبی به نحوی آسان و کارآمد برای تمامی taskهای map یا reduce.

1-4- استفاده از پیکربندی Job

در این روش میتوان زوج‌های دلخواه کلید-مقدار را در پیکربندی job  با به‌کارگیری متدهای مختلف setter بر روی Configuration تنظیم نمود. این شیوه هنگامی که میخواهید بخش کوچکی از متادیتا را به task مورد نظر ارسال نمایید بسیار مفید است.

2-4- Distributed Cache

به جای پشت سر هم قرار دادن داده‌های جانبی در پیکربندی Job، ترجیح بر این است که دیتاست‌ها را با استفاده از مکانیزم Cache توزیع شده هدوپ توزیع نمود. به این ترتیب سرویس کپی کردن فایل‌ها و آرشیوها در نودهای task در زمان مناسب جهت استفاده هنگام اجرا فراهم میگردد. کاربرد این روش برای ابزارهایی است که از GenericOptionsParser استفاده میکنند. روش کار به این صورت است که هنگامی که یک job شروع میشود، هدوپ فایل‌های مشخص شده توسط گزینه‌های –files، -archives و –libjars را بر روی فایل سیستم توزیع شده (معمولا HDFS) کپی مینماید. سپس پیش از آنکه task اجرا شود، مدیریت‌کننده نودها فایل‌ها را از فایل سیستم توزیع شده بر روی دیسک local (cache) کپی میکند. بنابراین task میتواند به فایل دسترسی داشته باشد.

  1. کلاس‌های کتابخانه MapReduce

هدوپ کتابخانه‌ای از mapperها و reducerها برای توابعی که به طور معمول مورد استفاده قرار می‌گیرند، ارائه داده است که در بخش انتهایی فصل لیست این کلاس‌ها و توضیح مختصری از هریک ارائه شده است و برای توضیحات بیشتر میتوان از مستندات جاوا مرتبط با آنها استفاده نمود.