Spark 任务执行排查慢的问题排查-2

现象描述:

Application主要是从hadoop文件中读取数据,然后计算出24小时的车辆状态,并存储。所以总共24个Job。之前Application的平均执行时间是2小时,目前执行时间是5小时。仔细查看Application的执行的每一个Job,之前都是2分钟,目前都是10分钟左右。

细节描述

《Spark 任务执行排查慢的问题排查-2》 image.png

但是可以看到的是每个job都有一个stage 是failed
任选一个Job然后点开stage列表
发现所有stage的耗时时间只不过3分钟,但是奇怪的是这为什么显示的是10分钟。
这个原因解释一下:
每个stage执行的时候可能会失败(时间不一定,可能5,6分钟),但是失败之后Spark会自动重试,如果自动重试成功的话,那么这个stage的执行时间是按照执行成功的时间计算的,所以大家看到所有stage的Duration时间总和并不等于这个Job的Duration。
每个Job运行的时候可以看到每个Stage的状态,包括失败的Stage,但是这个每个Job执行结束了话就没办法在UI上看到错误的信息了。如果没有的话,可以去yarn的日志里面看。

排查过程:

1 查看机器的性能 cpu,内存,磁盘io
  • 查看cpu

    《Spark 任务执行排查慢的问题排查-2》 image.png

    发现并没有问题,load 3.13,

  • 内存(free -h)

    《Spark 任务执行排查慢的问题排查-2》 image.png

    发现也没有问题

  • 查看磁盘容量

    《Spark 任务执行排查慢的问题排查-2》 image.png

    也没问题

  • 查看磁盘读写
    iostat -x 1s 10 每个一秒统计一次,总共统计十次

    《Spark 任务执行排查慢的问题排查-2》 image.png

    也没有问题

2 获取driver进程id

根据UI提示的问题,怀疑,每个Job执行完之后都可能由于driver机器性能问题导致没有开启下一个job,在UI界面查看applicationId,以及driver的机器ip
于是登陆driver机器

ps -ef |grep ApplicationMaster |grep applicationId 获取到driver进程的processId
3 查看进程内存
  • jmap -heap processId 主要查看年轻代Eden,和Old

    《Spark 任务执行排查慢的问题排查-2》 image.png

  • 查看gc情况
    jstat -gcutil processId 1s 60
    《Spark 任务执行排查慢的问题排查-2》 image.png
    这个数值有了,如何判断gc是否频繁呢,主要是看GC的时间和频次。
    按照我的经验:如果 YGC的不到10s一次,就是过于频繁,每次耗时超过 20ms就有点长。根据你具体的业务情况而定
查看业务日志

错误信息贴一下:

Caused by: java.io.IOException: Connecting to d5.hdp.cn/10.190.1.xx:11538 timed out (120000 ms)
at org.apache.spark.network.client.TransportClientFactory.createClient(TransportClientFactory.java:230)
    at org.apache.spark.network.client.TransportClientFactory.createClient(TransportClientFactory.java:182)
    at org.apache.spark.network.netty.NettyBlockTransferService$$anon$1.createAndStart(NettyBlockTransferService.scala:98)
    at org.apache.spark.network.shuffle.RetryingBlockFetcher.fetchAllOutstanding(RetryingBlockFetcher.java:141)
    at org.apache.spark.network.shuffle.RetryingBlockFetcher.lambda$initiateRetry$3(RetryingBlockFetcher.java:169)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
    ... 1 more

可以明显看到是错误日志的问题,是网络连接问题,于是登陆问题及其,ping了一下目标及其,发现根本不通。发现问题。

后来经运维同学排查,是因为原来老的hostname是d5的机器下线了,换了一个新的机器,结果ip变了,但是其他机器的host没改,导致找不到新机器。

总结

这又是一个Spark执行的慢的问题排查,这次的排查比较耗时,原因是没有直接去查看业务日志,没直接看看到UI提供的错误信息提示,而是直接根据主观的看法,去判断driver的机器性能问题。
这里比较重要的一点也是,spark job 中stage在ui显示的计算时间的问题,这个一定要做好区分。stage最后显示的时间,是成功的stage执行时间,但是Spark job duration 是 success 和failed的所有stage执行时间之和。

    原文作者:pcqlegend
    原文地址: https://www.jianshu.com/p/1f45bb8a81b3
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