ขั้นตอนแบ่งออกเป็นภารกิจใน Spark อย่างไร


143

สมมติว่าสำหรับ Spark ต่อไปนี้มีเพียงหนึ่งงานเท่านั้นที่ทำงานในทุกจุด

สิ่งที่ฉันได้รับจนถึง

นี่คือสิ่งที่ฉันเข้าใจว่าเกิดอะไรขึ้นใน Spark:

  1. เมื่อ a SparkContextถูกสร้างขึ้นโหนดของผู้ทำงานแต่ละคนจะเริ่มต้นตัวเรียกทำงาน ผู้บริหารเป็นกระบวนการแยก (JVM) ที่เชื่อมต่อกลับไปที่โปรแกรมไดรเวอร์ ผู้บริหารแต่ละคนมี jar ของโปรแกรมควบคุม การออกจากโปรแกรมควบคุมการปิดตัวจัดการการทำงาน ผู้บริหารแต่ละคนสามารถมีพาร์ติชันได้บ้าง
  2. เมื่องานถูกดำเนินการแผนการดำเนินการจะถูกสร้างขึ้นตามกราฟเชื้อสาย
  3. งานการดำเนินการจะแบ่งออกเป็นขั้นตอนที่ขั้นตอนที่มีการแปลงและการดำเนินการที่อยู่ใกล้เคียง (ในกราฟเชื้อสาย) เป็นจำนวนมาก แต่ไม่มีการสับ ดังนั้นขั้นตอนจะถูกคั่นด้วยการสับ

ภาพที่ 1

ฉันเข้าใจ

  • งานคือคำสั่งที่ส่งจากไดรเวอร์ไปยังผู้ปฏิบัติการโดยการทำให้วัตถุฟังก์ชั่นเป็นอนุกรม
  • ตัวจัดการ deserializes (พร้อมไดร์เวอร์ jar) คำสั่ง (ภารกิจ) และเรียกใช้งานบนพาร์ติชัน

แต่

คำถาม (s)

ฉันจะแบ่งเวทีออกเป็นงานเหล่านั้นได้อย่างไร

โดยเฉพาะ:

  1. งานนั้นถูกกำหนดโดยการเปลี่ยนแปลงและการกระทำหรืออาจเป็นการเปลี่ยนแปลง / การกระทำหลายอย่างในงานหรือไม่?
  2. เป็นงานที่กำหนดโดยพาร์ติชัน (เช่นงานหนึ่งงานต่อหนึ่งเวทีต่อพาร์ติชั่น)
  3. งานจะถูกกำหนดโดยโหนด (เช่นหนึ่งงานต่อขั้นต่อโหนด) หรือไม่?

สิ่งที่ฉันคิด (เฉพาะคำตอบบางส่วนแม้ว่าจะถูก)

ในhttps://0x0fff.com/spark-architecture-shuffleการสับเปลี่ยนจะถูกอธิบายด้วยภาพ

ป้อนคำอธิบายรูปภาพที่นี่

และฉันก็ได้รับความประทับใจว่าเป็นกฎ

แต่ละสเตจแบ่งออกเป็นงาน # number-of-partitions โดยไม่คำนึงถึงจำนวนโหนด

สำหรับภาพแรกของฉันฉันบอกว่าฉันมี 3 งานแผนที่และ 3 งานลด

สำหรับภาพจาก 0x0fff ฉันจะบอกว่ามี 8 งานแผนที่และ 3 ลดงาน (สมมติว่ามีเพียงสามไฟล์สีส้มและสามไฟล์สีเขียวเข้ม)

เปิดคำถามในทุกกรณี

ถูกต้องไหม แต่ถึงแม้ว่าจะถูกต้องแล้วคำถามของฉันยังไม่ได้รับคำตอบทั้งหมดเนื่องจากยังคงเปิดอยู่ไม่ว่าจะเป็นการดำเนินการหลายอย่าง (เช่นหลายแผนที่) ภายในงานเดียวหรือแยกออกเป็นงานเดียวต่อการปฏิบัติงาน

สิ่งที่คนอื่นพูด

