文章目录
- Hive 数据血缘实现介绍
- 表级别
- 表级别总结
- 推荐阅读:
- 字段级别
- 字段级别总结
- 推荐阅读:
Hive 数据血缘实现介绍
Hive作为一个离线数仓工具,其实自带了数据血缘分析的解决方案:
- 表级别: org.apache.hadoop.hive.ql.tools 下的LineageInfo类
- 字段级别:这里有两种方式
①org.apache.hadoop.hive.ql.hooks.LineageLogger类
②Execution Hooks机制
本文只做简单介绍,方便自己查询.详细使用参考我给出的文章链接
表级别
LineageInfo#main方法展示
public static void main(String[] args) throws IOException, ParseException,
SemanticException {
String query = args[0];
LineageInfo lep = new LineageInfo();
lep.getLineageInfo(query);
for (String tab : lep.getInputTableList()) {
System.out.println("InputTable=" + tab);
}
for (String tab : lep.getOutputTableList()) {
System.out.println("OutputTable=" + tab);
}
}
由于这个类自带main方法我们可以直接命令行跑jar,也可以直接复制到自己的项目中使用,输出结果大概这样
InputTable=tb1
InputTable=tb2
OutputTable=dw.tmp_info
表级别总结
LineageInfo这种方式上手简单迅速,但是效果一般,只知道输入/输出表名.
推荐阅读:
文章:
-
hive血缘关系之输入表与目标表的解析 博客园这篇帖子对
LineageInfo
这个类添加了识别with语法的等功能,实质上就是在switch 多加了对 TOK_CTE的判断,找出表名罢了 - 利用LineageInfo分析HiveQL中的表级别血缘关系 这个是我最初看的,仅仅就是简略介绍+简单使用,扫一眼即可
-
大数据血缘分析系统设计(三) 利用hive hook获得hql语句再利用
LineageInfo
解析,顺便提到了类似的思路:Spark SparkListener
字段级别
字段级别比较麻烦,由于 select * 等这种存在还得连接元数据库
,所以Hive的解决办法还是将SQL直接跑一遍.
之前我说字段级本身有LineageLogger
和 Execution hook
(即钩子),实际上LineageLogger
也是基于 钩子 这一机制实现的,两者殊途同归.
hook需要先去hive的xml配置一下
vi /usr/local/hive/conf/hive-site.xml
hive.exec.post.hooks
org.apache.hadoop.hive.ql.hooks.LineageLogger
然后跑SQL,结束后血缘JSON就会打印在终端上
如果想将生成的血缘以文件的形式保存,需要配个配置
vi /usr/local/hive/conf/hive-log4j.properties
在文件末尾追加
log4j.logger.org.apache.hadoop.hive.ql.hooks.LineageLogger=INFO
默认日志输出在/tmp/${user.home}/hive.log
生成JSON数据格式如下(来着CXY的大数据实践田,为了篇幅美观有删减 )
{
"version": "1.0",
"user": "hadoop",
"timestamp": 1510308124,
"duration": 45959,
"jobIds": [
"job_1509088410884_16752"
],
"engine": "mr",
"database": "cxy7_dw",
"hash": "a184be21aadb9dd5b6c950fe0b3298d8",
"queryText": "SELECT z.zoneid AS zone_id,z.zonename AS zone_name, c.cityid AS city_id, c.cityname AS city_name FROM dict_zoneinfo z LEFT JOIN dict_cityinfo c ON z.cityid = c.cityid AND z.dt='20171109' AND c.dt='20171109' WHERE z.dt='20171109' AND c.dt='20171109' LIMIT 10",
"edges": [
{
"sources": [
4
],
"targets": [
0
],
"edgeType": "PROJECTION"
},
{
"sources": [
10,
9
],
"targets": [
0,
1,
2,
3
],
"expression": "((z.dt = '20171109') and (c.dt = '20171109'))",
"edgeType": "PREDICATE"
}
],
"vertices": [
{
"id": 0,
"vertexType": "COLUMN",
"vertexId": "zone_id"
},
{
"id": 1,
"vertexType": "COLUMN",
"vertexId": "zone_name"
},
{
"id": 2,
"vertexType": "COLUMN",
"vertexId": "city_id"
}
]
}
- vertices:顶点。代表参与DAG的节点元素,vertexType有COLUMN和TABLE两个值
- edges:边。代表DAG的流向,由sources指向targets,edgeType有PROJECTION(投影)和PREDICATE(谓语)两个值
static {
OPERATION_NAMES.add(HiveOperation.QUERY.getOperationName());
OPERATION_NAMES.add(HiveOperation.CREATETABLE_AS_SELECT.getOperationName());
OPERATION_NAMES.add(HiveOperation.ALTERVIEW_AS.getOperationName());
OPERATION_NAMES.add(HiveOperation.CREATEVIEW.getOperationName());
}
从LineageLogger
源码可以看出,hive支持
- HiveOperation.QUERY
- HiveOperation.CREATETABLE_AS_SELECT
- HiveOperation.ALTERVIEW_AS
- HiveOperation.CREATEVIEW
字段级别总结
利用Hook这一方案最大的问题在于必须实实在在地去Hive把SQL跑一遍,其它无缺点.
由于有边和顶点的数据,所以市面上我查到有关的Hive 血缘文章,大多数是要把生成的json存到图数据neo4j可视化展示.
可惜不适应于我司~