Hadoop MapReduce Join & Counter พร้อมตัวอย่าง
⚡ สรุปอย่างชาญฉลาด
MapReduce join จะรวมชุดข้อมูลขนาดใหญ่สองชุดเข้าด้วยกันโดยใช้คีย์ร่วมกัน ไม่ว่าจะภายใน mapper หรือ reducer ในขณะที่ MapReduce counter จะรวบรวมสถิติเกี่ยวกับงานเพื่อให้สามารถวัดผลข้อมูลที่ไม่ถูกต้องได้ แทนที่จะคาดเดา

Join ใน MapReduce คืออะไร?
การดำเนินการ Join ใน MapReduce ใช้สำหรับรวมชุดข้อมูลขนาดใหญ่สองชุดเข้าด้วยกัน อย่างไรก็ตาม กระบวนการนี้เกี่ยวข้องกับการเขียนโค้ดจำนวนมากเพื่อทำการรวมชุดข้อมูลจริง การรวมชุดข้อมูลสองชุดเริ่มต้นด้วยการเปรียบเทียบขนาดของแต่ละชุดข้อมูล หากชุดข้อมูลหนึ่งมีขนาดเล็กกว่าอีกชุดข้อมูลหนึ่ง ชุดข้อมูลที่เล็กกว่าจะถูกกระจายไปยังโหนดข้อมูลทุกโหนดในคลัสเตอร์
เมื่อเข้าร่วมแล้ว แผนที่ลด ในกรณีที่การประมวลผลแบบกระจายตัว ตัว Mapper หรือ Reducer จะใช้ชุดข้อมูลขนาดเล็กกว่าในการค้นหาเรคอร์ดที่ตรงกันจากชุดข้อมูลขนาดใหญ่ จากนั้นจึงรวมเรคอร์ดเหล่านั้นเข้าด้วยกันเพื่อสร้างเรคอร์ดผลลัพธ์
ประเภทของการเข้าร่วม
การเชื่อมต่อข้อมูลใน Hadoop แบ่งออกเป็นสองประเภท ขึ้นอยู่กับตำแหน่งที่ทำการเชื่อมต่อจริง
- เข้าร่วมฝั่งแผนที่ — เมื่อการเชื่อมต่อข้อมูลเกิดขึ้นโดยตัวแมปเปอร์ จะเรียกว่าการเชื่อมต่อฝั่งแมป (map-side join) ในรูปแบบนี้ การเชื่อมต่อจะเกิดขึ้นก่อนที่ข้อมูลจะถูกนำไปใช้ในฟังก์ชันแมปจริง ๆ จำเป็นอย่างยิ่งที่ข้อมูลนำเข้าของแต่ละแมปจะต้องอยู่ในรูปแบบของพาร์ติชันและเรียงลำดับแล้ว นอกจากนี้ จำนวนพาร์ติชันต้องเท่ากันและต้องเรียงลำดับตามคีย์การเชื่อมต่อด้วย
- ข้อต่อด้านลด — เมื่อตัวลด (reducer) ทำการเชื่อมข้อมูล จะเรียกว่าการเชื่อมข้อมูลฝั่งลด (reduce-side join) การเชื่อมข้อมูลแบบนี้ไม่จำเป็นต้องมีชุดข้อมูลในรูปแบบที่มีโครงสร้าง (หรือแบ่งพาร์ติชัน) การประมวลผลฝั่งแมป (map side processing) จะสร้างคีย์การเชื่อมและทูเปิลที่เกี่ยวข้องของทั้งสองตาราง ผลจากการประมวลผลนี้ ทูเปิลทั้งหมดที่มีคีย์การเชื่อมเดียวกันจะตกไปอยู่ในตัวลดเดียวกัน ซึ่งจะทำการเชื่อมข้อมูลที่มีคีย์การเชื่อมเดียวกันนั้น
ผังกระบวนการโดยรวมของการรวมใน Hadoop แสดงอยู่ในไดอะแกรมด้านล่าง

