เหตุใดงาน Spark จึงล้มเหลวด้วย org.apache.spark.shuffle.MetadataFetchFailedException: ไม่มีตำแหน่งเอาต์พุตสำหรับสับเปลี่ยน 0 ในโหมดเก็งกำไร


88

ฉันทำงาน Spark ด้วยโหมดเก็งกำไร ฉันมีงานประมาณ 500 งานและบีบอัดไฟล์ขนาด 1 GB gz ประมาณ 500 ไฟล์ ฉันทำงานแต่ละงานไปเรื่อย ๆ 1-2 งานข้อผิดพลาดที่แนบมาซึ่งจะเรียกใช้ซ้ำหลังจากนั้นหลายสิบครั้ง

org.apache.spark.shuffle.MetadataFetchFailedException: ไม่มีตำแหน่งเอาต์พุตสำหรับการสุ่ม 0

ความคิดใดคือความหมายของปัญหาและจะเอาชนะมันได้อย่างไร?

org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 0
    at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$1.apply(MapOutputTracker.scala:384)
    at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$1.apply(MapOutputTracker.scala:381)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:108)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:108)
    at org.apache.spark.MapOutputTracker$.org$apache$spark$MapOutputTracker$$convertMapStatuses(MapOutputTracker.scala:380)
    at org.apache.spark.MapOutputTracker.getServerStatuses(MapOutputTracker.scala:176)
    at org.apache.spark.shuffle.hash.BlockStoreShuffleFetcher$.fetch(BlockStoreShuffleFetcher.scala:42)
    at org.apache.spark.shuffle.hash.HashShuffleReader.read(HashShuffleReader.scala:40)
    at org.apache.spark.rdd.ShuffledRDD.compute(ShuffledRDD.scala:92)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.MappedRDD.compute(MappedRDD.scala:31)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.FlatMappedRDD.compute(FlatMappedRDD.scala:33)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.MappedRDD.compute(MappedRDD.scala:31)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.rdd.MappedRDD.compute(MappedRDD.scala:31)
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:263)
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:230)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:61)
    at org.apache.spark.scheduler.Task.run(Task.scala:56)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:196)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)

1
คุณเคยเห็นLostExecutorข้อความ INFO หรือไม่? คุณสามารถตรวจสอบหน้าผู้ดำเนินการ UI ของเว็บและดูว่าตัวดำเนินการทำงานอย่างไรโดยเฉพาะ GC ฉลาด?
Jacek Laskowski

คำตอบ:


52

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

วิธีแก้ปัญหาคือการเพิ่ม swap หรือกำหนดค่าผู้ปฏิบัติงาน / ผู้ปฏิบัติการให้ใช้หน่วยความจำน้อยลงนอกเหนือจากการใช้ระดับการจัดเก็บ MEMORY_AND_DISK สำหรับหลาย ๆ ครั้ง


3
หากคุณมีทรัพยากรบนโหนด (หน่วยความจำ) คุณสามารถลองเพิ่มหน่วยความจำตัวดำเนินการจุดประกาย ฉันจะลองก่อนหากคุณกังวลเกี่ยวกับประสิทธิภาพ
nir

15
สวัสดี @Joren นี่ไม่ใช่การแข่งขัน ปัญหา OP คือตัวดำเนินการไม่มีหน่วยความจำเพียงพอที่จะจัดเก็บเอาต์พุตแบบสุ่ม สิ่งที่ได้ผลสำหรับคุณไม่ได้ลดลงหน่วยความจำของตัวดำเนินการ แต่ใช้ระดับการจัดเก็บ MEMORY_AND_DISK ซึ่งช่วยขจัดข้อ จำกัด ด้านหน่วยความจำของตัวดำเนินการ OP ยังไม่ได้บอกว่าเขามีทรัพยากรเท่าไหร่สำหรับผู้ดำเนินการ
nir

