در اسپارک یک RDD می تواند به گونه مجموعه ای از دوتایی های Key-Value باشد که تابع های Transformation ویژه ای برای کار با این RDD های دوتایی فراهم شده است. پیش از آنکه بخواهیم عملگرهای Transformation را بگویی، باید بدانیم که چگونه می توانیم یک RDD دوتایی های Key-Value را بسازیم.

ساخت RDD از دوتایی ها

RDD های دوتایی چیز ویژه ای نیستند و آنها تنها دارای مجموعه ای از دوتایی های Key-Value هستند که در آن Value یک ارزش (یا مقدار) و Key کلیدی یا نشاسه ای به آن ارزش است. نیازی نیست که در آغاز مجموعه های دوتایی داشته باشیم و از این رو می توانیم داده ها را به کمک تابع هایی به دوتایی تبدیل کنیم. برای نمونه یک فایل ساده را می خوانیم که در این زمان یک RDD معمولی داریم ولی سپس آن را به یک RDD دوتایی تبدیل می کنیم.

تابع reduceByKey در RDD

تابع ()reduceByKey یک RDD از دوتایی ها را دریافت کرده و سپس ارزش ها را بر پایه کلیدها و عملگرهای دودویی مانند عملگرهای ریاضی یا عمگرهای مقایسه ای کاهش می دهد. در کدهای زیر نخست یک لیست به نام pairs از دوتایی ها نوشته شده است و سپس به کمک متد ()parallelize از کلاس SparkContext یک RDD ساخته شده است که اکنون یک RDD دوتایی است.

در نخستین فراخوانی تابع ()reduceByKey یک تابع بی نام به آن فرستاده شده است که دو ورودی x و y را دریافت کرده و سپس این دو ورودی را با هم جمع می کند. توجه کنید که پیش از این RDD دوتایی با ()parallelize ساخته شده است و گونه کلید و ارزش، هر دو رشته است. در دومین فراخوانی اگر x کمتر از y باشد، گزینه ای برگزیده شده x است وگرنه y برگزیده می شود.

مفهوم کاهش (Reduce) این است که تابع ()reduceByKey همه ارزش های کلیدهای یکسان را با یکدیگر ادغام می کند. اگر نوشته  به یاد داشته باشید، گفتیم که یک گام است که خروجی های تابع های نگاشت دهنده را دریافت و سپس به هر تابع کاهش دهنده دوتایی هایی می دهد که همه در نام کلید یکسان هستند. بنابراین تابع ()reduceByKey چنین کاری را انجام می دهد.

در کد زیر به کمک ()textFile یک فایل متنی ساده خوانده شده است که برآیند آن یک RDD به نام textRDD است. سپس به کمک متد ()first نخستین عنصر RDD به نام textRDD نشان داده می شود. سپس به کمک تابع ()map یک RDD تازه به نام pairRDD ساخته می شود. توجه کنید ورودی تابع ()map یک تابع بی نام است که یک ورودی که در هر گام یک خط از فایل است را دریافت می کند و سپس یک دوتایی می سازد که عنصر یکم آن خود خط و عنصر دوم آن اندازه خط است. بنابراین با تابع ()map توانستیم یک دوتایی بسیازیم و در دنباله و به کمک متد ()collect همه عنصرهای درون RDD به نام pairRDD را نشان داده ایم.

توجه کنید که متدهای ()first و ()collect هر دو عضوی از کلاس RDD هستند که به ترتیب نخستین عنصر و همه عنصرهای یک RDD را نشان می دهند.

سپس به کمک متد ()reduceByKey R دوتایی های درون pairRDD را بر پایه کلید مشترک دسته بندی می کنیم. البته در کد گفته شده، نخستین عنصر دوتایی ها خود خط و دومین، اندازه خط است که می توانید در تابع بی نام درون ()map جای آنها را تغییر دهید. برای درک این کد باید فایل متنی داشته باشید که خط هایی در آن باشد که با یکدیگر یکسان هستند. بنابراین دو تابع ()map و ()reduceByKey که هر دو بخشی از کلاس RDD هستند یک تابع بی نام را دریافت می کند ولی تابع ()reduceByKey ویژه RDD های دوتایی است. همچنین در آغاز، نخستین RDD با ()textFile از روی فایل متنی ساخته شده که هر عنصر آن یکی از خط های فایل است که می تواند اندازه اش صفر باشد، زیرا یک خط تهی (خالی) است. سپس یک دوتایی با متد ()map ساخته شد و در پایان عملیات کاهش با متد ()reduceByKey انجام شده است.

تابع ()groupByKey در RDD

به زبان ساده، ()groupByKey یک RDD از دوتایی ها را بر پایه کلیدهای یکسان، گروه بندی می کند. برای نمونه می خواهیم بر پایه اندازه یکسان هر خط، ارزش ها گروه بندی شوند که در اینجا کلید همان اندازه خط و ارزش (یا مقدار) نیز خود آن خط است. می توانند دو تابع ()reduceByKey و ()groupByKey برآیندی یکسان را بسازند ولی این دو از دید کارایی با یکدیگر متفاوت هستند.

در کدهای زیر، نخست یک لیست از دوتیی هایی داریم که عنصر نخست هر کدام یک رشته و دومین ارزش شماره ای دارند. می خواهیم به کمک متد ()groupByKey در گروه ها، شماره های هر دوتایی در یک گروه با یکدیگر جمع شوند. بنابراین ارزش ها با کلیدهای مشترک گروه بندی می شوند، به گونه ای که در گروه ها، عنصرهای دوم با یکدیگر جمع شده اند. توجه کنید هر دوتایی دارای دو عنصر است که در اسکالا نخستین عنصر دارای اندیس ۱ ولی در پایتون دارای اندیس صفر است. همچنین برای جمع در پایتون تابع ()sum به کار رفته است.