در نوشته بخش سوم مفهوم RDD های دوتایی آغاز شود و نشان دادیم که می توانیم از روی خط های یک فایل متنی ساده یک RDD دوتایی بسازیم. برای نمونه دیگر، می توانید یک فایل CSV را در نظر بگیرید که هر سطر آن دو ستون دارد. در دنباله تابع Transformation برای RDD های دوتایی در این نوشته می خواهیم درباره تابع های دیگری همانند ()combinByKey بگوییم.

تابع ()combneByKey

برای درک بهتر چگونگی کارکرد تابع ()combineByKey باید پیش از آن تا اندازه ای با مفهوم Combiner در چارچوب MapReduce آشنا باشید. به زبان ساده Combiner در چارچوب MapReduce گامی میان نگاشت (Map) و کاهش (Reduce) است که حجم داده های انتقال شدنی از Map به Reduce را کاهش می دهد. بنابراین این متد نیز کاربردی همانند Combiner در چارچوب نگاشت کاهش دارد.

این تابع سه پارامتر ورودی را دریافت می کند که نخستین آنها createCombiner است و همانگونه که از نام آن آشکار است، این پارامتر یک Combiner را می سازد که سپس به کار گرفته می شود. این پارامتر برای نخستین بار زمانی فراخوانی می شود، زمانی که کلیدی برای یک یک پارتیشن پیدا می شود. همچنین این پارامتر نخستین گام تجمیع (Aggregation) برای هر کلید تازه در پارتیشن است.

mergeValue دومین پارامتری است که به تابع فرستاده می شود. این پارامتر وابستگی سر راستی به مفهومی به نام Accumulator دارد. Accumulator در اسپارک، یک متغیری است که برای تجمیع اطلاعات در سراسر Executor به کار گرفته می شود. Accumulator یا انباشته، یک متغیر اشتراکی (Shared Variable) است که از ویژگی های  شرکت پذیر (Associative Properties) و ویژگی های جابحایی پذیر (Commutative Properties) پشتیبانی می کند که هر دو برای موازی سازی نیاز هستند. به هر رو، این پارامتر زمانی فراخوانی می شود که کلید یک Accumulator داشته باشد. واپسین پارامتر mergeCominer نام دارد و زمانی فراخوانی می شود که بیش از یک پارتیشن باشد که Accumulator با کلیدی همسان داشته باشد. هر سه این پارامترها، تابع هایی هستند که به ترتیب پارامترهای یکم، دوم و سوم تابع ()combineByValue هستند.

در کد زیر که به پایتون است نخست یک لیست از دوتایی ها ساخته ایم و سپس از روی آن و به کمک متد ()parallelize یک دوتایی ساخته ایم. توجه کنید فهرست دوتایی ها تنها دارای سه کلید k1, k2 و k3 است و از این رو می خواهیم ارزش های این کلیدها را گروه بندی کنیم. در واقع ما به دنبال ساخت فهرست زیر هستیم.

(lambda val: (val, 1 نخستین تابع بی نامی است که در متغیری به نام createCombiner نگهداری می شود. این تابع سپس به نخستین پارامتر ()combineByKey فرستاده می شود. توجه کنید این تابع بی نام تنها یک پارامتر ورودی به نام دلخواه val دارد. این تابع روی هر دوتایی (Key, Value) از RDD دوتایی واگذار شده و سپس یک دوتایی تازه به گونه (Value, 1) را می سازد که در واقع می توانیم بگوییم دوتایی تازه به گونه (1, (Key, Value)) می سازد. برای نخستین دوتایی که به گونه (K1, 10) است یک دوتایی تازه (1, (K1, 10)) می سازد.

(1+ [lambda valcntpair, val: (valcntpair[0] + val, valcntpair[1 دومین تابع بی نامی است که در متغیر mergeValue نگهداری می شود و این همان تابعی است که به دومین پارامتر ()combineByKey فرستاده می شود. دومین پارمتر ()combineByKey گام ادغام است که هر زمان به یک کلید دیگر برسد، این پارامتر از نو انجام می شود. هر زمان که یک کلید دیگر پیدا شود، تابع بی نام، یک متغیر به نام valcntpair که کوتاه شده Value Count Pair یا دوتایی ارزش و شمار (تعداد) است را به کار می برد. پیش از این در گام Create Combiner، به هر ارزش (Key, Value) یک ارزش شماره ۱ داده می شود و از این رو در این زمان هر دوتایی یک بار تکرار شده است، بی توجه به این که کلید همسان باشد. سپس تابع بی نام مقدارهای تازه را با یک مقدار از پیش موجود ادغام و شمارش می کند. ایده این است که زمانی که کلیدی پیدا شده، آن به یک دوتایی از پیش موجود افزوده شده و سپس مقدار شمار (یا تعداد) یکی افزایش پیدا می کند. بنابراین ادغام ارزش یک کلید در یک دوتایی موجود و افزایش شمار آن کلید را از آن خواهیم داشت.

بنابراین تا بدین جا ادغام و شمارش انجام شد که بدین معنی است که، ما دوتایی ها به ازای هر کلید-ارزش داریم که یکی به شمار هر یک افزوده شده است. برای نمونه برای کلید k1 دو تا، دوتایی (2, (k1, 10)) و (2, (k1, 6)) داریم. اکنون باید این دوتایی را نیز ادغام کنیم تا دوتایی های ((k1′, (16, 2′) و ((k2′, (6, 2′) و ((k3′, (8, 2′) داشته باشیم، یعنی دوتایی هایی که کلید آنها k1, k2 و k3 است و ارزش هر کدام یک دوتایی دیگر که نخستین آرگومانش جمع همه ارزش های آن کلید و دومین عنصر آن شمار ارزش های همان کلید است که در اینجا هر کلید دو بار هست.

نمایش درون مایه RDD با تابع های ()take و ()first و ()collect

در کد بالا یکی دیگر از تابع نمایش درون مایه RDD به نام ()take به کار رفته است که یک شماره صحیح را دریافت می کند. در اینجا RDD پایانی که برآیند ()combineByKey است، دارای سه عنصر دوتایی است، زیرا در کل سه تا کلید داشتیم. بنابراین در کد زیر چون شماره ۳ به متد ()take فرستاده شده است، پس هر سه عنصر درون RDD نشان داده می شوند. برای نمونه اگر شماره ۱ فرستاده می شد، تنها نخستین عنصر نشان داده می شود. توجه کنید در کنار ()take، دو متد دیگر به نام ()first و ()collect نیز درون مایه RDD را نشان می دهند ولی ()first تنها نخستین عنصر را ولی ()collect همه عنصرها را نشان می دهد