مثال على برامج MapReduce

مكتمل

كمثال بسيط على MapReduce، يمكننا كتابة وظيفة/برنامج يحسب الأوقات التي تظهر فيها كل كلمة في ملف أو مجموعة من الملفات. على سبيل المثال، إذا افترضنا ملفين، A وB، مع محتويات "هذه هي دورة حوسبة السحابة" و"هذا هو مسار التعلم 4 في دورة حوسبة السحابة"، فإننا نتوقع إخراجات مماثلة لما هو موضح في الجدول التالي. يطلق على مثل هذا البرنامج اسم WordCount. يتم تضمين برنامج WordCount في توزيع Hadoop وهو متوفر بسهولة للتشغيل والاختبار. وهو يمثل مجموعة واسعة من خوارزميات معالجة النصوص في تطبيقات البيانات الضخمة. وعلى هذا النحو، يعتبره الكثيرون حمل عمل قياسي متطور لتقييم كفاءة Hadoop. استخدمت ورقة MapReduce الأصلية1 WordCount كحمل عمل قياسي.

يوضح الجدول التالي تكرار كل كلمة في ملفين مع محتويات "هذه هي دورة حوسبة السحابة" و"هذا هو مسار التعلم 4 في دورة حوسبة السحابة"، كما يتم إنشاؤها افتراضًا بواسطة البرنامج القياسي WordCount:

Word عدد    Word عدد    Word عدد
هذه 2   حوسبة 2   4 1
عبارة عن 2   دورة 2   في 1
ص 1   التعلم 1   1
cloud 2   path 1      

يمكن كتابة برامج MapReduce بلغة برمجة Java. لكتابة برنامج WordCount (أو برامج MapReduce بشكل عام)، عادةً ما نبدأ بتحديد تنسيقات الإدخال والإخراج لدالات الخريطة والتقليل. وبما أننا نتعامل مع أزواج قيم المفاتيح، فإننا نحتاج فقط إلى تحديد المفاتيح والقيم الفعلية التي ستحتويها ملفات الإدخال والإخراج وأنواعها (مثل السلسلة أو العددية). يجب أن يحمل إدخال الوظيفة (مجموعة بيانات الإدخال)، كونه ملفًا واحدًا أو مليون ملف، التنسيق ذاته. وبشكل مماثل، يجب أن تعرض ملفات إخراج الوظيفة دائمًا التنسيق ذاته، الذي قد يختلف عن تنسيقات الإدخال.

يمكن أن تكون تنسيقات الإدخال والإخراج سجلات عشوائية تستند إلى سطر، على سبيل المثال، أو صور أو مقاطع فيديو أو سجلات متعددة الأسطر أو شيء مختلف تمامًا. بإمكان Hadoop معالجة أي تنسيق ملف، من نص ثابت والثنائي وحتى قواعد البيانات المركبة. لترتيب ذلك، يمكن للمستخدمين تجاوز فئات Hadoop InputFormat (TextInputFormat افتراضي) وOutputFormat (TextOutputFormat افتراضي). الأول يحدد كيفية قراءة ملفات الإدخال كأزواج قيم المفاتيح وينشئ تقسيمات الإدخال المقابلة لمهام الخريطة. ينتج محرك Hadoop مهمة خريطة واحدة لكل تقسيم إدخال ومن ثم يتم إنشاؤها. كما تحدد الفئة OutputFormat بشكل مماثل كيفية كتابة أزواج قيم المفاتيح عن طريق مهام التقليل كملفات إخراج إلى HDFS. يعرض الفيديو التالي توضيحًا تفصيليًا لكيفية استخدام الفئتين InputFormat وOutputFormat في Hadoop MapReduce.

