自定义Hive Sql Job分析工具

本文介绍了如何分析Hive SQL Job,特别是针对大SQL拆分成的子Job,通过查找HDFS上的job配置文件获取Hive查询字符串。解析过程中遇到了中文乱码和单线程解析效率低的问题,通过转码和多线程处理提高了效率。然而,数据写入MySQL的速度仍然较慢,可能存在超长SQL导致的问题。提供了GitHub上的源代码链接。

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

前言

我们都知道,在大数据领域,Hive的出现帮我降低了许多使用Hadoop书写方式的学习成本.使用用户可以使用类似Sql的语法规则写明查询语句,从hive表数据中查询目标数据.最为重要的是这些sql语句会最终转化为map reduce作业进行处理.这也是Hive最强大的地方.可以简单的理解为Hive就是依托在Hadoop上的1个壳.但是这里有一点点小小的不同,不是每段hive查询sql语句与最后生成的job一一对应,如果你的这段sql是一个大sql,他在转化掉之后,会衍生出许多小job,这些小job是独立存在运行的,以不同的job名称进行区别,但是也会保留公共的job名称.所以一个问题来了,对于超级长的hive sql语句,我想查看到底是哪段子sql花费了我大量的执行时间,在JobHistory上只有每个子Job的运行时间,没有子Job对应的sql语句,一旦这个功能有了之后,就会帮助我们迅速的定位到问题所在.


Hive子Job中的Sql

OK,带着上述的目标,我们要想分析出到底哪段子sql所衍生的job运行时间更长,就要先知道这些sql到底在存在与哪里.在前面的描述中,已经提到了,Hive是依托于Hadoop,自然Hive提交的job信息也是保存在Hadoop的HDFS上的.在联想一下JobHistory中的各个文件类型.你应该会发现带有下面后缀的文件存在.


我们发现里面包含了之前分析过的.jhist文件,还有带conf字符的.xml格式文件,从文件名上来看就是job提交时的一些配置信息,然后我们用vim命令查阅conf.xml后缀的文件,看看里面是不是有我们想要的hive qury string 这样的属性


OK,目标算是找到了,这的确就是我们想要的属性.说明这样的信息的确是存在的,后面的操作就是怎么去解析这段有用的信息了.


程序工具分析Hive Sql Job

知道了目标数据源,我们能想到的最简单快速的方法就是逐行解析文件,做做文本匹配,筛选关键信息.这些代码谁都会写,首先要传入一个HDFS目录地址,这个是在JobHistory的存储目录上加上一个具体日期目录,这段解析程序在文章的末尾会加上.下面列举在调试分析程序时遇到的一些问题,这个还是比较有用的.

1.hive sql中的中文导致解析出现乱码

这个又是非常讨厌的java解析出现乱码的原因,因为考虑到sql中存在中文注释,而Hadoop在存中文的时候都是用utf8的编码方式,所以读出文件数据后进行一次转utf-8编码方式的处理,就是下面所示代码.

