Apache Spark: จำนวนคอร์เทียบกับจำนวนของผู้ปฏิบัติการ


194

ฉันพยายามที่จะเข้าใจความสัมพันธ์ของจำนวนคอร์และจำนวนผู้บริหารเมื่อทำการรันงาน Spark บน YARN

สภาพแวดล้อมการทดสอบมีดังนี้:

  • จำนวนโหนดข้อมูล: 3
  • ข้อมูลจำเพาะของเครื่องโหนดข้อมูล:
    • CPU: Core i7-4790 (จำนวนแกน: 4, จำนวนเธรด: 8)
    • RAM: 32GB (8GB x 4)
    • HDD: 8TB (2TB x 4)
  • เครือข่าย: 1Gb

  • รุ่น Spark: 1.0.0

  • รุ่น Hadoop: 2.4.0 (Hortonworks HDP 2.1)

  • Spark job flow: sc.textFile -> filter -> map -> filter -> mapToPair -> ลดByKey -> map -> saveAsTextFile

  • ป้อนข้อมูล

    • ประเภท: ไฟล์ข้อความเดียว
    • ขนาด: 165GB
    • จำนวนบรรทัด: 454,568,833
  • เอาท์พุต

    • จำนวนบรรทัดหลังจากตัวกรองที่สอง: 310,640,717
    • จำนวนบรรทัดของไฟล์ผลลัพธ์: 99,848,268
    • ขนาดของไฟล์ผลลัพธ์: 41GB

งานถูกรันด้วยคอนฟิกูเรชันต่อไปนี้:

  1. --master yarn-client --executor-memory 19G --executor-cores 7 --num-executors 3 (ตัวเรียกใช้งานต่อโหนดข้อมูลใช้มากที่สุดเท่าที่แกน)

  2. --master yarn-client --executor-memory 19G --executor-cores 4 --num-executors 3 (จำนวนแกนลดลง)

  3. --master yarn-client --executor-memory 4G --executor-cores 2 --num-executors 12 (คอร์น้อยกว่าตัวจัดการเพิ่มเติม)

เวลาที่ผ่านไป:

  1. 50 นาที 15 วินาที

  2. 55 นาที 48 วินาที

  3. 31 นาที 23 วินาที

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

(มีการเพิ่มสิ่งต่อไปนี้หลังจากคำตอบของ pwilmot)

สำหรับข้อมูลการจับภาพหน้าจอมอนิเตอร์ประสิทธิภาพมีดังนี้:

  • สรุปโหนดข้อมูล Ganglia สำหรับ (1) - งานเริ่มต้นที่ 04:37

สรุปโหนดข้อมูล Ganglia สำหรับ (1)

  • สรุปโหนดข้อมูล Ganglia สำหรับ (3) - งานเริ่มต้นที่ 19:47 โปรดละเว้นกราฟก่อนหน้านั้น

สรุปโหนดข้อมูล Ganglia สำหรับ (3)

กราฟแบ่งออกเป็น 2 ส่วนโดยประมาณ:

  • ก่อน: ตั้งแต่เริ่มต้นจนถึงลด ByYey: CPU เข้มข้นไม่มีกิจกรรมเครือข่าย
  • ที่สอง: หลังจากลดโดย ByKey: CPU ลดลง I / O เครือข่ายจะทำ

ดังที่กราฟแสดงให้เห็นว่า (1) สามารถใช้พลังงาน CPU ได้มากเท่าที่ได้รับ ดังนั้นอาจไม่ใช่ปัญหาของจำนวนเธรด

จะอธิบายผลลัพธ์นี้อย่างไร?


2
ตอนนี้ฉันสงสัยว่า GC ... ที่จริงแล้วบน Spark UI เวลาทั้งหมดที่ใช้สำหรับ GC นั้นยาวกว่าใน 1) มากกว่า 2)
zeodtr

ทำไมคุณไม่ลอง 3) กับ 19G? เป็นไปได้ไหมว่าการ จำกัด พนักงานใน 4G จะลดผลกระทบ NUMA ที่ ppl บางจุดมี นั่นคือ 4G ของคุณตั้งอยู่บนหนึ่งใน 2 คอร์ที่จัดสรรให้กับเวิร์กโฟลว์ของคุณและทำให้มีการชะลอตัวของ i / o น้อยลงทำให้ประสิทธิภาพโดยรวมดีขึ้น มิฉะนั้นฉันคิดว่าคำถามหลักคือ: กี่แกน / เธรดสามารถใช้ผู้บริหารหนึ่งคนเดียวในคนงาน? (หนึ่งสามารถระบุจำนวนแกนรวมสำหรับผู้ปฏิบัติงานไม่ได้อยู่ที่ความละเอียดของผู้ปฏิบัติการ)
เบคอน