فئات الإدخال/الإخراج الفرعية الافتراضية مناسبة لمعالجة النص. وبوجه خاص، تعمل TextInputFormat على تمكين قراءة الملفات النصية، مع إزاحة البايت من سطر يكون مفتاحًا ومحتوى الخط الفعلي يكون قيمة. تسمح TextOutputFormat بكتابة الملفات كأزواج قيم مفاتيح3 النص. يتم شحن فئات التنسيق الأخرى، مثل الفئتين SequenceFileInputFormat وSequenceFileOutputFormat، مع Hadoop وتسمح بقراءة الملفات الثنائية وكتابتها. بالإضافة إلى ذلك، يمكن لمستخدمي Hadoop دائمًا تنفيذ فئات تنسيق إدخال وإخراج مخصصة ومصممة خصيصًا لمجموعات بيانات الإدخال. يمكن العثور على مزيد من المعلومات حول كيفية القيام بذلك في "Hadoop: The Definitive Guide" من White.3

يفترض مثال WordCount لدينا إدخالات الملفات النصية. ومن ثم، يمكننا استخدام الفئة TextInputFormat مباشرة، مع مفتاح يُعد إزاحة بايت من سطر في ملف وقيمة كونها محتوى الخط ذاته. وعلاوة على ذلك، يمكننا استخدام الفئة TextOutputFormat مباشرة، مع مفتاح يُعد كلمة مصادفة في مجموعة بيانات الإدخال وقيمة كونها تكرار الكلمة. يمكن تعيين نوع المفتاح إلى Java Long (LongWritable في Hadoop) ونوع القيمة إلى Java String (Text في Hadoop). يجب أن تتلقى دالة التقليل كلمات من مهام الخريطة كمفاتيح والرقم 1 لكل كلمة كقيم،4 بحيث يكون نوع المفتاح هو الكلمات (Text) ونوع القيمة هو من أرقام الوحدة (Java Integer وIntWritable في Hadoop). كل ما تبقى هو منطق دالات الخريطة والتقليل. بالنسبة إلى دالة الخريطة، يجب تحليل تقسيمات الإدخال وكل كلمة منبعثة بعدد 1. في دالة التقليل، يمكن أن تكون كل كلمة تم تلقيها إخراجًا ببساطة مثل تكرارها، ويتم حسابها بعد جمع كل الأعداد 1 التي تم تلقيها مع تلك الكلمة.5

تعرض القصاصة البرمجية التالي مثال تعليمة WordCount البرمجية الكاملة لواجهة برمجية التطبيقات Java MapReduce API الجديدة التي تم إصدارها في Hadoop 0.20.0.

import java.io.IOException;
import java.util.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapreduce.*;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

public class WordCount {

	public static class WCMap extends Mapper<LongWritable, Text, Text,
	IntWritable> {
		private final static IntWritable one = new
				IntWritable(1);
		private Text word = new Text();

		public void map(LongWritable key, Text value, Context context) throws
		IOException, InterruptedException {
			String line = value.toString();
			StringTokenizer tokenizer = new StringTokenizer(line);

			while (tokenizer.hasMoreTokens()) {
				word.set(tokenizer.nextToken());
				context.write(word, one);
			}
		}
	}

	public static class WCReduce extends Reducer<Text, IntWritable, Text,
	IntWritable> {

		public void reduce(Text key, Iterable<IntWritable> values, Context
		context)
				throws IOException, InterruptedException {
			int sum = 0;
			for (IntWritable val : values) {
				sum += val.get();
			}
			context.write(key, new IntWritable(sum));
		}
	}

	public static void main(String[] args) throws Exception {
		Configuration conf = new Configuration();

		Job job = new Job(conf, "wordcount");

		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);

		job.setMapperClass(WCMap.class);
		job.setReducerClass(WCReduce.class);

		job.setInputFormatClass(TextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);

		FileInputFormat.addInputPath(job, new Path(args[1]));
		FileOutputFormat.setOutputPath(job, new Path(args[2]));

		job.waitForCompletion(true);
	}

}