ฉันมีปัญหาเดียวกันและฉันได้ลองใช้วิธีต่างๆเช่นการเพิ่มหน่วยความจำของตัวดำเนินการเพิ่มจำนวนพาร์ติชันใหม่เพิ่มหน่วยความจำกายภาพให้มากขึ้น และบางครั้งก็ใช้งานได้ในขณะที่บางครั้งก็ไม่ได้ผล ฉันพบว่าสิ่งนี้เกิดขึ้นในเฟสการอ่านแบบสุ่มเท่านั้นและฉันต้องการถามว่าฉันจะตั้งค่า StorageLevel ได้ที่ไหน?
Lhfcws

ฉันปรับโครงสร้างข้อมูลของฉันให้เหมาะสมและแก้ไขแล้ว ฉันเพิ่งเปลี่ยน HashMap เป็นไบต์ [] ซึ่งต่อเนื่องกันโดย protostuff
Lhfcws

1
ลองเปลี่ยน spark.driver.overhead.memory และ spark.executor.overhead.memory เป็นค่าที่มากกว่า 384 (ค่าเริ่มต้น) และควรใช้งานได้ คุณสามารถใช้ 1024 MB หรือ 2048 MB
rahul gulati

15

เราพบข้อผิดพลาดที่คล้ายกันกับ Spark แต่ฉันไม่แน่ใจว่าเกี่ยวข้องกับปัญหาของคุณ

เราใช้ JavaPairRDD.repartitionAndSortWithinPartitionsข้อมูล 100GB และยังคงล้มเหลวในลักษณะเดียวกับแอปของคุณ จากนั้นเราดูบันทึก Yarn บนโหนดเฉพาะและพบว่าเรามีปัญหาหน่วยความจำไม่เพียงพอดังนั้น Yarn จึงขัดจังหวะการทำงาน วิธีการแก้ปัญหาของเราคือการเปลี่ยน / เพิ่มในspark.shuffle.memoryFraction 0 .../spark/conf/spark-defaults.confนั่นทำให้เราสามารถจัดการกับข้อมูลจำนวนมาก (แต่น่าเสียดายที่ไม่สิ้นสุด) ด้วยวิธีนี้


มันเป็น "0" จริงๆหรือว่าเป็นข้อผิดพลาดในการพิมพ์ อะไรคือตรรกะที่อยู่เบื้องหลังการบังคับให้มันหกลงดิสก์อย่างถาวร
Virgil

@Virgil ใช่ เราทำการทดสอบบางอย่าง ยิ่งเราเข้าใกล้ศูนย์มากเท่าไหร่จำนวนเงินที่ประมวลผลได้ก็ยิ่งมากขึ้นเท่านั้น ราคาคือ 20% ของเวลา
Notinlist

ที่น่าสนใจฉันยังลด spark.shuffle.memoryFraction เป็นศูนย์ แต่มีข้อผิดพลาดมากขึ้นติดต่อกัน (ได้แก่ : MetadataFetchFailedException และ FetchFailedException intermittenly) ควรกลายเป็นบั๊ก / ปัญหาหาก "all-spill" มีข้อผิดพลาดน้อยกว่า "partially-spill"
tribbloid

11

ฉันพบปัญหาเดียวกันในคลัสเตอร์ YARN เครื่อง 3 เครื่องของฉัน ฉันเปลี่ยน RAM ไปเรื่อย ๆ แต่ปัญหายังคงอยู่ ในที่สุดฉันก็เห็นข้อความต่อไปนี้ในบันทึก:

17/02/20 13:11:02 WARN spark.HeartbeatReceiver: Removing executor 2 with no recent heartbeats: 1006275 ms exceeds timeout 1000000 ms
17/02/20 13:11:02 ERROR cluster.YarnScheduler: Lost executor 2 on 1worker.com: Executor heartbeat timed out after 1006275 ms

และหลังจากนั้นก็มีข้อความนี้:

org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 67

ฉันแก้ไขคุณสมบัติใน spark-defaults.conf ดังนี้:

spark.yarn.scheduler.heartbeat.interval-ms 7200000
spark.executor.heartbeatInterval 7200000
spark.network.timeout 7200000

แค่นั้นแหละ! งานของฉันเสร็จสมบูรณ์หลังจากนี้