ภารกิจใน Spark คืออะไร? ผู้ปฏิบัติงาน Spark ใช้งานไฟล์ jar อย่างไร และApache Scheduler แบ่งไฟล์เป็นอย่างไร? คล้ายกัน แต่ฉันไม่รู้สึกว่าคำถามของฉันได้รับคำตอบที่ชัดเจน

คำตอบ:


52

คุณมีเค้าโครงที่ดีงามที่นี่ เพื่อตอบคำถามของคุณ

  • แยกtask ไม่stageจำเป็นต้องได้รับการเปิดตัวสำหรับพาร์ทิชันของข้อมูลสำหรับแต่ละ พิจารณาว่าแต่ละพาร์ติชันมีแนวโน้มว่าจะอยู่ในตำแหน่งทางกายภาพที่แตกต่างกัน - เช่นบล็อกใน HDFS หรือไดเรกทอรี / ไดรฟ์สำหรับระบบไฟล์โลคัล

โปรดทราบว่าการส่งของStages DAG Schedulerจะขับเคลื่อนด้วย ซึ่งหมายความว่าสเตจที่ไม่พึ่งพาซึ่งกันและกันอาจถูกส่งไปยังคลัสเตอร์เพื่อดำเนินการแบบขนาน: สิ่งนี้จะช่วยเพิ่มความสามารถในการขนานในคลัสเตอร์ ดังนั้นหากการดำเนินการในดาต้าโฟลว์ของเราสามารถเกิดขึ้นได้พร้อมกันเราคาดว่าจะเห็นการเปิดตัวหลายขั้นตอน

เราจะเห็นว่าในการดำเนินการในตัวอย่างของเล่นต่อไปนี้ที่เราทำการดำเนินการประเภทต่อไปนี้:

  • โหลดสองแหล่งข้อมูล
  • ดำเนินการแผนที่บางอย่างในแหล่งข้อมูลทั้งสองแยกจากกัน
  • เข้าร่วมพวกเขา
  • ดำเนินการบางอย่างของแผนที่และตัวกรองตามผลลัพธ์
  • บันทึกผลลัพธ์

ดังนั้นเราจะจบด้วยกี่ขั้น?

  • 1 สเตจแต่ละครั้งสำหรับการโหลดสองแหล่งข้อมูลในแบบขนาน = 2 สเตจ
  • ขั้นตอนที่สามที่เป็นตัวแทนของjoinที่ขึ้นอยู่กับอีกสองขั้นตอน
  • หมายเหตุ: การดำเนินการติดตามทั้งหมดที่ทำงานกับข้อมูลที่เข้าร่วมอาจดำเนินการในขั้นตอนเดียวกันเนื่องจากจะต้องเกิดขึ้นตามลำดับ ไม่มีประโยชน์ในการเรียกใช้งานขั้นตอนเพิ่มเติมเนื่องจากไม่สามารถเริ่มทำงานได้จนกว่าการดำเนินการก่อนหน้านี้จะเสร็จสิ้น

นี่คือโปรแกรมของเล่น

val sfi  = sc.textFile("/data/blah/input").map{ x => val xi = x.toInt; (xi,xi*xi) }
val sp = sc.parallelize{ (0 until 1000).map{ x => (x,x * x+1) }}
val spj = sfi.join(sp)
val sm = spj.mapPartitions{ iter => iter.map{ case (k,(v1,v2)) => (k, v1+v2) }}
val sf = sm.filter{ case (k,v) => v % 10 == 0 }
sf.saveAsTextFile("/data/blah/out")

และนี่คือ DAG ของผลลัพธ์

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้: มีงานกี่งาน ? จำนวนงานควรเท่ากับ