5
Btw ฉันเพิ่งตรวจสอบรหัสที่ core / src / main / scala / org / apache / spark / deploy / workers / ExecutorRunner.scala และดูเหมือนว่า 1 ผู้ปฏิบัติการ = 1 เธรดของผู้ปฏิบัติงาน
เบคอน

ช้าไปหน่อย แต่นี่คือโพสต์บน cloudera ในหัวข้อนี้: blog.cloudera.com/blog/2015/03/…
Orelus

1
โดยวิธีการที่ฉันพบข้อมูลนี้ใน cloudera สไลด์ดาดฟ้าslideshare.net/cloudera/ …ที่อธิบายเล็กน้อยเกี่ยวกับการตัดสินใจในผู้บริหารแกนและหน่วยความจำ
Manish Sahni

คำตอบ:


58

เพื่อหวังว่าจะทำให้ทุกคอนกรีตเล็ก ๆ ขึ้นที่นี่เป็นตัวอย่างที่ทำงานของการกำหนดค่าแอป Spark กับการใช้งานมากที่สุดเท่าของกลุ่มที่เป็นไปได้: Imagine คลัสเตอร์กับหกโหนดทำงาน NodeManagers แต่ละห้องมี16 แกนและ 64GB หน่วยความจำ ความจุ NodeManager, yarn.nodemanager.resource.memory-mb และ yarn.nodemanager.resource.cpu-vcores น่าจะถูกตั้งค่าเป็น 63 * 1024 = 64512 (เมกะไบต์) และ 15 ตามลำดับ เราหลีกเลี่ยงการจัดสรรทรัพยากร 100% ให้กับคอนเทนเนอร์ YARN เนื่องจากโหนดต้องการทรัพยากรบางอย่างเพื่อเรียกใช้ระบบปฏิบัติการและ Hadoop daemons ในกรณีนี้เราจะทิ้งกิกะไบต์และแกนหลักสำหรับกระบวนการของระบบเหล่านี้ Cloudera Manager ช่วยด้วยการบัญชีสำหรับสิ่งเหล่านี้และกำหนดค่าคุณสมบัติ YARN เหล่านี้โดยอัตโนมัติ

มีแนวโน้มที่แรกแรงกระตุ้นที่จะใช้--num-รัฟ 6 --executor แกน 15 --executor หน่วยความจำตัวเครื่อง 63 กรัม อย่างไรก็ตามนี่เป็นวิธีการที่ผิดเพราะ:

63GB + ค่าใช้จ่ายหน่วยความจำของตัวเรียกทำงานจะไม่พอดีกับความจุ 63GB ของ NodeManagers แอ็พพลิเคชันหลักจะใช้แกนบนโหนดใดโหนดหนึ่งซึ่งหมายความว่าจะไม่มีที่ว่างสำหรับตัวประมวลผล 15-core บนโหนดนั้น 15 คอร์ต่อผู้ปฏิบัติการสามารถนำไปสู่ทรูพุตของ HDFS I / O ที่ไม่ดี

ตัวเลือกที่ดีที่จะใช้--num-รัฟ 17 --executor แกน 5 --executor หน่วยความจำ 19G ทำไม?

การกำหนดค่านี้ส่งผลให้มีตัวเรียกใช้งานสามตัวบนโหนดทั้งหมดยกเว้นโหนดที่มี AM ซึ่งจะมีตัวจัดการสองตัว - ตัวประมวลผลหน่วยความจำได้รับมาเป็น (63/3 ตัวประมวลผลต่อโหนด) = 21 21 * 0.07 = 1.47 21 - 1.47 ~ 19

คำอธิบายที่ได้รับในบทความในบล็อก Cloudera ของวิธีการ: การปรับแต่ง Apache Spark ของคุณงาน (Part 2)


1
msgstr "การกำหนดค่านี้ส่งผลให้ตัวจัดการสามตัวบนโหนดทั้งหมดยกเว้นตัวที่มี AM ซึ่งจะมีตัวจัดการสองตัว". สิ่งนี้หมายความว่าอะไรเกี่ยวกับ "--executor-cores 5"?
ดีเร็ก

