Spark Thrift Server改造:返回执行进度日志

Posted CodingArt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spark Thrift Server改造:返回执行进度日志相关的知识,希望对你有一定的参考价值。

一、问题背景


当前Spark Thrift Server在运行SQL时,Client不会输出任何日志,只有任务运行结束后输出的查询结果集(目前Spark最新版本2.4.0仍有此问题)。在任务运行过程中看不到当前的执行进度,影响了用户的使用体验,为了解决此问题对Spark Thrift Server作了一番改造。

此前为了解决任务提交入口收敛的问题也对HiveServer2作了改造,了解过其内部的相关具体实现,而Spark Thrift Server的核心代码移植自HiveServer2,因此想到通过对比两者的实现差异找到解决问题的切入点。


二、相关实现


Hive的查询结果和执行日志都是通过 fetchResults 方法返回,由 FetchType 参数指定返回的是查询结果(QUERY_OUTPUT)还是执行日志(LOG)。

Spark Thrift Server改造:返回执行进度日志

任务的执行日志在具体代码实现中被称为OperationLog,有关日志的读、写、删除操作都封装在该类中。OperationLog以本地文件的方式存储在 hive.server2.logging.operation.log.location 配置的目录中,每个session有唯一的UUID,对应一个存储目录,相同session内提交的statement用单独的文件存储日志(以提交这个statement的handle UUID作为对应的文件名)。

Spark Thrift Server改造:返回执行进度日志

执行日志的写入并非直接调用OperationLog.writeOperationLog方法,而是专门实现了一个Log4j Appender,通过动态追加Appender,其他类在调用log.info()等方法打印日志时就会统一写入OperationLog。由于在调用log.info()时并不会传入与OperationLog有关的参数,为了区分哪些日志应该写入到哪个OperationLog中,OperationLog内部使用了ThreadLocal与线程做了绑定,也就是说在相同线程上调用log.info打印的日志将写入到相同线程的OperationLog中。

Spark Thrift Server改造:返回执行进度日志

通过对比发现,Spark Thrift Server不输出日志是由于在执行前没有将OperationLog与线程绑定,涉及改动代码:

Spark Thrift Server改造:返回执行进度日志

Spark Thrift Server改造:返回执行进度日志

重新编译,然后测试,发现也就只有寥寥几行日志,依然没有进度信息:

Spark Thrift Server改造:返回执行进度日志

但Thrift Server端却有较详细的进度日志,包括各个stage、task的运行情况等,由此推断 TaskSetManager 的方法调用与OperationLog不在相同线程内。

Spark Thrift Server改造:返回执行进度日志

为了获取各个stage、task的运行信息,可以通过注册 SparkListener 实现:

首先在 SparkExecuteStatementOperation 中保存 statementId 与 OperationLog 实例的映射关系,然后在 SparkListener 通过 statementId 得到对用的 OperationLog 实例实现执行日志的写入。另外,由于SparkListener中的各个接口参数信息不全的关系,在 SparkListener 内部还需要额外存储 jobId 与 statementId、stageId 与 jobId 的映射关系以辅助找到对应的OperationLog 实例。


最后一步,在 HiveThriftServer2 中注册该SparkListener:

最终输出执行日志效果:


以上是关于Spark Thrift Server改造:返回执行进度日志的主要内容,如果未能解决你的问题,请参考以下文章

「Spark」Spark SQL Thrift Server运行方式

Spark的thrift端口

spark sql thrift server

身份验证和授权Spark Thrift Server

对 Spark Thrift Server 的直线查询未在 Spark History UI 中显示任何内容

使用HAProxy代理控制Spark SQL Thrift Server服务的最大连接数