1
ในเอกสารจุดประกายกล่าวว่า: spark.executor.heartbeatInterval should be significantly less than spark.network.timeout. ดังนั้นการตั้งค่าทั้งสองให้เป็นค่าเดียวกันอาจไม่ใช่ความคิดที่ดีที่สุด
Bitswazsky

2

ฉันแก้ไขข้อผิดพลาดนี้ในการเพิ่มหน่วยความจำที่จัดสรรใน executorMemory และ driverMemory คุณสามารถทำได้ใน HUE เลือกโปรแกรม Spark ซึ่งเป็นสาเหตุของปัญหาและในคุณสมบัติ -> รายการตัวเลือกคุณสามารถเพิ่มสิ่งนี้:

--driver-memory 10G --executor-memory 10G --num-executors 50 --executor-cores 2

แน่นอนว่าค่าของพารามิเตอร์จะแตกต่างกันไปขึ้นอยู่กับขนาดของคลัสเตอร์และความต้องการของคุณ


2

สำหรับฉันฉันกำลังทำหน้าต่างข้อมูลขนาดใหญ่ (ประมาณ 50B แถว) และรับน้ำหนักเรือ

ExternalAppendOnlyUnsafeRowArray:54 - ถึงเกณฑ์การรั่วไหลที่ 4096 แถวโดยเปลี่ยนเป็น org.apache.spark.util.collection.unsafe.sort.UnsafeExternalSorter

ในบันทึกของฉัน เห็นได้ชัดว่า 4096 อาจมีขนาดเล็กสำหรับข้อมูลดังกล่าว ... สิ่งนี้ทำให้ฉันไปสู่ ​​JIRA ต่อไปนี้:

https://issues.apache.org/jira/browse/SPARK-21595

และท้ายที่สุดสำหรับสองตัวเลือกการกำหนดค่าต่อไปนี้:

  • spark.sql.windowExec.buffer.spill.threshold
  • spark.sql.windowExec.buffer.in.memory.threshold

ทั้งค่าเริ่มต้นเป็น 4096; ฉันยกระดับพวกเขาให้สูงขึ้นมาก (2097152) และตอนนี้ดูเหมือนจะดีขึ้น ฉันไม่แน่ใจ 100% ว่าเป็นเช่นเดียวกับปัญหาที่ยกมาที่นี่ แต่เป็นอีกสิ่งที่ควรลอง


1

ใน Spark Web UI หากมีข้อมูลเช่น Executors lostคุณต้องตรวจสอบบันทึกเส้นด้ายตรวจสอบให้แน่ใจว่าคอนเทนเนอร์ของคุณถูกฆ่าหรือไม่

ถ้าตู้คอนเทนเนอร์ถูกฆ่าอาจเป็นเพราะหน่วยความจำไม่เพียงพอ

จะค้นหาข้อมูลสำคัญในบันทึกเส้นด้ายได้อย่างไร ตัวอย่างเช่นอาจมีคำเตือนดังนี้:

Container killed by YARN for exceeding memory limits. 2.5 GB of 2.5 GB physical memory used. 
Consider boosting spark.yarn.executor.memoryOverhead.

spark.yarn.executor.memoryOverheadในกรณีนี้มันแสดงให้เห็นว่าคุณควรจะเพิ่มขึ้น


0

ในกรณีของฉัน (คลัสเตอร์แบบสแตนด์อโลน) ข้อยกเว้นถูกทิ้งเนื่องจากระบบไฟล์ของ Spark Slave บางตัวเต็ม 100% การลบทุกอย่างในspark/workโฟลเดอร์ของทาสช่วยแก้ปัญหาได้


0

ฉันพบปัญหาเดียวกัน แต่ฉันค้นหาคำตอบมากมายที่ไม่สามารถแก้ปัญหาของฉันได้ ในที่สุดฉันก็แก้จุดบกพร่องรหัสของฉันทีละขั้นตอน ฉันพบปัญหาที่เกิดจากขนาดข้อมูลไม่สมดุลสำหรับแต่ละพาร์ติชันนำไปสู่MetadataFetchFailedExceptionสิ่งนั้นในmapระยะไม่ใช่สreduceเตจ เพิ่งทำdf_rdd.repartition(nums)ก่อนreduceByKey()

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