Hive SQL运行状态监控(HiveSQLMonitor)

本文介绍了一种方法,通过分析HiveSQL执行过程中的日志信息,实现对HiveSQL执行状态的实时监控与进度展示。利用会话日志、预钩子(PreHook)和自定义的REST API服务,该方法能够收集并处理日志数据,从而获取到查询执行的详细状态,包括转换为的MapReduce任务数量、各任务的进度以及最终的执行结果。同时,通过维护JobName与QueryId的关系,以及JobName与查询进度的对应,实现对查询执行进度的跟踪。尽管数据维护在内存中且服务为单点,但此方法提供了对HiveSQL执行过程的透明化监控手段。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hive SQL运行状态监控(HiveSQLMonitor)

引言

 
目前数据平台使用Hadoop构建,为了方便数据分析师的工作,使用Hive对Hadoop MapReduce任务进行封装,我们面对的不再是一个个的MR任务,而是一条条的SQL语句。数据平台内部通过类似JDBC的接口与HiveServer进行交互,仅仅能够感知到一条SQL的开始与结束,而中间的这个过程通常是漫长的(两个因素:数据量、SQL复杂度),某些场景下用户需要了解这条SQL语句的执行进度,从而为我们引入以下几个问题:
 
(1)通过JDBC接口执行一条SQL语句时,这条SQL语句被转换成几个MR任务,每个MR任务的JobId是多少,如何维护这条SQL语句与MR任务的对应关系?
(2)如何获取MR任务的运行状态,通过JobClient?
(3)通过HiveServer是否可以获取到上述信息?
 
思路
 
当我们在终端下执行命令“hive”后,会看到有如下输出:
 
 
Hive有会话(Session)的概念,而 这次会话中的所有日志消息将会输出到这个日志文件中,包含SQL语句的执行日志,查看这个日志文件可以看到以下信息:
 
 
 
QueryStart行日志包含QUERY_STRING、QUERY_ID。
 
 
TaskStart行日志包含TASK_ID、QUERY_ID。
 
 
TaskProgress行日志包含TASK_HADOOP_PROGRESS、TASK_ID、QUERY_ID、TASK_HADOOP_ID,其中TASK_HADOOP_PROGRESS中可以获取到map、reduce进度。
 
 
TaskEnd行日志包含TASK_HADOOP_PROGRESS、TASK_ID、QUERY_ID、TASK_HADOOP_ID。
 
 
QueryEnd行日志包含QUERY_STRING、QUERY_ID。
 
由上可知,QueryStart、TaskStart、TaskProgress、TaskEnd(一个复杂的Query可能会产生多个Task)、QueryEnd覆盖整个查询的执行过程,通过对这些行日志的解析,我们就可以获取到Hive SQL的执行状态。
 
此外,还有SessionStart、SessionEnd,由于使用过程中发现SessionEnd日志有时不被输出,因此没有使用这两个状态。
 
会话的日志文件存储在HiveServer的本地磁盘中,而实际应用中我们有多台HiveServer提供服务,因此我们需要能够统一收集所有HiveServer的会话日志。
 
通过对Hive源码的分析发现,每次Hive执行语句时都会执行一些“Hook”(PreHook),代码如下:
 
 
通过会话日志、PreHook,我们基本可以整理出以下思路:
 
在PreHook中启动线程监听会话日志的输出(类型Linux的tailf),将这些日志信息统一收集到某一服务中,统一处理后做进度展示。
 
实现
 
我们构建了一个Rest API服务,一部分用于接收由PreHook发送的会话日志信息,另一部分用于对外提供进度展示。
 
PreHook要求实现接口ExecuteWithHookContext,如下:
 
 
通过hookContext我们可以获取到以下信息:
 
QueryId:
 
 
QueryStr:
 
 
HadoopJobName:
 
 
Jobs:
 
 
HistFileName:
 
 
为了保证后续对会话日志的接收,我们需要在查询执行伊始就将上述信息发送给Rest API服务,如下:
 
 
 
然后就是对会话日志的输出监听(即tailer),我们使用Apache Commons IO中的Tailer完成些功能,如下:
 
 
Tailer实际上启动一个后台线程,并通过listener完成数据行的处理,而一次会话中可能执行多条查询语句,而每一次执行查询语句时都会导致PreHook的执行,因此我们需要避免同一会话中对histFileName多次“tailf”,需要维护已被“tailf”的文件,而且Tailer实例是需要被“stop”的,多数时候无法获取到SessionEnd数据行,需要通过其它方式能够终止会话已经消失的Tailer线程。为此专门设计了TailerTracker(单例,即TAILER_TRACKER)。
 
TailerTracker维护着一个记录列表:
 
 
 
 
维护着成对的tailer与listener实例,其中listener实例中维护着对应tailer实例中最后一次新数据产生的时间,如果tailer实例在设定的时间内都没有新数据产生,则应该对其执行stop,核心代码如下:
 
 
判断某一个会话文件是否已经被“tailer”,代码如下:
 
 
标记一个会话文件已经被“tailer”,代码如下:
 
 
会话日志数据行的输出实际由FileTailerListener(继承自TailerListenerAdapter)完成,代码如下:
 
 
每处理一行数据,都要更新一下时间戳lastHandleTime,而QueryStart、QueryEnd、TaskStart、TaskProgress、TaskEnd的数据行会通过不同的Rest API Post。
 