توضح القصاصة البرمجية أن المبرمجين بحاجة إلى إنشاء اثنتين من الدالات التسلسلية فقط، وهما الخريطة والتقليل، المغلفتين في فئتين (داخليتين): في هذه الحالة، الفئتان الداخليتان WCMap وWCReduce. تعمل الفئة الداخلية WCMapعلى توسيع الفئة Mapper وتجاوز دالة map() لديها. تخطط الفئة Mapper أنواع زوج قيم مفاتيح الإدخال (LongWritable وText) لمجموعة من أنواع زوج قيم مفاتيح الإخراج (Text وIntWritable). يجب أن تطابق أنواع زوج قيم مفاتيح الإخراج التي تم تحديدها في الفئة Mapper دائمًا أنواع زوج قيم مفاتيح الإدخال في الفئة Reducer. تعمل الفئة الداخلية WCReduceعلى توسيع الفئة Reducer وتجاوز دالة reduce() لديها. بالإضافة إلى تحديد أنواع زوج قيم مفاتيح الإدخال، تعمل الفئة Reducer على تحديد أنواع زوج قيم مفاتيح الإخراج (Text وIntWritable) التي سيتم استخدامها من قبل مهام التقليل لإنشاء النتائج النهائية.

تعمل الدالتان map() وreduce() في الفئتين الداخليتين WCMap وWCReduce على دمج المنطق الفعلي لبرنامج WordCount. تعمل المعلمة Context في كلتا الدالتين على إجراء عمليات كتابة الإدخال/الإخراج على الأقراص المحلية وHDFS. تعمل الدالة main() على إعداد وظيفة لتنفيذ برنامج WordCount على مجموعة من ملفات الإدخال باستخدام الدالة addInputPath(). كما تحدد مكان وضع ملفات الإخراج على HDFS باستخدام الدالة setOutputPath(). في الدالة main()، تعمل setOutputKeyClass() وsetOutputValueClass() على تحديد أنواع زوج قيم المفاتيح المنبعثة من مهام التقليل وافتراض، بشكل افتراضي، أن هذه الأنواع تطابق أنواع قيم مفاتيح إخراج مهمة الخريطة. إذا لم يكن هذا هو الحال، يجب أن تعمل الدالةmain() أيضًا على استدعاء setMapOutputKeyClass() وsetMapOutputValueClass() لتحديد أنواع قيم مفاتيح إخراج مهمة الخريطة لتعيين تنسيقات الإدخال والإخراج، يتم استدعاء الدالتين setInputFormatClass() وsetOutputFormatClass(). وأخيرًا، يتم استخدام الدالتين setMapperClass() وsetReducerClass() لتعيين فئات الخريطة والتقليل الداخلية التأسيسية، WCMap وWCReduce. الفيديو التالي يناقش Sort، والذي هو مثال آخر كلاسيكي على MapReduce.

يعرض هذا الفيديو التالي Sobel، وهو مثال على معالجة الصور، واكتشاف الحافة.



3 لاحظ أنها مسافة جدولة (ليست مسافة واحدة) بين المفتاح والقيمة.

4 الرقم 1 لكل كلمة، W، هو الإخراج للإشارة إلى أن W قد ظهر في تقسيم الإدخال. وهذا يسمح لمهمة التقليل، التي تتلقى W، بزيادة عداده ببساطة إلى W.

5 بإمكان كل مهمة تقليل تلقي كلمات متعددة من مهام خريطة متعددة ولكن تظهر كل كلمة في مهمة تقليل واحدة فقط.


المراجع

  1. ي. Dean and S. Ghemawat (Dec. 2004). MapReduce: Simplified Data Processing on Large Clusters OSDI
  2. إم. Zaharia, A. Konwinski, A. Joseph, R. Katz, and I. Stoica (2008). تحسين أداء MapReduce في البيئات غير المتجانسة OSDI
  3. T. White (2011). Hadoop: الدليل التعريفي النسخة الثانية من O'Reilly

‏‫اختبر معلوماتك

1.

للحصول على مثال WordCount، ما دالة الجمع التي يمكن استخدامها للحصول على الإخراج الصحيح؟