มันหมายถึงผู้บริหารแต่ละคนใช้ 5 คอร์ แต่ละโหนดมีตัวเรียกใช้งาน 3 ตัวซึ่งใช้ 15 คอร์ยกเว้นหนึ่งในโหนดจะทำงานกับแอ็พพลิเคชันหลักสำหรับงานดังนั้นสามารถโฮสต์ตัวจัดการ 2 ตัวเท่านั้นเช่น 10 คอร์ที่ใช้เป็นตัวจัดการ
Davos

อธิบายอย่างดี - โปรดทราบว่าสิ่งนี้ใช้ได้กับการyarn.scheduler.capacity.resource-calculatorปิดการใช้งานซึ่งเป็นค่าเริ่มต้น นี่เป็นเพราะโดยปกติแล้วมันจะกำหนดเวลาตามหน่วยความจำไม่ใช่โดยซีพียู
YoYo

1
ตัวเรียกใช้งานเพิ่มเติมสามารถนำไปสู่ทรูพุตของ HDFS I / O ที่ไม่ดี ดังนั้นถ้าฉันไม่ได้ใช้ HDFS เลยในกรณีนั้นฉันสามารถใช้มากกว่า 5 คอร์ต่อผู้ปฏิบัติการได้ไหม
Darshan

ฉันว่า Application master รันบนแต่ละโหนด ตามข้างต้นซึ่งหมายความว่าจะมีเพียง 1 แอปพลิเคชันหลักในการเรียกใช้งาน ถูกต้องไหม
Roshan Fernando

15

ในขณะที่คุณใช้งานแอพ spark ของคุณบน HDFS ตามSandy Ryza

ฉันสังเกตเห็นว่าไคลเอนต์ HDFS มีปัญหากับเธรดที่เกิดขึ้นพร้อมกันมากมาย การเดาคร่าวๆคืองานมากที่สุดห้างานต่อหนึ่งผู้ปฏิบัติการสามารถบรรลุผลงานการเขียนที่สมบูรณ์ดังนั้นจึงเป็นเรื่องดีที่จะรักษาจำนวนแกนประมวลผลต่อผู้ปฏิบัติการไว้ต่ำกว่าจำนวนนั้น

ดังนั้นฉันเชื่อว่าการกำหนดค่าแรกของคุณช้ากว่าที่สามเนื่องจาก HDFS I / O ทรูพุตที่ไม่ดี


11

ฉันไม่ได้เล่นกับการตั้งค่าเหล่านี้ด้วยตัวเองนี่เป็นเพียงการเก็งกำไร แต่ถ้าเราคิดว่าปัญหานี้เป็นคอร์และเธรดปกติในระบบกระจายแล้วในคลัสเตอร์ของคุณคุณสามารถใช้คอร์ได้ถึง 12 คอร์ (4 * 3 เครื่อง) และ 24 เธรด (8 * 3 เครื่อง) ในสองตัวอย่างแรกของคุณคุณจะให้จำนวนแกนที่เป็นธรรม (พื้นที่การคำนวณที่มีศักยภาพ) แต่จำนวนเธรด (งาน) ที่จะทำงานบนแกนเหล่านั้นมี จำกัด ดังนั้นคุณจึงไม่สามารถใช้กำลังการประมวลผลส่วนใหญ่ได้ และทำให้งานช้าลงแม้ว่าจะมีทรัพยากรการคำนวณมากขึ้น

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


ขอบคุณสำหรับคำตอบของคุณ แต่ฉันสงสัยว่าจำนวนเธรดไม่ใช่ปัญหาหลัก ฉันได้เพิ่มการดักจับหน้าจอการมอนิเตอร์ ดังที่กราฟแสดงให้เห็นว่า 1) สามารถใช้พลังงาน CPU ได้มากเท่าที่ได้รับ
zeodtr

1
@zeodtr pwilmot ถูกต้อง - คุณต้องใช้ 2-4 งานขั้นต่ำเพื่อใช้ประโยชน์เต็มศักยภาพของแกนของคุณ ใส่นี่เป็น - ฉันมักจะใช้อย่างน้อย 1,000 พาร์ทิชันสำหรับ 80 กลุ่มหลักของฉัน
samthebest

@samthebest สิ่งที่ฉันอยากรู้คือเหตุผลของความแตกต่างของประสิทธิภาพระหว่าง 1) และ 3) เมื่อฉันดู Spark UI ทั้งคู่ทำงาน 21 งานแบบขนานในส่วนที่ 2 (เพราะเหตุใด 21 แทนที่จะเป็น 24 ในกรณีที่ 3) ไม่เป็นที่รู้จักในตอนนี้) แต่งานสำหรับ 3) เพิ่งจะทำงานได้เร็วขึ้น
zeodtr

10

