本文概述了可用于查看 Apache Spark 应用程序内部的不同调试选项。 要检查的三个重要位置是:
- Spark用户界面
- 驱动程序日志
- 执行器日志
请参阅 使用 Spark UI 诊断成本和性能问题,了解如何使用 Spark UI 诊断成本和性能问题。
Spark用户界面
启动作业后,Spark UI 会显示有关应用程序中发生的情况的信息。 若要转到 Spark UI,请单击附加的计算:
流媒体选项卡
到达 Spark UI 后,如果流式处理作业在此计算中运行,你将看到“流式处理”选项卡。 如果此计算中未运行流式处理作业,则此选项卡将不可见。 你可跳到驱动程序日志了解如何检查启动流式处理作业时可能发生的异常。
在本页中首先要查看的是你的流媒体应用程序是否从源接收任何输入事件。 在本例中,你可看到该作业每秒接收 1000 个事件。
注意
对于 TextFileStream
,由于文件是输入的,因此输入事件的 #始终为 0。 在这些情况下,可以查看笔记本中的已完成的批处理部分,了解如何查找详细信息。
如果你有一个接收多个输入流的应用程序,则可以单击 输入速率 链接,该链接将显示每个接收器接收到的事件数。
处理时间
向下滚动,找到“处理时间”关系图。 这是了解流式处理作业性能的关键图之一。 一般来说,如果你可在批处理时间的 80% 内处理每个批,那就很好。
对于此应用程序,批处理间隔为 2 秒。 平均处理时间为 450 毫秒,远远低于批处理间隔。 如果平均处理时间接近或大于批处理间隔,那么流式处理应用程序将会开始排队,这会很快导致积压工作,最终可能使流式处理作业失败。
已完成的批处理
在页面末尾,你将看到所有已完成批处理的列表。 该页显示已完成的最后 1000 批的详细信息。 从表中,可以获取每个批处理处理的事件数及其处理时间。 如果想要了解有关其中一个批处理上发生的情况的详细信息,可以单击批处理链接以访问“批处理详细信息”页。
批次详情页
此页面包含有关批处理的所有详细信息。 两个关键事项包括:
- 输入:包含有关批处理输入的详细信息。 在这种情况下,它包含有关此批处理中由 Spark 结构化流读取的 Apache Kafka 主题、分区和偏移量的详细信息。 对于 TextFileStream,会看到此批读取的文件名列表。 对于从文本文件读取的流式处理应用程序,这是启动调试的最佳方式。
- 处理:可以单击指向作业 ID 的链接,该 ID 包含此批处理期间完成的处理的所有详细信息。
作业详细信息页
作业详细信息页显示 DAG 可视化效果。 这对于了解每个批处理的操作顺序和依赖项非常有用。 在本例中,可以看到批处理从 Kafka 直接流读取输入,然后执行平面映射操作,最后执行映射操作。 然后,生成的流用于使用 updateStateByKey 更新全局状态。 (灰色框表示跳过的阶段。如果某些阶段不需要重新计算,Spark 能够聪明地跳过它们。如果数据已经通过检查点或被缓存,Spark 会跳过重新计算这些阶段。在这种情况下,这些阶段对应于updateStateBykey
因为以前批处理的依赖项。由于 Spark 结构化流在内部对流进行检查点处理,从而从检查点读取数据,而不依赖于以前的批处理,因此这些阶段显示为灰色阶段。)
在页面底部,你还将找到为此批处理执行的作业列表。 可以点击描述中的链接,深入了解任务级别的执行情况。
“任务详细信息”页
对于 Spark 应用程序,这是可从 Spark UI 获取的最精细调试级别。 此页面包含为此批处理执行的所有任务。 如果您正在调查流式处理应用程序的性能问题,该页面将提供有关信息,例如执行的任务数,任务执行所在的执行器,以及洗牌信息。
提示
确保在计算中的多个执行程序(节点)上执行任务,在处理时具有足够的并行度。 如果你有一个接收器,那么在某些情况下,尽管你在计算环境中有多个执行程序,但可能只有一个执行程序会完成所有的工作。
线程转储
线程转储显示 JVM 中各线程状态的快照。
在调试特定挂起或运行缓慢的任务时,线程转储很有用。 若要在 Spark UI 中查看特定任务的线程转储文件,请执行以下操作:
- 单击“作业”选项卡。
- 在 作业 表中,找到与要查看的线程转储对应的目标作业,然后单击 说明 列中的链接。
- 在作业的 “阶段 ”表中,找到与要查看的线程转储对应的目标阶段,然后单击 “说明” 列中的链接。
- 在 阶段的任务列表中 ,找到与要查看的线程转储对应的目标任务,并记下其 任务 ID 和 执行程序 ID 值。
- 单击“执行程序”选项卡。
- 在 执行程序 表中,找到包含与前面记录的 执行程序 ID 值对应的 执行程序 ID 值的行。 在该行中,单击“线程转储”列中的链接。
- 在“执行程序的线程转储”表中,单击“线程名称”列包含 (TID) 的行,后跟前面记下的“任务 ID”值。 (如果任务已完成运行,则找不到匹配的线程)。 当前显示任务的线程转储。
对于调试驱动程序似乎挂起(例如,没有显示 Spark 进度条)或查询没有进展(例如,Spark 进度条停滞在 100%)的问题,线程转储也很有用。 若要在 Spark UI 中查看驱动程序的线程转储,请执行以下操作:
- 单击“执行程序”选项卡。
- 在 执行程序 表中,在 驱动程序 行中,单击 线程转储 列中的链接。 显示驱动的线程转储信息。
驱动程序日志
驱动程序日志可用于 2 个目的:
- 异常:有时可能会在 Spark UI 中看不到“流式处理”选项卡。 这是因为流式处理作业由于某些异常而未启动。 可以深入到驱动程序日志,查看异常的堆栈轨迹。 在某些情况下,流式处理作业可能已正常启动。 但你会发现所有批处理永远不会转到“已完成的批处理”部分。 它们可能都处于“正在处理”或“已失败”状态。 在这种情况下,驱动程序日志也可用于了解潜在问题的性质。
- 打印:作为 DAG 的一部分的任何打印语句也显示在日志中。
注意
谁可以访问驱动程序日志取决于计算资源的访问模式。 对于使用 标准 访问模式的计算,只有工作区管理员可以访问驱动程序日志。 对于具有 专用 访问模式的计算,专用用户或组和工作区管理员可以访问驱动程序日志。
执行器日志
如果看到某些任务行为不当,并且希望看到特定任务的日志,则执行程序日志有时很有用。 从上面所示的任务详细信息页中,可以获取运行任务的执行程序。 在获得该程序后,可转到计算 UI 页面,单击 # 节点,然后单击主节点。 主节点页会列出所有工作节点。 可选择运行可疑任务的工作节点,然后转到 log4j 输出。
注意
执行程序日志不适用于 具有标准 访问模式的计算。 对于具有 专用 访问模式的计算,专用用户或组和工作区管理员可以访问执行程序日志。