Spark 작업이 org.apache.spark.shuffle.MetadataFetchFailedException으로 실패하는 이유 : 추측 모드에서 셔플 0의 출력 위치가 누락 되었습니까?


85

추측 모드에서 Spark 작업을 실행하고 있습니다. 약 500 개의 작업과 약 500 개의 1GB gz 파일이 압축되어 있습니다. 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
LostExecutorINFO 메시지 를 본 적이 있습니까? 웹 UI의 실행자 페이지를 확인하고 실행기가 어떻게 작동하는지 확인할 수 있습니다. GC- 와이즈?
Jacek Laskowski

답변:


50

이것은 작업자 노드에있는 것보다 더 많은 메모리를 부여했을 때 발생했습니다. 스왑이 없었기 때문에 더 이상 메모리가 남아 있지 않은 상태에서 셔플을 위해 개체를 저장하려고 시도하는 동안 Spark가 충돌했습니다.

해결 방법은 스왑을 추가하거나 작업자 / 실행기를 구성하여 메모리를 적게 사용하도록 구성하고 여러 지속성에 대해 MEMORY_AND_DISK 저장소 수준을 사용하는 것입니다.


3
노드 (메모리)에 리소스가있는 경우 Spark 실행기 메모리를 늘릴 수 있습니다. 성능에 대한 우려도 있다면 먼저 시도해 보겠습니다.
nir

14
안녕하세요 @Joren 이것은 경쟁이 아닙니다. OP 문제는 실행자가 셔플 출력을 저장할 충분한 메모리가 없다는 것입니다. 당신을 위해 일한 것은 실행기 메모리를 줄이는 것이 아니라 실행기의 메모리 제한을 제거하는 MEMORY_AND_DISK 스토리지 레벨을 사용하는 것입니다. 또한 OP는 그가 집행자에게 얼마나 많은 자원을 가지고 있는지에 대해 말하지 않습니다.
nir

나는 같은 문제가 있으며 실행기 메모리 증가, 재 파티션 양 증가, 더 많은 실제 메모리 확보와 같은 방법을 시도했습니다. 그리고 때로는 작동하지 않았지만 때로는 작동했습니다. 이것은 셔플 읽기 단계에서만 발생한다는 것을 알았고 StorageLevel을 어디에 설정할 수 있는지 묻고 싶습니다.
Lhfcws

데이터 구조를 최적화하고 수정했습니다. I는 protostuff 직렬화 된 바이트 []에 해시 MAP 변경
Lhfcws

1
spark.driver.overhead.memory 및 spark.executor.overhead.memory를 384 (기본값) 이상의 값으로 변경하면 제대로 작동합니다. 1024MB 또는 2048MB를 사용할 수 있습니다.
rahul gulati 2017-06-06

14

Spark에서도 비슷한 오류가 발생했지만 문제와 관련이 있는지 잘 모르겠습니다.

우리는 JavaPairRDD.repartitionAndSortWithinPartitions100GB 데이터를 사용 했으며 앱과 유사하게 계속 실패했습니다. 그런 다음 특정 노드의 Yarn 로그를 살펴보고 일종의 메모리 부족 문제가 있음을 발견하여 Yarn이 실행을 중단했습니다. 우리의 솔루션은 변경 / 추가이었다 spark.shuffle.memoryFraction 0에서 .../spark/conf/spark-defaults.conf. 이를 통해 훨씬 더 많은 (그러나 불행히도 무한하지 않은) 양의 데이터를 이런 방식으로 처리 할 수있었습니다.


정말 "0"입니까 아니면 입력 오류입니까? 디스크에 영구적으로 유출되도록하는 논리는 무엇입니까?
Virgil

@Virgil 예. 몇 가지 테스트를했습니다. 0에 가까울수록 처리 가능한 양이 더 커졌습니다. 가격은 시간의 20 %였습니다.
Notinlist 2015 년

흥미롭게도 spark.shuffle.memoryFraction을 0으로 줄 였지만 연속적으로 더 많은 오류가 발생했습니다. (즉 : MetadataFetchFailedException 및 FetchFailedException 간헐적으로) "all-spill"이 "partially-spill"보다 오류가 적 으면 버그 / 문제가됩니다.
tribbloid

11

3 컴퓨터 YARN 클러스터에서 동일한 문제가 발생했습니다. 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

그게 다야! 이 후 내 작업이 성공적으로 완료되었습니다.


Spark 문서에서는 다음과 같이 말합니다 spark.executor.heartbeatInterval should be significantly less than spark.network.timeout.. 따라서 둘 다 동일한 값으로 설정하는 것이 최선의 방법이 아닐 수 있습니다.
Bitswazsky

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

executorMemory 및 driverMemory에서 할당 된 메모리를 늘리는이 오류를 해결했습니다. HUE에서 문제를 일으키는 Spark 프로그램을 선택하고 속성-> 옵션 목록에서 다음과 같이 추가 할 수 있습니다.

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

물론 매개 변수의 값은 클러스터의 크기와 필요에 따라 달라집니다.


1

Spark 웹 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 슬레이브의 파일 시스템이 100 % 채워져 예외가 발생했습니다. spark/work슬레이브 폴더의 모든 항목을 삭제 하면 문제가 해결되었습니다.


0

같은 문제가 생겼지 만 문제를 해결할 수없는 답을 많이 찾았습니다. 결국 코드를 ​​단계별로 디버깅합니다. 나는 데이터 크기에 의해 발생하는 문제가 납이 함유 된 각 파티션에 대한 균형되지 찾을 수 MetadataFetchFailedException에 해당 map하지 단계 reduce단계. 그냥 df_rdd.repartition(nums)하기 전에reduceByKey()

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.