ผลรวมของ ( Stage* #Partitions in the stage)


2
ขอบคุณ! โปรดอธิบายคำตอบของคุณเกี่ยวกับเนื้อหาของฉัน: 1) คำจำกัดความของขั้นตอนของฉันไม่ครอบคลุมหรือไม่? ดูเหมือนว่าฉันพลาดข้อกำหนดที่สเตจไม่สามารถมีการดำเนินการที่อาจขนานกันได้ หรือคำอธิบายของฉันอย่างนั้นหมายความว่าอย่างนั้น? 2) จำนวนงานที่ต้องดำเนินการสำหรับงานนั้นพิจารณาจากจำนวนพาร์ติชัน แต่ไม่ใช่จำนวนตัวประมวลผลหรือโหนดในขณะที่จำนวนงานที่สามารถดำเนินการได้ในเวลาเดียวกันขึ้นอยู่กับจำนวน โปรเซสเซอร์ใช่ไหม 3) งานสามารถมีการดำเนินงานหลายอย่าง?
Make42

1
4) คุณหมายถึงอะไรกับประโยคสุดท้ายของคุณ? ท้ายที่สุดจำนวนพาร์ติชั่นอาจแตกต่างกันไปในแต่ละด่าน คุณหมายถึงว่านี่เป็นวิธีกำหนดค่างานของคุณสำหรับทุกขั้นตอนหรือไม่
Make42

@ Make42 แน่นอนว่าจำนวนพาร์ติชั่นอาจแตกต่างกันไปในแต่ละด่าน - คุณถูกต้องแล้ว มันเป็นความตั้งใจของฉันโดยบอกว่าsum(..)คำนึงถึงการเปลี่ยนแปลงนั้น
javadba

ว้าวคำตอบของคุณก็โอเค แต่น่าเสียดายที่ประโยคสุดท้ายนั้นเป็นแนวคิดที่ผิด ไม่ได้หมายความว่าหมายเลขพาร์ติชันในสเตจเท่ากับจำนวนตัวประมวลผลอย่างไรก็ตามคุณสามารถตั้งค่าจำนวนพาร์ติชันสำหรับ RDD ตามจำนวนแกนที่แสดงบนเครื่องของคุณ
epcpu

@epcpu มันเป็นกรณีพิเศษ - แต่ฉันยอมรับว่าจะทำให้เข้าใจผิดดังนั้นฉันจึงลบมัน
javadba

26

สิ่งนี้อาจช่วยให้คุณเข้าใจชิ้นส่วนต่าง ๆ ได้ดีขึ้น:

  • เวที: เป็นชุดของงาน กระบวนการเดียวกันทำงานกับชุดย่อยของข้อมูลที่แตกต่างกัน (พาร์ติชัน)
  • ภารกิจ: หมายถึงหน่วยของงานบนพาร์ติชันของชุดข้อมูลแบบกระจาย ดังนั้นในแต่ละสเตจจำนวนของงาน = จำนวนพาร์ติชันหรือตามที่คุณพูดว่า "หนึ่งงานต่อสเตจต่อพาร์ติชั่น"
  • ผู้บริหารแต่ละคนทำงานในที่เก็บเส้นด้ายหนึ่งตู้และแต่ละตู้บรรจุอยู่บนโหนดเดียว
  • แต่ละขั้นตอนใช้ตัวประมวลผลหลายตัวตัวประมวลผลแต่ละตัวจะถูกจัดสรรหลาย vcores
  • vcore แต่ละตัวสามารถทำงานได้ครั้งละหนึ่งงาน
  • ดังนั้นในทุกขั้นตอนสามารถทำงานหลายอย่างพร้อมกันได้ number-of-task running = number-of-vcores ที่ใช้

2
นี่คือการอ่านที่มีประโยชน์จริง ๆ เกี่ยวกับสถาปัตยกรรม Spark: 0x0fff.com/spark-architecture
pedram bashiri

ฉันไม่ได้รับหมายเลขจุดของคุณ 3 เท่าที่ฉันรู้ว่าแต่ละโหนดสามารถมีตัวเรียกใช้งานได้หลายตัวดังนั้นตามข้อ 3: ควรมีตัวประมวลผลเพียงตัวเดียวต่อโหนด คุณช่วยชี้แจงประเด็นนี้ได้หรือไม่?
Rituparno Behera

@RituparnoBehera แต่ละโหนดสามารถมีคอนเทนเนอร์ mutiple และดังนั้นจึงเป็นตัวจัดการ Spark หลายตัว ลองลิงค์นี้ docs.cloudera.com/runtime/7.0.2/running-spark-applications/…
pedram bashiri