คำตอบสั้น ๆ : ฉันคิดว่าtgbaggioถูกต้อง คุณเข้าถึง HDFS ขีด จำกัด ปริมาณงานของผู้ปฏิบัติการของคุณ

ฉันคิดว่าคำตอบที่นี่อาจจะง่ายกว่าคำแนะนำที่นี่เล็กน้อย

เงื่อนงำสำหรับฉันอยู่ในกราฟเครือข่ายคลัสเตอร์ สำหรับการรัน 1 การใช้งานจะอยู่ที่ ~ 50 M ไบต์ต่อวินาที สำหรับการรัน 3 การใช้งานที่มั่นคงเป็นสองเท่าประมาณ 100 M ไบต์ / s

จากโพสต์บล็อกของ cloudera ที่แบ่งปันโดยDzOrdคุณจะเห็นข้อความที่สำคัญนี้:

ฉันสังเกตเห็นว่าไคลเอนต์ HDFS มีปัญหากับเธรดที่เกิดขึ้นพร้อมกันมากมาย การเดาคร่าวๆคืองานมากที่สุดห้างานต่อหนึ่งผู้ปฏิบัติการสามารถบรรลุผลงานการเขียนที่สมบูรณ์ดังนั้นจึงเป็นเรื่องดีที่จะรักษาจำนวนแกนประมวลผลต่อผู้ปฏิบัติการไว้ต่ำกว่าจำนวนนั้น

ดังนั้นลองคำนวณสองสามครั้งดูว่าเราคาดหวังว่าประสิทธิภาพเป็นอย่างไร


เรียกใช้ 1: 19 GB, 7 แกน, 3 ผู้ดำเนินการ

  • 3 ตัวจัดการ x 7 เธรด = 21 เธรด
  • ด้วย 7 คอร์ต่อผู้ปฏิบัติการเราคาดว่าจะ จำกัด IO ถึง HDFS (สูงสุดที่ ~ 5 คอร์)
  • ปริมาณงานที่มีประสิทธิภาพ ~ = 3 ตัวดำเนินการ x 5 เธรด = 15 เธรด

เรียกใช้ 3: 4 GB, 2 คอร์, ตัวจัดการ 12 ตัว

  • 2 ตัวจัดการ x 12 เธรด = 24 เธรด
  • 2 คอร์ต่อผู้ดำเนินการดังนั้นอัตราการรับส่งข้อมูล HD ก็โอเค
  • ปริมาณงานที่มีประสิทธิภาพ ~ = 12 ตัวดำเนินการ x 2 เธรด = 24 เธรด

หากงานถูก จำกัด 100% โดยการทำงานพร้อมกัน (จำนวนเธรด) เราคาดหวังว่า runtime จะมีความสัมพันธ์แบบผกผันอย่างสมบูรณ์กับจำนวนเธรด

ratio_num_threads = nthread_job1 / nthread_job3 = 15/24 = 0.625
inv_ratio_runtime = 1/(duration_job1 / duration_job3) = 1/(50/31) = 31/50 = 0.62

ดังนั้นratio_num_threads ~= inv_ratio_runtimeและดูเหมือนว่าเรามีเครือข่ายที่ จำกัด

เอฟเฟกต์เดียวกันนี้อธิบายความแตกต่างระหว่าง Run 1 และ Run 2


เรียกใช้ 2: 19 GB, 4 แกน, 3 ผู้ดำเนินการ

  • 3 ตัวจัดการ x 4 เธรด = 12 เธรด
  • ด้วย 4 คอร์ต่อผู้ปฏิบัติการโอเค IO ถึง HDFS
  • ปริมาณงานที่มีประสิทธิภาพ ~ = 3 ตัวดำเนินการ x 4 เธรด = 12 เธรด

การเปรียบเทียบจำนวนเธรดที่มีประสิทธิภาพและรันไทม์:

ratio_num_threads = nthread_job2 / nthread_job1 = 12/15 = 0.8
inv_ratio_runtime = 1/(duration_job2 / duration_job1) = 1/(55/50) = 50/55 = 0.91

มันไม่ได้สมบูรณ์แบบเท่ากับการเปรียบเทียบครั้งล่าสุด แต่เรายังคงเห็นการลดลงที่คล้ายกันเมื่อเราเสียเธรด

ทีนี้สำหรับบิตสุดท้าย: ทำไมเป็นกรณีที่เราได้ประสิทธิภาพที่ดีขึ้นด้วยเธรดที่มากขึ้นโดยเฉพาะ มีเธรดมากกว่าจำนวน CPU หรือไม่