...
fileSystem = path.getFileSystem(new Configuration());
			in = fileSystem.open(path);
			InputStreamReader isr;
			BufferedReader br;

			isr = new InputStreamReader(in, "UTF-8");
			br = new BufferedReader(isr);

			while ((str = br.readLine()) != null) {
...

2.单线程解析文件速度过慢

之前在测试环境中做文件解析看不出真实效果,文件一下解析就OK了,但是到真实环境中,多达几万个job文件,程序马上就吃不消了,算上解析文件,再把结果写入mysql,耗时达到60多分钟,后面改成了多线程的方式,后来开到10个线程去跑,速度才快了许多.


3.结果数据写入MySql过慢

后来处理速度是上去了,但是写入sql速度过慢,比如说,我有一次测试,开10个线程区解析,花了8分钟就解析好了几万个文件数据,但是插入数据库花了20分钟左右,而且量也就几万条语句.后来改成了批处理的方式,效果并没有什么大的改变,这个慢的问题具体并没有被解决掉,怀疑可能是因有些语句中存在超长的hive sql语句导致的.


下面是程序的主要分析代码,分为工具类代码,和解析线程类,代码全部链接再此处:https://github.com/linyiqun/yarn-jobhistory-crawler/tree/master/jobHiveSqlAnalyse

主工具代码

package org.apache.hadoop.mapreduce.v2.hs.tool.sqlanalyse;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileContext;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.fs.UnsupportedFileSystemException;
import org.apache.hadoop.io.IOUtils;

public class HiveSqlAnalyseTool {
	private int threadNum;
	private String dirType;
	private String jobHistoryPath;

	private FileContext doneDirFc;
	private Path doneDirPrefixPath;

	private LinkedList<FileStatus> fileStatusList;
	private HashMap<String, String[]> dataInfos;
	private DbClient dbClient;

	public HiveSqlAnalyseTool(String dirType, String jobHistoryPath,
			int threadNum) {
		this.threadNum = threadNum;
		this.dirType = dirType;
		this.jobHistoryPath = jobHistoryPath;

		this.dataInfos = new 
### 在 Flink SQL 中集成和使用 Hive 自定义函数(UDF) 要在 Flink SQL 中集成和使用 Hive 自定义函数(UDF),可以按照以下方法进行配置和操作。以下是详细的说明以及相关注意事项。 --- #### 1. 加载 HiveModule 为了能够正常使用 Hive 的内置 UDF 或者自定义 UDF,首先需要加载 `HiveModule`。这一步骤使得 Flink 能够识别并调用 Hive 的系统函数[^1]。 代码示例 (Java): ```java import org.apache.flink.table.api.EnvironmentSettings; import org.apache.flink.table.api.TableEnvironment; public class LoadHiveModule { public static void main(String[] args) { EnvironmentSettings settings = EnvironmentSettings.newInstance().useBlinkPlanner().inBatchMode().build(); TableEnvironment tableEnv = TableEnvironment.create(settings); // 加载 HiveModule tableEnv.getConfig().getConfiguration().setString("table.modules", "hive"); System.out.println("HiveModule 已成功加载!"); } } ``` 注意:确保使用的 Planner 是 Blink Planner,因为只有 Blink Planner 支持完整的 Hive 功能集[^2]。 --- #### 2. 配置 HiveCatalog 为了让 Flink 访问 Hive Metastore 并获取其中的 UDF 定义,必须正确配置 `HiveCatalog`。该步骤还包括指定 Hive 的配置目录位置。 代码示例 (Java): ```java import org.apache.flink.table.catalog.hive.HiveCatalog; public class ConfigureHiveCatalog { public static void main(String[] args) throws Exception { String name = "my_hive_catalog"; String defaultDatabase = "default"; String hiveConfDir = "/path/to/hive/conf"; HiveCatalog catalog = new HiveCatalog(name, defaultDatabase, hiveConfDir); tableEnv.registerCatalog(catalog.getName(), catalog); System.out.println("HiveCatalog 注册成功!"); } } ``` --- #### 3. 将 Hive UDF JAR 包加入 ClassPath 如果要使用自定义Hive UDF,则需要将包含这些 UDF 的 JAR 文件放置到 Flink 的类路径中。具体做法是将 JAR 文件复制到 Flink 的 `lib` 目录下,或者通过命令行参数 `-C` 显式指定其路径[^2]。 例如: ```bash ./bin/flink run -c com.example.MyJob \ -C file:///path/to/my_udf.jar \ ./job.jar ``` --- #### 4. 使用 Hive UDF 当完成上述准备后,可以在 Flink SQL 中直接调用 Hive 的 UDF 函数。需要注意的是,某些特殊类型的 UDF 可能需要额外的类型适配器来处理数据格式差异[^3]。 SQL 示例: ```sql -- 假设存在一个名为 my_custom_udf 的 Hive UDF SELECT id, my_custom_udf(data_column) AS processed_data FROM source_table; ``` --- #### 5. 注意事项 - **版本兼容性**:确保 Flink 和 Hive 的版本兼容,否则可能会遇到运行时异常。 - **数据类型映射**:部分 Hive 数据类型可能无法直接映射到 Flink 类型体系中,需手动调整或编写转换逻辑[^4]。 - **性能优化**:对于复杂的 UDF 运算场景,应关注执行计划是否合理,并适当增加资源分配以提高吞吐量。 --- ### 示例总结 综合来看,整个流程涉及以下几个核心环节:加载 HiveModule、注册 HiveCatalog、导入必要的 JAR 包以及最后在 SQL 查询中应用所需的 UDF 函数[^5]。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值