改版通知

巨人肩膀网站已全新改版。若您仍依赖旧站功能或数据,欢迎联系我们,我们会协助处理。联系我们

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

忆往昔2024年5月20日0 回答216 浏览

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

原因:

shuffle分为shuffle write和shuffle read两部分。shuffle write的分区数由上一阶段的RDD分区数控制,shuffle read的分区数则是由Spark提供的一些参数控制。shuffle write可以简单理解为类似于saveAsLocalDiskFile的操作,将计算的中间结果按某种规则临时放到各个executor所在的本地磁盘上。shuffle read的时候数据的分区数则是由spark提供的一些参数控制。可以想到的是,如果这个参数值设置的很小,同时shuffle read的量很大,那么将会导致一个task需要处理的数据非常大。结果导致JVM crash,从而导致取shuffle数据失败,同时executor也丢失了,看到Failed to connect to host的错误,也就是executor lost的意思。有时候即使不会导致JVM crash也会造成长时间的gc。


解决方案:

  • 减少shuffle数据。思考是否可以使用map side join或是broadcast join来规避shuffle的产生。将不必要的数据在shuffle前进行过滤,比如原始数据有20个字段,只要选取需要的字段进行处理即可,将会减少一定的shuffle数据。
  • SparkSQL和DataFrame的join,group by等操作。通过spark.sql.shuffle.partitions控制分区数,默认为200,根据shuffle的量以及计算的复杂度提高这个值。
  • Rdd的join,groupBy,reduceByKey等操作。通过spark.shuffle.io.maxRetries控制重试次数,默认是3,可适当增加,例如10。通过spark.shuffle.io.retryWait控制重试的时间间隔,默认是5s,可适当增加,例如10s。
  • 提高executor的内存
  • 是否存在数据倾斜的问题