เมื่อเข้าใจสองรูปแบบนี้แล้ว ส่วนถัดไปจะอธิบายวิธีการใช้ reduce-side join กับไฟล์ข้อมูลขนาดเล็กสองไฟล์ของแผนก
วิธีรวมชุดข้อมูลสองชุด: ตัวอย่าง MapReduce
มีข้อมูลสองชุดอยู่ในไฟล์สองไฟล์ที่แตกต่างกัน (แสดงด้านล่าง) คีย์ Dept_ID มีอยู่ในทั้งสองไฟล์ เป้าหมายคือการใช้ MapReduce Join เพื่อรวมไฟล์เหล่านี้เข้าด้วยกัน
Input: ชุดข้อมูลป้อนเข้าคือไฟล์ข้อความชื่อ DeptName.txt และ DeptStrength.txt
ดาวน์โหลดไฟล์อินพุตได้จากที่นี่
รับรองว่ามี Hadoop ติดตั้งเรียบร้อยแล้ว ก่อนเริ่มต้นกระบวนการจริงตามตัวอย่าง MapReduce Join ให้เปลี่ยนผู้ใช้เป็น 'hduser' (รหัสผู้ใช้ที่ใช้ในการกำหนดค่า Hadoop คุณสามารถเปลี่ยนไปใช้รหัสผู้ใช้ที่ใช้ในการกำหนดค่า Hadoop ได้)
su - hduser_
ข้อความแจ้งเตือนจะเปลี่ยนเป็นบัญชี Hadoop ดังแสดงด้านล่าง
ขั้นตอน 1) คัดลอกไฟล์ zip ไปยังตำแหน่งที่คุณต้องการ
ขั้นตอน 2) คลายการบีบอัดไฟล์ซิป
sudo tar -xvf MapReduceJoin.tar.gz
อดีตtracชื่อไฟล์ ted จะเลื่อนผ่านไปขณะที่ tar กำลังแตกไฟล์เก็บถาวร
ขั้นตอน 3) ไปที่ไดเร็กทอรี MapReduceJoin/
cd MapReduceJoin/
ขั้นตอน 4) เริ่ม Hadoop
$HADOOP_HOME/sbin/start-dfs.sh
$HADOOP_HOME/sbin/start-yarn.sh
สคริปต์ทั้งสองจะแสดงรายชื่อของดีมอนที่พวกมันเรียกใช้งาน
ขั้นตอน 5) DeptStrength.txt และ DeptName.txt เป็นไฟล์อินพุตที่ใช้สำหรับโปรแกรมตัวอย่าง MapReduce Join นี้
จำเป็นต้องคัดลอกไฟล์เหล่านี้ไปยัง เอชดีเอฟเอส โดยใช้คำสั่งด้านล่างนี้
$HADOOP_HOME/bin/hdfs dfs -copyFromLocal DeptStrength.txt DeptName.txt /
ขั้นตอน 6) รันโปรแกรมโดยใช้คำสั่งด้านล่าง-
$HADOOP_HOME/bin/hadoop jar MapReduceJoin.jar MapReduceJoin/JoinDriver/DeptStrength.txt /DeptName.txt /output_mapreducejoin
คำสั่งจะถูกแสดงออกมาก่อน จากนั้นกระบวนการจะรายงานความคืบหน้าบนคอนโซล
ขั้นตอน 7) หลังจากดำเนินการเสร็จสิ้น ไฟล์ผลลัพธ์ (ชื่อ 'part-00000') จะถูกจัดเก็บไว้ในไดเร็กทอรี /output_mapreducejoin บน HDFS
สามารถดูผลลัพธ์ได้โดยใช้อินเทอร์เฟซบรรทัดคำสั่ง
$HADOOP_HOME/bin/hdfs dfs -cat /output_mapreducejoin/part-00000
สามารถดูผลลัพธ์ได้ผ่านทางเว็บอินเตอร์เฟสเช่นกัน
จากนั้นเลือก 'เรียกดูระบบไฟล์' และไปยังไดเร็กทอรี /output_mapreducejoin
เปิด part-r-00000
ผลลัพธ์จะปรากฏขึ้น
หมายเหตุ: โปรดทราบว่าก่อนที่จะรันโปรแกรมนี้ในครั้งต่อไป คุณจะต้องลบไดเร็กทอรีเอาต์พุต /output_mapreducejoin
$HADOOP_HOME/bin/hdfs dfs -rm -r /output_mapreducejoin
ทางเลือกอื่นคือใช้ชื่ออื่นสำหรับไดเร็กทอรีเอาต์พุต
การเชื่อมต่อข้อมูลจะบอกคุณว่าข้อมูลมีลักษณะอย่างไร ส่วนตัวนับ ซึ่งจะกล่าวถึงในหัวข้อถัดไป จะบอกคุณว่ากระบวนการที่สร้างข้อมูลนั้นทำงานอย่างไร
ตัวนับใน MapReduce คืออะไร
ตัวนับใน MapReduce คือกลไกที่ใช้ในการรวบรวมและวัดข้อมูลทางสถิติเกี่ยวกับงานและเหตุการณ์ของ MapReduce ตัวนับจะเก็บข้อมูลต่างๆ ไว้ track คือค่าสถิติต่างๆ ของงานใน MapReduce เช่น จำนวนการดำเนินการที่เกิดขึ้นและความคืบหน้าของการดำเนินการ ตัวนับเหล่านี้ใช้สำหรับการวินิจฉัยปัญหาใน MapReduce
ตัวนับ Hadoop คล้ายกับการใส่ข้อความบันทึกลงในโค้ดสำหรับแผนที่หรือลดขนาด ข้อมูลนี้อาจเป็นประโยชน์สำหรับการวินิจฉัยปัญหาในการประมวลผลงาน MapReduce
โดยทั่วไป ตัวนับเหล่านี้ใน Hadoop จะถูกกำหนดไว้ในโปรแกรม (map หรือ reduce) และจะเพิ่มขึ้นระหว่างการทำงานเมื่อเกิดเหตุการณ์หรือเงื่อนไขเฉพาะ (ที่เฉพาะเจาะจงกับตัวนับนั้น) ตัวอย่างการใช้งานตัวนับ Hadoop ที่ดีมากอย่างหนึ่งคือ... track รายการที่ถูกต้องและไม่ถูกต้องจากชุดข้อมูลอินพุต
ประเภทของตัวนับ MapReduce
โดยพื้นฐานแล้ว MapReduce Counter มีอยู่ 2 ประเภท
- ตัวนับในตัวของ Hadoop: มีตัวนับ Hadoop ในตัวบางตัวที่มีอยู่สำหรับแต่ละงาน ด้านล่างนี้เป็นกลุ่มตัวนับในตัว -
- ตัวนับงาน MapReduce — รวบรวมข้อมูลเฉพาะของงาน (เช่น จำนวนระเบียนข้อมูลขาเข้า) ในระหว่างการประมวลผล
- ตัวนับระบบไฟล์ — รวบรวมข้อมูล เช่น จำนวนไบต์ที่อ่านหรือเขียนโดยงานนั้นๆ
- ตัวนับรูปแบบไฟล์อินพุต — รวบรวมข้อมูลจำนวนไบต์ที่อ่านผ่าน FileInputFormat
- ตัวนับ FileOutputFormat — รวบรวมข้อมูลจำนวนไบต์ที่เขียนผ่านฟังก์ชัน FileOutputFormat
- เคาน์เตอร์งาน — ตัวนับเหล่านี้จะบันทึกสถิติโดยรวมของงาน เช่น จำนวนภารกิจที่เริ่มต้นสำหรับงานนั้นๆ
- ตัวนับที่ผู้ใช้กำหนดเอง: นอกเหนือจากตัวนับในตัวแล้ว ผู้ใช้ยังสามารถกำหนดตัวนับของตนเองได้โดยใช้ฟังก์ชันการทำงานที่คล้ายคลึงกันซึ่งมีอยู่ในภาษาโปรแกรม ตัวอย่างเช่น ใน Javaโดยใช้ 'enum' ในการกำหนดค่าตัวนับที่ผู้ใช้กำหนดเอง
💡 หมายเหตุเกี่ยวกับเวอร์ชัน: ตัวนับงานได้รับการดูแลโดยฝ่ายงานTracker ภายใต้ MRv1 บน YARN บทบาทนั้นเป็นของ MapReduce ApplicationMaster ดังนั้นชื่อตัวนับจึงยังคงอยู่ แต่ส่วนประกอบที่รายงานค่าเหล่านั้นได้เปลี่ยนไปแล้ว
งานหนึ่งๆ ไม่สามารถประกาศตัวนับได้ไม่จำกัดจำนวน mapreduce.job.counters.max โดยค่าเริ่มต้น การตั้งค่าจะจำกัดจำนวนรวมต่องานไว้ที่ 120 และงานที่ประกาศจำนวนมากกว่านั้นจะล้มเหลวพร้อมข้อความแสดงข้อผิดพลาด LimitExceededExceptionดังนั้น ตัวนับจึงมีไว้สำหรับสัญญาณโดยรวมเพียงไม่กี่อย่าง มากกว่าการนับจำนวนตามแต่ละคีย์
ตัวอย่างเคาน์เตอร์
ตัวอย่าง MapClass ที่มีตัวนับเพื่อนับจำนวนค่าที่หายไปและค่าที่ไม่ถูกต้อง ไฟล์ข้อมูลที่ใช้ในบทช่วยสอนนี้คือไฟล์ CSV ชื่อ SalesJan2009.csv
public static class MapClass extends MapReduceBase implements Mapper<LongWritable, Text, Text, Text> { static enum SalesCounters { MISSING, INVALID }; public void map ( LongWritable key, Text value, OutputCollector<Text, Text> output, Reporter reporter) throws IOException { //Input string is split using ',' and stored in 'fields' array String fields[] = value.toString().split(",", -20); //Value at 4th index is country. It is stored in 'country' variable String country = fields[4]; //Value at 8th index is sales data. It is stored in 'sales' variable String sales = fields[8]; if (country.length() == 0) { reporter.incrCounter(SalesCounters.MISSING, 1); } else if (sales.startsWith("\"")) { reporter.incrCounter(SalesCounters.INVALID, 1); } else { output.collect(new Text(country), new Text(sales + ",1")); } } }
โค้ดตัวอย่างด้านบนแสดงการใช้งานตัวนับใน Hadoop MapReduce
ที่นี่ เคาน์เตอร์ขาย เป็นตัวนับที่กำหนดโดยใช้ 'อีนุมใช้สำหรับนับจำนวนข้อมูลที่ขาดหายไปและข้อมูลที่ไม่ถูกต้อง
ในโค้ดตัวอย่าง ถ้า 'ประเทศ'หากฟิลด์มีความยาวเป็นศูนย์ ค่าของฟิลด์นั้นจะหายไป และตัวนับที่เกี่ยวข้อง SalesCounters.MISSING จะถูกเพิ่มขึ้น'
ต่อไป ถ้า 'ขายหากฟิลด์เริ่มต้นด้วยเครื่องหมาย “ แสดงว่าเรคอร์ดนั้นไม่ถูกต้อง ซึ่งจะแสดงโดยการเพิ่มค่าตัวนับ SalesCounters.INVALID ขึ้นไปเรื่อยๆ
💡 หมายเหตุเกี่ยวกับ API: โค้ดด้านบนใช้ต้นฉบับ org.apache.hadoop.mapred API ที่ MapReduceBaseที่ Mapper อินเตอร์เฟซ, OutputCollector และ Reporter ปรากฏแยกกัน โค้ดปัจจุบันเขียนขึ้นโดยคำนึงถึงสิ่งต่อไปนี้ org.apache.hadoop.mapreduceโดยที่เพียงอันเดียว Context แทนที่ตัวเก็บรวบรวมและตัวรายงาน และตัวนับจะเพิ่มขึ้นทีละหนึ่ง context.getCounter(SalesCounters.MISSING).increment(1)แนวคิดเรื่องตัวนับนั้นเหมือนกันในทั้งสองแบบ











