spark在运行过程中出现task fail 报如下错误:
org.apache.spark.shuffle.FetchFailedException: java.io.FileNotFoundException: /home/disk2/spark/spark-a26b1ea4-d622-4af0-88c9-d73ebba7f79e/spark-local-20150730163603-9e78/04/shuffle_0_70_0.index (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:146)
at org.apache.spark.shuffle.IndexShuffleBlockManager.getBlockData(IndexShuffleBlockManager.scala:109)
…
at org.apache.spark.network.server.TransportRequestHandler.processRpcRequest(TransportRequestHandler.java:124)
at org.apache.spark.network.server.TransportRequestHandler.handle(TransportRequestHandler.java:97)
at org.apache.spark.network.server.TransportChannelHandler.channelRead0
这类错误在计算数据量大的作业Shuffle阶段高频发生。一些解决方案如下:
1) 调整作业实现方式
建议优先从作业的角度去调整,排除一些低效、不必要或不合理的操作。
尽量避免大表直接Join,优先进行filter操作等。
2) 调整spark.storage.memoryFraction和spark.shuffle.memoryFraction
可以适当调大spark.shuffle.memoryFraction(执行内存占用堆内存比例),调小spark.storage.memoryFraction(存储内存占用堆内存比例)。
这样计算节点用于缓存的内存比例会减少,用于计算的内存比例会增加,能在一定程度上缓解此问题。
3) 调整partition数目
可以通过repartition操作适当增大partition数目,“少量多次”处理。
更多的partition意味这任务被分解为更多份,可以缓解executor执行单任务的内存压力。
4) 增大Memory
如果上述方案和参数调整后仍然出OOM那就是计算资源内存实在不足,考虑增加资源了。
调大spark.executor.memory。
5) 作业分解,长尾数据特殊处理
如果作业Shuffle阶段失败是由于少数长尾Task导致,则可以考虑将长尾数据从原始数据中剥离出来。
剥离后的非常尾数据有很大概率不需要调整作业实现和内存参数就能直接运行通过。
对于长尾数据,可以单独另起作业专门处理,根据具体业务场景使用不同的参数。
如果一次处理不完,可以将长尾数据分解,”少量多次”处理。