15

ถ้าฉันเข้าใจถูกต้องมี 2 สิ่งที่เกี่ยวข้องที่ทำให้คุณสับสน:

1) สิ่งที่กำหนดเนื้อหาของงานหรือไม่

2) อะไรกำหนดจำนวนของงานที่จะดำเนินการ?

เอ็นจิ้นของ Spark "glues" เข้าด้วยกันใช้งานง่ายบน rdds ต่อเนื่องตัวอย่างเช่น:

rdd1 = sc.textFile( ... )
rdd2 = rdd1.filter( ... )
rdd3 = rdd2.map( ... )
rdd3RowCount = rdd3.count

ดังนั้นเมื่อคำนวณ rdd3 (lazily) spark จะสร้างงานต่อพาร์ติชั่นของ rdd1 และแต่ละงานจะดำเนินการทั้งตัวกรองและแผนที่ต่อบรรทัดเพื่อให้ได้ผลลัพธ์ใน rdd3

จำนวนงานถูกกำหนดโดยจำนวนพาร์ติชัน ทุก RDD มีจำนวนพาร์ติชันที่กำหนดไว้ สำหรับ RDD ต้นทางที่อ่านจาก HDFS (ตัวอย่างเช่น sc.textFile (... )) จำนวนพาร์ติชันคือจำนวนของการแบ่งที่สร้างโดยรูปแบบอินพุต การดำเนินการบางอย่างใน RDD อาจส่งผลให้ RDD มีจำนวนพาร์ติชันที่แตกต่างกัน:

rdd2 = rdd1.repartition( 1000 ) will result in rdd2 having 1000 partitions ( regardless of how many partitions rdd1 had ).

อีกตัวอย่างคือการเข้าร่วม:

rdd3 = rdd1.join( rdd2  , numPartitions = 1000 ) will result in rdd3 having 1000 partitions ( regardless of partitions number of rdd1 and rdd2 ).

(ส่วนใหญ่) การดำเนินการที่เปลี่ยนจำนวนพาร์ติชันที่เกี่ยวข้องกับการสลับเมื่อเราทำเช่น:

rdd2 = rdd1.repartition( 1000 ) 

สิ่งที่เกิดขึ้นจริงคืองานในแต่ละพาร์ติชันของ rdd1 จำเป็นต้องสร้าง end-output ที่สามารถอ่านได้ในขั้นตอนต่อไปนี้เพื่อให้ rdd2 มี 1,000 พาร์ติชัน (พวกมันทำอย่างไรHash or Sort ) บางครั้งงานในด้านนี้บางครั้งเรียกว่า "งานแผนที่ (ด้าน)" งานที่จะทำงานในภายหลังใน rdd2 จะทำหน้าที่ในหนึ่งพาร์ติชัน (ของ rdd2!) และจะต้องคิดหาวิธีการอ่าน / รวมเอาท์พุทด้านแผนที่ที่เกี่ยวข้องกับพาร์ติชันนั้น บางครั้งงานในด้านนี้บางครั้งเรียกว่า "งานลด (ด้าน)"

คำถาม 2 ข้อเกี่ยวข้องกัน: จำนวนงานในสเตจคือจำนวนพาร์ติชั่น (โดยทั่วไปสำหรับ rdds ติดต่อกัน "ติดกาว" ด้วยกัน) และจำนวนของพาร์ติชันของ rdd สามารถเปลี่ยนระหว่างสเตจได้ (โดยระบุจำนวนพาร์ติชันให้บางส่วน ตัวอย่างการสลับแบบสุ่มทำให้เกิดการทำงาน)

เมื่อการดำเนินการของสเตจเริ่มต้นภารกิจของมันสามารถครอบครองสล็อตภารกิจได้ จำนวนของ task-slot ที่เกิดขึ้นพร้อมกันคือ numExecutors * ExecutorCores โดยทั่วไปสิ่งเหล่านี้สามารถครอบครองโดยงานจากขั้นตอนที่แตกต่างกันและไม่ขึ้นอยู่กับ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.