md2

117 阅读3分钟

HDFS based shuffle主要是解决FetchFailedException导致stage重试或者作业失败的问题。解决方案为将mapper存储到本地shuffle数据多存储一份到HDFS上,当reducer获取不到shuffle数据时,会从HDFS上获取对应数据,避免了fetchfailed的问题。 开启的方式是

set spark.shuffle.hdfs.enabled=true;

如何判断作业是hdfs shuffle file not found

如下图所示:

  1. 报错的exception是 FetchFailedException: File does not exists
  2. 文件名的后缀是.indexeddata

图片

问题可能的原因以及对应的解决方案

文件被后台清理程序清理掉了

  • 说明

由于线上开启hdfs shuffle的作业平均每天会写入超过100PB(2副本就是200PB+)的数据到hdfs,虽然spark作业在执行结束的时候会自动清理其写入hdfs的数据,但是存在大量作业异常退出,导致数据无法即使删除,此外,对于常驻Spark作业,如果不及时清理,会积累数量庞大的hdfs shuffle数据,所以Spark团队维护了一个定时清理hdfs shuffle数据的任务:

  1. 清理非运行作业的hdfs shuffle数据
  2. 清理运行作业,但是已经写入超过24h的hdfs shuffle数据
  • 如何判断

如果你的作业已经运行超过了24h,就有可能遇到这种情况。 如下图,该stage已经运行了100h,其上游shuffle数据很有可能已经被清理程序清理掉了 图片

  • 处理方式

这种情况,基本都是作业得不到足够的资源导致运行时间异常,需要用户检查提交的队列的使用资源情况,如果队列资源不足,可以换一个有资源的队列。

发生了stage重试

  • 说明

如果spark 某个stage发生了重试,那么该stage写到hdfs的shuffle数据就会被删除,下游就可能读不到hdfs shuffle文件。

  • 如何判断

如下图可见,stage2因为某种原因(非hdfs shuffle文件not found)失败,导致stage2重试,此时我们看到重试的stage2均因为hdfs shuffle文件找不到而失败。 图片

  • 处理方式

作业失败的根因不是hdfs shuffle文件找不到,而是需要看stage2第一次失败的原因,有可能是偶发的shuffle失败问题,可以先尝试重试。 如果重试还是失败,且报错和第一次一样,建议拉Spark oncall处理。

文件没有写到hdfs上

  • 说明

开了hdfs shuffle功能后,Spark会将每个stage的shuffle数据双写一份到hdfs,这个过程其实是不强保证的,即使写入hdfs shuffle失败,也不会阻塞Spark的运行,所以存在小概率情况,hdfs shuffle文件在一开始没有成功写到hdfs shuffe。

  • 如何判断

排除了上述两种可能性,大概率就是这种情况

  • 处理方式

小概率事件,重试即可