คำอธิบายที่ดีของความแตกต่างระหว่างความเท่าเทียม (สิ่งที่เราได้รับโดยการหารข้อมูลบนซีพียูหลาย) และเห็นพ้องด้วย (สิ่งที่เราได้รับเมื่อเราใช้หลายหัวข้อที่จะทำงานบน CPU เดียว) เป็นผู้ให้บริการในโพสต์ที่ยิ่งใหญ่นี้โดย Rob หอก: Concurrency ไม่เท่าเทียม

คำอธิบายสั้น ๆ คือถ้างาน Spark กำลังโต้ตอบกับระบบไฟล์หรือเครือข่าย CPU จะใช้เวลานานในการรอการติดต่อสื่อสารกับอินเตอร์เฟสเหล่านั้นและไม่ได้ใช้เวลามากในการ "ทำงาน" จริง ๆ ด้วยการให้ซีพียูเหล่านั้นทำงานมากกว่า 1 ครั้งพวกเขาใช้เวลาในการรอน้อยลงและใช้เวลามากขึ้นและคุณจะเห็นประสิทธิภาพที่ดีขึ้น


1
คำอธิบายที่น่าสนใจและน่าเชื่อถือฉันสงสัยว่าคุณเดาได้อย่างไรว่าผู้ดำเนินการมี5งานที่ จำกัด เพื่อให้ได้ปริมาณงานสูงสุด
Dat Nguyen

ดังนั้นหมายเลข 5 จึงไม่ใช่สิ่งที่ฉันคิดขึ้น: ฉันเพิ่งสังเกตเห็นสัญญาณของคอขวด IO และออกไปเพื่อค้นหาว่าคอขวดเหล่านั้นมาจากไหน
turtlemonvh

8

จากทรัพยากรที่ยอดเยี่ยมที่มีอยู่ในหน้าแพคเกจ Sparklyr ของ RStudio :

คำจำกัดความประกายไฟ :

มันอาจจะมีประโยชน์ในการให้คำจำกัดความง่ายๆสำหรับการตั้งชื่อ Spark:

โหนด : เซิร์ฟเวอร์

Worker Node : เซิร์ฟเวอร์ที่เป็นส่วนหนึ่งของคลัสเตอร์และพร้อมใช้งานเพื่อเรียกใช้งาน Spark

Master Node : เซิร์ฟเวอร์ที่ประสานงานโหนดผู้ปฏิบัติงาน

ผู้บริหาร : ประเภทของเครื่องเสมือนภายในโหนด One Node สามารถมี Executors หลายคน

โหนดไดรเวอร์ : โหนดที่เริ่มเซสชัน Spark โดยทั่วไปจะเป็นเซิร์ฟเวอร์ที่ตั้ง sparklyr

ไดร์เวอร์ (ผู้บริหาร) : โหนดไดรเวอร์จะปรากฏขึ้นในรายการผู้บริหาร


1

การจัดสรร Spark Dynamic ให้ความยืดหยุ่นและจัดสรรทรัพยากรแบบไดนามิก ในจำนวน min และ max executors นี้สามารถกำหนดได้ นอกจากนี้ยังสามารถกำหนดจำนวนตัวเรียกใช้งานที่เริ่มต้นแอปพลิเคชันได้

อ่านด้านล่างเดียวกัน:

http://spark.apache.org/docs/latest/configuration.html#dynamic-allocation


1

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

แต่อย่าให้มากกว่า 5 คอร์ต่อผู้ดำเนินการจะมีคอขวดที่ประสิทธิภาพของ i / o

ดังนั้นเครื่องที่ดีที่สุดในการทำเครื่องหมายนี้อาจเป็นโหนดข้อมูลที่มี 10 คอร์

ข้อมูลจำเพาะของเครื่องดาต้าโหนด: CPU: Core i7-4790 (จำนวนแกน: 10, จำนวนเธรด: 20) RAM: 32GB (8GB x 4) HDD: 8TB (2TB x 4)


0

ฉันคิดว่าหนึ่งในเหตุผลสำคัญคือท้องถิ่น ขนาดไฟล์อินพุตของคุณคือ 165G บล็อกที่เกี่ยวข้องของไฟล์จะถูกกระจายไปยัง DataNode หลาย ๆ ตัวอย่างแน่นอนผู้ปฏิบัติการจำนวนมากสามารถหลีกเลี่ยงการคัดลอกเครือข่ายได้

พยายามตั้งค่าจำนวนบล็อกเท่ากันของ executor ผมคิดว่าสามารถเร็วขึ้นได้

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