เกี่ยวข้องกับCouchDBของฉันคำถาม
ใครสามารถอธิบาย MapReduce ในแง่ที่ numbnuts สามารถเข้าใจได้?
เกี่ยวข้องกับCouchDBของฉันคำถาม
ใครสามารถอธิบาย MapReduce ในแง่ที่ numbnuts สามารถเข้าใจได้?
คำตอบ:
ลงไปสู่พื้นฐานสำหรับ Map and Reduce
แผนที่เป็นฟังก์ชั่นที่ "แปลง" รายการในรายการบางประเภทเป็นรายการประเภทอื่นและนำพวกเขากลับมาอยู่ในรายการประเภทเดียวกัน
สมมติว่าฉันมีรายการตัวเลข: [1,2,3] และฉันต้องการสองครั้งทุกตัวเลขในกรณีนี้ฟังก์ชั่น "double every number" คือ function x = x * 2 และถ้าไม่มีการแมปฉันสามารถเขียนได้ พูดง่าย ๆ
A = [1, 2, 3]
foreach (item in A) A[item] = A[item] * 2
และฉันมี A = [2, 4, 6] แต่แทนที่จะเขียนลูปถ้าฉันมีฟังก์ชั่นแผนที่ฉันสามารถเขียนได้
A = [1, 2, 3].Map(x => x * 2)
x => x * 2 เป็นฟังก์ชั่นที่จะทำงานกับองค์ประกอบใน [1,2,3] สิ่งที่เกิดขึ้นคือโปรแกรมใช้แต่ละไอเท็มเรียกใช้งาน (x => x * 2) โดยใช้ x เท่ากับแต่ละไอเท็มและสร้างรายการผลลัพธ์
1 : 1 => 1 * 2 : 2
2 : 2 => 2 * 2 : 4
3 : 3 => 3 * 2 : 6
ดังนั้นหลังจากรันฟังก์ชั่นแผนที่ด้วย (x => x * 2) คุณจะมี [2, 4, 6]
ลดคือฟังก์ชั่นที่ "รวบรวม" รายการในรายการและดำเนินการคำนวณบางอย่างในพวกเขาทั้งหมดจึงลดพวกเขาให้เป็นค่าเดียว
การหาผลรวมหรือการหาค่าเฉลี่ยเป็นอินสแตนซ์ทั้งหมดของฟังก์ชันลด เช่นถ้าคุณมีรายการตัวเลขให้พูด [7, 8, 9] แล้วคุณอยากให้พวกมันรวมกันคุณจะเขียนลูปแบบนี้
A = [7, 8, 9]
sum = 0
foreach (item in A) sum = sum + A[item]
แต่ถ้าคุณมีฟังก์ชั่นลดขนาดคุณสามารถเขียนมันแบบนี้ได้
A = [7, 8, 9]
sum = A.reduce( 0, (x, y) => x + y )
ตอนนี้มันสับสนเล็กน้อยว่าทำไมมีการโต้แย้ง 2 ครั้ง (0 และฟังก์ชั่นที่มี x และ y) ผ่านไป เพื่อให้ฟังก์ชั่นลดมีประโยชน์จะต้องสามารถนำ 2 รายการคำนวณบางอย่างและ "ลด" ที่ 2 รายการเป็นเพียงค่าเดียวดังนั้นโปรแกรมสามารถลดแต่ละคู่ได้จนกว่าเราจะมีค่าเดียว
การดำเนินการจะเป็นดังนี้:
result = 0
7 : result = result + 7 = 0 + 7 = 7
8 : result = result + 8 = 7 + 8 = 15
9 : result = result + 9 = 15 + 9 = 24
แต่คุณไม่ต้องการเริ่มต้นด้วยเลขศูนย์ตลอดเวลาดังนั้นอาร์กิวเมนต์แรกอยู่ที่นั่นเพื่อให้คุณระบุค่าเมล็ดโดยเฉพาะค่าในครั้งแรก result =
บรรทัด
สมมติว่าคุณต้องการรวม 2 รายการอาจมีลักษณะเช่นนี้:
A = [7, 8, 9]
B = [1, 2, 3]
sum = 0
sum = A.reduce( sum, (x, y) => x + y )
sum = B.reduce( sum, (x, y) => x + y )
หรือเวอร์ชันที่คุณมีแนวโน้มจะพบในโลกแห่งความเป็นจริง:
A = [7, 8, 9]
B = [1, 2, 3]
sum_func = (x, y) => x + y
sum = A.reduce( B.reduce( 0, sum_func ), sum_func )
มันเป็นสิ่งที่ดีในซอฟต์แวร์ DB เพราะด้วยการสนับสนุน Map \ Reduce คุณสามารถทำงานกับฐานข้อมูลได้โดยไม่จำเป็นต้องรู้ว่าข้อมูลถูกเก็บไว้ในฐานข้อมูลเพื่อใช้อย่างไรนั่นคือสิ่งที่โปรแกรม DB ใช้
คุณเพียงแค่ต้องสามารถ "บอก" เครื่องยนต์ที่คุณต้องการโดยการจัดหาให้กับแผนที่หรือฟังก์ชั่นการลดแล้วเครื่องยนต์ DB สามารถหาทางไปรอบ ๆ ข้อมูลใช้ฟังก์ชันของคุณและสร้างผลลัพธ์ที่คุณต้องการ ต้องการทั้งหมดโดยที่คุณไม่รู้ว่ามันวนซ้ำไปมาในทุก ๆ บันทึกอย่างไร
มีดัชนีและคีย์และตัวเชื่อมและมุมมองและหลาย ๆ สิ่งที่ฐานข้อมูลเดียวสามารถเก็บไว้ได้ดังนั้นโดยการป้องกันคุณกับวิธีการจัดเก็บข้อมูลจริงรหัสของคุณจะง่ายต่อการเขียนและบำรุงรักษา
เช่นเดียวกันสำหรับการเขียนโปรแกรมแบบขนานหากคุณระบุเฉพาะสิ่งที่คุณต้องการจะทำกับข้อมูลแทนที่จะใช้รหัสลูปจริง ๆ แล้วโครงสร้างพื้นฐานที่สามารถ "ขนาน" และดำเนินการฟังก์ชั่นของคุณในลูปขนานพร้อมกันสำหรับคุณ
Average()
Sum()
แต่ฉันได้พูดถึงเรื่องนี้เพื่อแสดงให้เห็นว่าเหตุใดฟังก์ชันจึงถูกเรียกว่า "ลด" ... ฟังก์ชันเฉลี่ยคือสิ่งที่รับรายการตัวเลขและลดลงเป็นตัวเลขเดียว (ซึ่งก็คือค่าเฉลี่ย)
MapReduce เป็นวิธีการประมวลผลข้อมูลจำนวนมหาศาลในแบบคู่ขนานโดยไม่ต้องให้ผู้พัฒนาเขียนโค้ดอื่นใดนอกเหนือจาก mapper และลดฟังก์ชั่น
แผนที่ฟังก์ชั่นใช้เวลาในข้อมูลและปั่นออกผลซึ่งจะจัดขึ้นในอุปสรรค ฟังก์ชันนี้สามารถทำงานพร้อมกันกับงานแผนที่เดียวกันจำนวนมาก ชุดข้อมูลสามารถลดลงได้เป็นค่าสเกลาร์
ดังนั้นถ้าคุณคิดว่ามันเหมือนคำสั่ง SQL
SELECT SUM(salary)
FROM employees
WHERE salary > 1000
GROUP by deptname
เราสามารถใช้แผนที่เพื่อรับชุดย่อยของพนักงานที่มีเงินเดือน> 1,000 ซึ่งแผนที่จะส่งสิ่งกีดขวางไปยังถังขนาดกลุ่ม
การลดจะรวมกลุ่มแต่ละกลุ่ม ให้ชุดผลลัพธ์แก่คุณ
เพิ่งดึงสิ่งนี้จากบันทึกการศึกษามหาวิทยาลัยของฉันเกี่ยวกับกระดาษ google
ขั้นตอนที่ 2 คือแผนที่ ขั้นตอนที่ 3 คือลด
ตัวอย่างเช่น,
เหตุผลที่ MapReduce ถูกแยกระหว่าง Map กับ Reduce นั้นเป็นเพราะส่วนต่าง ๆ นั้นสามารถทำขนานกัน (โดยเฉพาะอย่างยิ่งถ้าการลดมีคุณสมบัติทางคณิตศาสตร์บางอย่าง)
สำหรับคำอธิบายที่ซับซ้อน แต่ที่ดีของ MapReduce ดู: MapReduce ของ Google Programming รุ่น - เยือน (PDF)
MAP และ REDUCE เป็นฟังก์ชั่น Lisp แบบเก่าตั้งแต่ครั้งที่มนุษย์ฆ่าไดโนเสาร์ตัวสุดท้าย
ลองนึกภาพคุณมีรายชื่อเมืองที่มีข้อมูลเกี่ยวกับชื่อจำนวนผู้คนที่อาศัยอยู่ที่นั่นและขนาดของเมือง:
(defparameter *cities*
'((a :people 100000 :size 200)
(b :people 200000 :size 300)
(c :people 150000 :size 210)))
ตอนนี้คุณอาจต้องการค้นหาเมืองที่มีประชากรหนาแน่นที่สุด
ก่อนอื่นเราสร้างรายการชื่อเมืองและความหนาแน่นของประชากรโดยใช้ MAP:
(map 'list
(lambda (city)
(list (first city)
(/ (getf (rest city) :people)
(getf (rest city) :size))))
*cities*)
=> ((A 500) (B 2000/3) (C 5000/7))
การใช้การลดซ้ำเราสามารถค้นหาเมืองที่มีความหนาแน่นของประชากรมากที่สุด
(reduce (lambda (a b)
(if (> (second a) (second b))
a
b))
'((A 500) (B 2000/3) (C 5000/7)))
=> (C 5000/7)
เมื่อรวมทั้งสองส่วนเข้าด้วยกันเราจะได้รับรหัสต่อไปนี้:
(reduce (lambda (a b)
(if (> (second a) (second b))
a
b))
(map 'list
(lambda (city)
(list (first city)
(/ (getf (rest city) :people)
(getf (rest city) :size))))
*cities*))
มาแนะนำฟังก์ชั่น:
(defun density (city)
(list (first city)
(/ (getf (rest city) :people)
(getf (rest city) :size))))
(defun max-density (a b)
(if (> (second a) (second b))
a
b))
จากนั้นเราสามารถเขียนรหัส MAP REDUCE ของเราเป็น:
(reduce 'max-density
(map 'list 'density *cities*))
=> (C 5000/7)
มันเรียกร้องMAP
และREDUCE
(การประเมินผลที่อยู่ภายในออก) ดังนั้นจึงเรียกว่าแผนที่ลด
max-density
เปรียบเทียบองค์ประกอบที่สองของ args ที่ผ่านไปใช่ไหม ขออภัยสำหรับการแก้ไขโง่ ๆ
ลองมาตัวอย่างจากกระดาษของ Google เป้าหมายของ MapReduce คือเพื่อให้สามารถใช้งานหน่วยการประมวลผลที่โหลดได้อย่างมีประสิทธิภาพซึ่งทำงานในแนวเดียวกับอัลกอริทึมบางชนิด ตัวอย่างมีดังต่อไปนี้: คุณต้องการแยกคำและจำนวนทั้งหมดในชุดเอกสาร
การใช้งานทั่วไป:
for each document
for each word in the document
get the counter associated to the word for the document
increment that counter
end for
end for
การใช้งาน MapReduce:
Map phase (input: document key, document)
for each word in the document
emit an event with the word as the key and the value "1"
end for
Reduce phase (input: key (a word), an iterator going through the emitted values)
for each value in the iterator
sum up the value in a counter
end for
คุณจะมีโปรแกรมหลักซึ่งจะแบ่งพาร์ติชันของเอกสารเป็น "แยก" ซึ่งจะถูกจัดการแบบขนานสำหรับเฟสแผนที่ ค่าที่ปล่อยออกมาจะถูกเขียนโดยผู้ปฏิบัติงานในบัฟเฟอร์เฉพาะสำหรับผู้ปฏิบัติงาน จากนั้นโปรแกรมหลักจะมอบหมายผู้ปฏิบัติงานอื่นให้ดำเนินการขั้นตอนการลดทันทีที่ได้รับแจ้งว่าบัฟเฟอร์พร้อมที่จะจัดการ
ผลลัพธ์ของผู้ปฏิบัติงานทุกคน (เป็นแผนที่หรือลดผู้ปฏิบัติงาน) อันที่จริงแล้วเป็นไฟล์ที่เก็บไว้ในระบบไฟล์แบบกระจาย (GFS สำหรับ Google) หรือในฐานข้อมูลแบบกระจายสำหรับ CouchDB
ข้อมูลเบื้องต้นง่ายๆอย่างรวดเร็วและ"สำหรับหุ่น" MapReduce สามารถดูได้ที่: http://www.marcolotz.com/?p=67
โพสต์เนื้อหาบางส่วนของมัน:
ก่อนอื่นทำไม MapReduce จึงถูกสร้างขึ้นตั้งแต่แรก
โดยทั่วไป Google ต้องการโซลูชันสำหรับการคำนวณงานขนาดใหญ่แบบขนานได้อย่างง่ายดายช่วยให้สามารถเผยแพร่ข้อมูลในเครื่องจำนวนมากที่เชื่อมต่อผ่านเครือข่าย นอกเหนือจากนั้นมันต้องจัดการกับความล้มเหลวของเครื่องจักรในวิธีที่โปร่งใสและจัดการปัญหาการปรับสมดุลโหลด
อะไรคือจุดแข็งที่แท้จริงของ MapReduce
หนึ่งอาจกล่าวได้ว่าเวทมนตร์ MapReduce ขึ้นอยู่กับแอปพลิเคชั่นแผนที่และลดฟังก์ชั่น ฉันต้องสารภาพคู่ครองที่ฉันไม่เห็นด้วยอย่างยิ่ง คุณสมบัติหลักที่ทำให้ MapReduce ได้รับความนิยมคือความสามารถในการขนานและกระจายอัตโนมัติรวมกับส่วนต่อประสานที่เรียบง่าย ปัจจัยเหล่านี้รวมกับการจัดการความล้มเหลวโปร่งใสสำหรับข้อผิดพลาดส่วนใหญ่ทำให้กรอบนี้เป็นที่นิยม
ความลึกบนกระดาษอีกเล็กน้อย:
MapReduce ถูกกล่าวถึงในกระดาษ Google (Dean & Ghemawat, 2004 - ลิงค์ที่นี่) เป็นวิธีการแก้การคำนวณใน Big Data โดยใช้วิธีการแบบขนานและกลุ่มคอมพิวเตอร์สินค้า ตรงกันข้ามกับ Hadoop ที่เขียนด้วย Java กรอบงานของ Google เขียนด้วย C ++ เอกสารอธิบายถึงวิธีการทำงานของเฟรมเวิร์กแบบขนานโดยใช้แผนที่และลดฟังก์ชั่นจากการตั้งโปรแกรมการทำงานผ่านชุดข้อมูลขนาดใหญ่
ในการแก้ปัญหานี้จะมีสองขั้นตอนหลัก - เรียกว่าแผนที่และลด - ด้วยขั้นตอนเพิ่มเติมระหว่างแรกและที่สอง - เรียกว่ารวม ขั้นตอนแผนที่จะเรียกใช้ก่อนทำการคำนวณในคู่คีย์ - ค่าอินพุตและสร้างเอาต์พุตคีย์ - ค่าใหม่ เราต้องจำไว้ว่ารูปแบบของคู่คีย์ - ค่าอินพุตไม่จำเป็นต้องตรงกับคู่ของรูปแบบเอาต์พุต ขั้นตอนการลดจะรวบรวมค่าทั้งหมดของคีย์เดียวกันโดยดำเนินการคำนวณอื่น ๆ เป็นผลให้ขั้นตอนสุดท้ายนี้จะส่งออกคู่คีย์ - ค่า แอปพลิเคชั่นที่น่าสนใจที่สุดอย่างหนึ่งของ MapReduce คือการใช้การนับจำนวนคำ
โค้ดหลอกสำหรับแอปพลิเคชันนี้จะได้รับการร้อง:
map(String key, String value):
// key: document name
// value: document contents
for each word w in value:
EmitIntermediate(w, “1”);
reduce(String key, Iterator values):
// key: a word
// values: a list of counts
int result = 0;
for each v in values:
result += ParseInt(v);
Emit(AsString(result));
ตามที่สามารถสังเกตเห็นได้แผนที่จะอ่านทุกคำในเร็กคอร์ด (ในกรณีนี้เรคคอร์ดสามารถเป็นบรรทัด) และปล่อยคำเป็นคีย์และหมายเลข 1 เป็นค่า ในภายหลังการลดจะจัดกลุ่มค่าทั้งหมดของคีย์เดียวกัน ลองยกตัวอย่าง: ลองจินตนาการว่าคำว่า 'บ้าน' ปรากฏในบันทึกสามครั้ง อินพุตของตัวลดจะเป็น [บ้าน [1,1,1]] ในตัวลดมันจะรวมค่าทั้งหมดสำหรับกุญแจบ้านและให้ผลลัพธ์เป็นค่าคีย์ต่อไปนี้: [house, [3]]
นี่คือภาพว่าลักษณะนี้จะเป็นอย่างไรในกรอบ MapReduce:
ในฐานะตัวอย่างคลาสสิกอื่น ๆ ของแอปพลิเคชั่น MapReduce เราสามารถพูดได้ว่า:
•จำนวนความถี่ในการเข้าถึง URL
•ย้อนกลับกราฟลิงค์เว็บ
• Grep กระจาย
•เทอมเวกเตอร์ต่อโฮสต์
เพื่อหลีกเลี่ยงการรับส่งข้อมูลเครือข่ายมากเกินไปกระดาษอธิบายถึงวิธีที่กรอบควรพยายามบำรุงรักษาตำแหน่งข้อมูล ซึ่งหมายความว่าควรพยายามตรวจสอบให้แน่ใจเสมอว่าเครื่องที่ใช้งานแผนที่มีข้อมูลในหน่วยความจำ / ที่เก็บข้อมูลในตัวเครื่องหลีกเลี่ยงการดึงข้อมูลจากเครือข่าย มีวัตถุประสงค์เพื่อลดเครือข่ายด้วยการใช้ mapper ซึ่งเป็นขั้นตอนตัวเลือกเสริมที่อธิบายไว้ก่อนหน้านี้ Combiner ทำการคำนวณบนเอาต์พุตของตัวแม็พในเครื่องที่กำหนดก่อนส่งไปยัง Reducers - ที่อาจอยู่ในเครื่องอื่น
เอกสารยังอธิบายถึงองค์ประกอบของเฟรมเวิร์กที่ควรปฏิบัติในกรณีที่เกิดข้อบกพร่อง ในเอกสารเหล่านี้เรียกว่าเป็นผู้ปฏิบัติงานและผู้เชี่ยวชาญ พวกเขาจะถูกแบ่งออกเป็นองค์ประกอบที่เฉพาะเจาะจงมากขึ้นในการใช้งานโอเพ่นซอร์ส เนื่องจาก Google ได้อธิบายถึงวิธีการในเอกสารเท่านั้นและไม่ได้เผยแพร่ซอฟต์แวร์ที่เป็นกรรมสิทธิ์จึงมีการสร้างเฟรมเวิร์กโอเพนซอร์ซจำนวนมากเพื่อใช้โมเดล เป็นตัวอย่างหนึ่งอาจพูด Hadoop หรือคุณลักษณะ MapReduce จำกัด ใน MongoDB
รันไทม์ควรดูแลรายละเอียดโปรแกรมเมอร์ที่ไม่ใช่ผู้เชี่ยวชาญเช่นการแบ่งพาร์ติชันข้อมูลอินพุตการกำหนดตารางเวลาการดำเนินการของโปรแกรมในชุดของเครื่องจักรขนาดใหญ่การจัดการกับความล้มเหลวของเครื่องจักร . ผู้ใช้ที่มีประสบการณ์สามารถปรับพารามิเตอร์เหล่านี้ได้เช่นเดียวกับวิธีการแบ่งพาร์ติชันข้อมูลระหว่างพนักงาน
แนวคิดหลัก:
•ความอดทนผิดพลาด:มันจะต้องทนต่อความล้มเหลวของเครื่องจักรอย่างสง่างาม ในการที่จะทำสิ่งนี้เจ้านายก็จะทำการส่งคนงานเป็นระยะ หากต้นแบบไม่ได้รับการตอบสนองจากผู้ปฏิบัติงานที่ได้รับในช่วงเวลาที่แน่นอนต้นแบบจะกำหนดงานที่ล้มเหลวในผู้ปฏิบัติงานนั้น ในกรณีนี้งานแผนที่ทั้งหมดที่เสร็จสิ้นโดยผู้ปฏิบัติงานผิดพลาดจะถูกโยนออกไปและมอบให้กับผู้ปฏิบัติงานอื่นที่มีอยู่ สิ่งที่คล้ายกันจะเกิดขึ้นหากผู้ปฏิบัติงานยังคงประมวลผลแผนที่หรือลดภาระงาน โปรดทราบว่าหากผู้ปฏิบัติงานเสร็จสิ้นส่วนที่ลดแล้วการคำนวณทั้งหมดก็เสร็จสิ้นตามเวลาที่ล้มเหลวและไม่จำเป็นต้องรีเซ็ต ในฐานะที่เป็นจุดหลักของความล้มเหลวถ้าต้นแบบล้มเหลวงานทั้งหมดล้มเหลว ด้วยเหตุผลนี้เราอาจกำหนดจุดตรวจตามกำหนดเวลาสำหรับต้นแบบเพื่อบันทึกโครงสร้างข้อมูล
• สถานที่:เพื่อหลีกเลี่ยงการรับส่งข้อมูลเครือข่ายเฟรมเวิร์กจะพยายามตรวจสอบให้แน่ใจว่าข้อมูลอินพุตทั้งหมดนั้นพร้อมใช้งานในเครื่องของเครื่องที่กำลังทำการคำนวณ ในคำอธิบายดั้งเดิมจะใช้ Google File System (GFS) ด้วยปัจจัยการจำลองแบบที่กำหนดเป็น 3 และขนาดบล็อก 64 MB ซึ่งหมายความว่าบล็อกเดียวกันของ 64 MB (ที่เขียนไฟล์ในระบบไฟล์) จะมีสำเนาเหมือนกันในเครื่องที่แตกต่างกันสามเครื่อง ต้นแบบรู้ว่าบล็อกอยู่ที่ไหนและพยายามกำหนดเวลางานแผนที่ในเครื่องนั้น หากล้มเหลวเจ้านายพยายามจัดสรรเครื่องใกล้กับแบบจำลองของข้อมูลที่ป้อนงาน (เช่นเครื่องทำงานในชั้นวางเดียวกันของเครื่องข้อมูล)
•ความละเอียดของงาน:สมมติว่าแต่ละเฟสของแผนที่แบ่งออกเป็นชิ้นส่วน M และแต่ละส่วนช่วงย่อจะถูกแบ่งออกเป็นชิ้นส่วนอุดมคติจะเป็นที่ M และ R มีขนาดใหญ่กว่าจำนวนของเครื่องจักรงาน นี่คือความจริงที่ว่าผู้ปฏิบัติงานที่ทำหน้าที่แตกต่างกันจำนวนมากช่วยปรับปรุงสมดุลภาระแบบไดนามิก นอกจากนั้นมันจะเพิ่มความเร็วในการกู้คืนในกรณีที่ผู้ปฏิบัติงานล้มเหลว (เนื่องจากงานแผนที่จำนวนมากที่เสร็จสิ้นแล้วสามารถกระจายไปทั่วเครื่องอื่น ๆ ทั้งหมด)
• ภารกิจการสำรองข้อมูล:บางครั้งผู้ทำงานใน Map หรือ Reducer อาจทำงานช้ากว่าคนอื่น ๆ ในคลัสเตอร์ สิ่งนี้อาจเก็บเวลาการประมวลผลทั้งหมดและทำให้เท่ากับเวลาประมวลผลของเครื่องช้าที่เดียว กระดาษต้นฉบับอธิบายถึงทางเลือกที่เรียกว่างานสำรองข้อมูลที่กำหนดเวลาโดยต้นแบบเมื่อการดำเนินการ MapReduce ใกล้เสร็จสมบูรณ์ เหล่านี้เป็นงานที่กำหนดโดย Master of งานระหว่างทำ ดังนั้นการดำเนินการ MapReduce เสร็จสมบูรณ์เมื่อการสำรองข้อมูลหลักหรือเสร็จสิ้น
•ตัวนับ:บางครั้งอาจต้องการนับเหตุการณ์ที่เกิดขึ้น ด้วยเหตุนี้จึงนับว่าสร้างได้ที่ไหน ค่าตัวนับในพนักงานแต่ละคนจะได้รับการถ่ายทอดไปยังต้นแบบเป็นระยะ ต้นแบบจะรวมตัวกัน (อ๋อดูเหมือนว่า Pregel aggregators มาจากสถานที่นี้) ค่าตัวนับของแผนที่ที่ประสบความสำเร็จและลดงานและส่งกลับไปยังรหัสผู้ใช้เมื่อการดำเนินการ MapReduce เสร็จสมบูรณ์ นอกจากนี้ยังมีค่าตัวนับปัจจุบันที่มีอยู่ในสถานะหลักดังนั้นการเฝ้าดูกระบวนการสามารถติดตามพฤติกรรมของมันได้
ฉันเดาด้วยแนวคิดทั้งหมดข้างต้น Hadoop จะเป็นเค้กชิ้นหนึ่งสำหรับคุณ หากคุณมีคำถามใด ๆ เกี่ยวกับบทความ MapReduce ดั้งเดิมหรือสิ่งที่เกี่ยวข้องโปรดแจ้งให้เราทราบ
ฉันไม่ต้องการฟังซ้ำซาก แต่สิ่งนี้ช่วยฉันได้มากและมันก็ค่อนข้างง่าย:
cat input | map | reduce > output
หากคุณคุ้นเคยกับ Python การอธิบายต่อไปนี้เป็นคำอธิบายที่ง่ายที่สุดของ MapReduce:
In [2]: data = [1, 2, 3, 4, 5, 6]
In [3]: mapped_result = map(lambda x: x*2, data)
In [4]: mapped_result
Out[4]: [2, 4, 6, 8, 10, 12]
In [10]: final_result = reduce(lambda x, y: x+y, mapped_result)
In [11]: final_result
Out[11]: 42
ดูการประมวลผลข้อมูลดิบแต่ละส่วนในกรณีนี้คูณด้วย 2 ( ส่วนแผนที่ของ MapReduce) จากข้อมูลmapped_result
เราสรุปได้ว่าผลลัพธ์จะเป็น42
( ส่วนที่ลดลงของ MapReduce)
ข้อสรุปที่สำคัญจากตัวอย่างนี้คือข้อเท็จจริงที่ว่าแต่ละกระบวนการประมวลผลไม่ได้ขึ้นอยู่กับกลุ่มข้อมูลอื่น ตัวอย่างเช่นหากthread_1
แมป[1, 2, 3]
และthread_2
แผนที่[4, 5, 6]
ผลลัพธ์สุดท้ายของเธรดทั้งสองจะยังคงอยู่[2, 4, 6, 8, 10, 12]
แต่เราได้ลดเวลาการประมวลผลลงครึ่งหนึ่ง เดียวกันสามารถพูดได้สำหรับการดำเนินการลดและเป็นสาระสำคัญของการทำงานของ MapReduce ในการคำนวณแบบขนาน