至此,HiveServer的会话日志收集过程完毕,而Rest服务则需要通过这些收集到的数据完成Hive SQL进度跟踪。
 
我们在通过JDBC接口与HiveServer交互时,是无法获取到QueryId的,但是我们可以通过属性mapred.job.name设置Hive SQL执行时的MR JobName,JobName代表查询名称,需要唯一,同时我们需要维护JobName与QueryId的对应关系。
 
在Rest服务内部设计实现ProgressController,用以维护JobName与QueryId的对应关系,同时使用QueryId跟踪Hive SQL执行进度,核心变量如下:
 
 
目前Hive SQL的进度记录仅仅在内存里维护(超过一定时间后,这些进度信息便不再有价值),因此需要控制内存中进度记录的数量,这一点是通过记录每一条SQL相关进度信息的最后更新时间(lastUpdateTime)来实现的,过期即被清除。
 
lastUpdateTime:维护JobName(即某个查询)记录最后更新时间;
 
jobNameToQueryId:维护JobName与QueryId的对应关系;
 
querys:维护QueryId与Hive SQL执行进度(QueryProgress)的对应关系。
 
QueryProgress内部结构如下:
 
 
queryId:查询ID;
 
sql:查询语句;
 
jobs:查询被转换成MapRecude Job的数量;
 
taskProgresses:维护TaskId与MapReduce的执行进度的对应关系;
 
startTime:查询的起始时间;
 
stopTime:查询的终止时间;
 
state:查询状态。
 
TaskProgress内部结构如下:
 
 
taskId:TaskId(Stage-1、Stage-2、...);
 
taskHadoopId:Task对应的Hadoop MapReduce Job Id;
 
map:Hadoop MapReduce map进度百分比值;
 
reduce:Hadoop MapReduce reduce进度百分比值;
 
startTime:Task起始时间;
 
stopTime:Task截止时间;
 
state:Task运行状态。
 
当收到query/init的请求时,执行ProgressController queryInit方法,代码如下:
 
 
当收到query/start的请求时,执行ProgressController queryStart方法,代码如下:
 
 
 
当收到task/start的请求时,执行ProgressController taskStart方法,代码如下:
 
 
当收到task/progress的请求时,执行ProgressController taskProgress方法,代码如下:
 
 
当收到task/end的请求时,执行ProgressController taskEnd方法,代码如下:
 
 
当收到query/end的请求时,执行ProgressController queryEnd方法,代码如下:
 
 
其中ProgressController还承担着定时清理的工作,代码如下:
 
 
进度示例
 
 
 
不足
 
Hive SQL执行进度数据维护在内存中,而且Rest服务为单点。
Hive SQL 是一种基于 Hadoop 平台的分布式数据仓库,它使用类 SQL 语言来查询和分析数据。如果你想在自己的电脑上运行 Hive SQL,你需要进行以下步骤: 1. 安装 Hadoop:你需要先安装 Hadoop,因为 Hive SQL 是建立在 Hadoop 之上的。你可以从官方网站下载 Hadoop,然后按照官方文档进行安装。 2. 安装 Hive:在安装完 Hadoop 后,你需要下载安装 Hive。你可以从官方网站下载 Hive,然后按照官方文档进行安装。 3. 配置环境变量:当安装完 Hive 后,你需要将 Hive 的路径添加到系统的环境变量中。你可以在命令行中输入以下命令来添加环境变量: ``` export HIVE_HOME=/path/to/hive export PATH=$PATH:$HIVE_HOME/bin ``` 其中,`/path/to/hive` 是你安装 Hive 的路径。 4. 启动 Hive:当你完成了前面的步骤后,你就可以启动 Hive 了。在命令行中输入以下命令来启动 Hive: ``` hive ``` 这个命令会启动 Hive 的交互式命令行界面,你可以在这个界面中输入 Hive SQL 语句来查询和分析数据。 如果你想打包 Hive SQL 应用程序并在集群上运行,你需要进行以下步骤: 1. 编写 Hive SQL 脚本:你需要编写一个 Hive SQL 脚本来查询和分析数据。你可以使用任何文本编辑器来编写这个脚本,脚本的文件格式应该是 .sql。 2. 将脚本上传到 HDFS:在你能够在集群上运行 Hive SQL 脚本之前,你需要将脚本上传到 HDFS 中。你可以使用 Hadoop 的命令行工具或者 HDFS 的 Web 界面来上传文件。 3. 运行 Hive SQL 脚本:当你完成了前面的步骤后,你就可以在集群上运行 Hive SQL 脚本了。在命令行中输入以下命令来运行脚本: ``` hive -f /path/to/script.sql ``` 其中,`/path/to/script.sql` 是你上传到 HDFS 中的 Hive SQL 脚本的路径。 这些是在本地和集群上运行 Hive SQL 的基本步骤。如果你想更深入地了解 Hive SQL,你可以参考官方文档或者其他在线教程。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值