基于Hive内部接口实现的Hive数据血缘的介绍

文章目录

Hive 数据血缘实现介绍

Hive作为一个离线数仓工具,其实自带了数据血缘分析的解决方案:

  • 表级别: org.apache.hadoop.hive.ql.tools 下的LineageInfo类
  • 字段级别:这里有两种方式
  1. org.apache.hadoop.hive.ql.hooks.LineageLogger类
  2. 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这种方式上手简单迅速,但是效果一般,只知道输入/输出表名.

推荐阅读:

文章:


字段级别

字段级别比较麻烦,由于 select * 等这种存在还得连接元数据库,所以Hive的解决办法还是将SQL直接跑一遍.

之前我说字段级本身有LineageLoggerExecution 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就会打印在终端上

我们可以添加Lineage到日志

vi /usr/local/hive/conf/hive-log4j.properties

在文件末尾追加

log4j.logger.org.apache.hadoop.hive.ql.hooks.LineageLogger=INFO

默认日志输出在/tmp/${user.home}/hive.log


 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

生成JSON数据格式如下(借用他人的,有删减)

{
    "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(谓语)两个值

字段级别总结

利用Hook这一方案最大的问题在于必须实实在在地去Hive把SQL跑一遍,其它无缺点.
由于有边和顶点的数据,所以市面上我查到有关的Hive 血缘文章,大多数是要把生成的json存到图数据neo4j可视化展示.
可惜不适应于我司~

推荐阅读:

开源项目:

文章:

排错:

上一篇:React函数类组件及其Hooks学习


下一篇:Pikachu漏洞练习平台 记录(xss)