Spark Task的各个动作时间来源以及Task Schedule Delay 问题排查

Spark Task的各个动作时间来源以及Task Schedule Delay 问题排查,第1张

Spark Task的各个动作时间来源以及Task Schedule Delay 问题排查 背景

发现线上偶尔会出现一些Spark Task会显示Schedule Delay数分钟甚至十几分钟,所以要排查原因。

Task 时间分析以及Schedule Delay计算公式

如图所示,时间轴上面的表示Driver 记录到的各个时间,时间轴下面的表示Executor记录到的各个时间。
我们反过来,先说 Executor 记录的各个时间,再说Driver记录的各个时间。

Executor 中Task运行时间

Task 在Executor端运行,有三个时间段,分别是 deserializeTime, executorRunTime, serializeTime。(很奇怪,Task 并没有选择和Driver端一样的方式,直接计算各个阶段的起止时间,而是选择将各个阶段的运行耗时计算好,再通过 metrics 返回给Driver。这种方式潜在的给我们这次问题排查造成了第一个麻烦。如果不能确定Task的真正开始和结束时间,那么我们就没办法确定Task Delay 发生在哪一个阶段了。)

  • deserializeTime: 表示Task获取Task后,进行反序列化的时间。 计算公式:task.metrics.setExecutorDeserializeTime(TimeUnit.NANOSECONDS.toMillis((taskStartTimeNs - deserializeStartTimeNs) + task.executorDeserializeTimeNs)) 包含两部分,task = ser.deserialize[Task[Any]](taskDescription.serializedTask, classLoader) 和 val (rdd, func) = ser.deserialize[(RDD[T], (TaskContext, Iterator[T]) => U)](ByteBuffer.wrap(taskBinary.value), classLoader)
  • executorRunTime: 表示Task 执行时间,不包含上面的 deserializeTime 时间,也不包含下面的对结果序列化的 serializeTime 时间。计算公式: task.metrics.setExecutorRunTime(TimeUnit.NANOSECONDS.toMillis((taskFinishNs - taskStartTimeNs) - task.executorDeserializeTimeNs))
  • serializeTime: 表示Task直接结果在发往Driver之前,进行序列化的时间。 计算公式: task.metrics.setResultSerializationTime(TimeUnit.NANOSECONDS.toMillis(afterSerializationNs - beforeSerializationNs))
Driver中Task运行时间
  • LaunchTime: 在 TaskSetManager 中,也叫 resourceOfferTime ,即 taskSet.offerTask() 成功后,开始运行 Task 的时间
  • LaunchDelay: 表示 从Stage被提交到当前Task被调度的时间,计算公式: taskInfo.launchTime - stage.submissionTime
  • finishTime: Driver最后标识该Task生命周期结束的时间, 具体是从 handleSuccessTask(taskSet, tid, serializedData) 进入 markFinished() 的时间
  • gettingResultTime: 如果我们的 Task 返回的结果比较大,Task结果返回的方式是 IndirectTaskResult,Driver 会在记录开始调用 fetchIndirectTaskResult() 进行读取结果的时间。(实际上应该还包括对读取的数据的deserialize 时间)。如果是 DirectTaskResult ,该时间为 0。 因为代码风格问题,在偏前段的代码中,改名叫 resultFetchStart, gettingResultTime 被重新定义为函数 = {launchTime + duration - fetchStart }
  • duration: = finishTime - launchTime
Schedule Delay Time

我们直接用UI页面(AppStatusUtils)的Schedule Delay Time 公式来分析

gettingResultTime = launchTime + duration - fetchStart
schedulerDelay =  math.max(0, 
	duration - runTime - deserializeTime - serializeTime - gettingResultTime
	)

所以这里得到的就是上图中的两个粉红色的时间范围。通过分析Executor 的 Task 运行日志,初步判定,是Task运行结束,上报RPC到Driver后的那一个时间段出现了问题。

预知后续分析,且听下回分解~~

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5575116.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存