48

数仓字段血缘解析实现(hive 版)

 4 years ago
source link: https://mp.weixin.qq.com/s/ufeZC32bdgdcMo-0WQK7-Q
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

本文大纲

1、字段血缘分析的意义

2、实现方案选择

3、实现过程

4、总结

字段血缘分析的意义

数仓经常会碰到的两类问题:

1、两个数据报表进行对比,结果差异很大,需要人工核对分析指标的维度信息,比如从头分析数据指标从哪里来,处理条件是什么,最后才能分析出问题原因       ——数据回溯问题

2、基础数据表因某种原因需要修改字段,需要评估其对数仓的影响,费时费力,然后在做方案        —— 影响分析问题

这两类问题都属于数据血缘分析问题,数据血缘分析还有其它的积极意义,比如:

  • 问题定位分析

    类似于影响分析,当程序运行出错时,可以方便找到问题的节点,并判断出问题的原因以及后续的影响

  • 指标波动分析

    当某个指标出现较大的波动时,可进行溯源分析,判断是由哪条数据发生变化所导致的

  • 数据体检

    判定系统和数据的健康情况,是否存在大量的冗余数据、无效数据、无来源数据、重复计算、系统资源浪费等问题

  • 数据评估

    通过血缘分析和元数据,可以从数据的集中度、分布、冗余度、数据热度、重要性等多角度进行评估分析,从而初步判断数据的价值

实现方案选择

经过调研,目前业界有一些优秀的框架,比如druid ,内部已经实现了大部分的解析功能,可以用来解析sql,但是它的缺点是支持mysql天衣无缝,但对hive sql却是有心无力,不能照顾到所有的语法,会导致有一部分sql不能很好的解析。

也有一些同学选择自己解析asttree来实现,但sql的语法千变万化,自己去解析难度还是很大的,尤其是一旦hive版本升级了,就得去关注新版本又更新了哪些语法,然后自己的代码也得跟进,很辛苦呀~~

我的想法是:利用hive内部解析的方法来解析sql,这样,凡是能在hive中执行的sql,都能够全面解析到字段依赖。

这个方法就要求我们 要对hive的解析过程非常了解,没关系呀,这个我完全擅长,通过对hive编译模块源码的透析,早已熟悉了各个模块在哪个数据结构里,掘地三尺,也是能把这些给挖出来的。

这个方法的主要难点就是该从什么地方切入呢,毕竟源码相关的,都是hive内部的结构,最好不要对源码做侵入性的修改。

在看源码时,发现hive 有个很牛逼的彩蛋:hive hooks 。hive hooks绑定了hive内部的工作机制,提供了使用hive扩展和集成外部功能的能力,可用于在查询处理的各个步骤中注入一些代码,而无需重新编译hive。

接下来就看该在哪个阶段注入代码了,根据钩子的类型,它可以在查询处理期间的不同点调用:

  • Pre-semantic-analyzer hooks:在Hive在查询字符串上运行语义分析器之前调用。

  • Post-semantic-analyzer hooks:在Hive在查询字符串上运行语义分析器之后调用。

  • Pre-driver-run hooks:在driver执行查询之前调用。

  • Post-driver-run hooks:在driver执行查询之后调用。

  • Pre-execution hooks:在执行引擎执行查询之前调用。

  • Post-execution hooks:在查询执行完成之后以及将结果返回给用户之前调用。

  • Failure-execution hooks:当查询执行失败时调用。

实现过程

整个实现过程比较简单,是因为发现hive的api案例中已经实现了类似的功能,我们要做的就是把这个稍做改造。

代码

研究hive hooks 的api时,发现hive已经实现了一个血缘关系的hook:

yaQjArE.jpg!web

只是这个hook 是把相关的依赖写在了 log里:

raaUbe3.png!web

下面,我们需要做一些设计,比如设计一张mysql表t_table_column_dependency来存放字段依赖的关系:

7faErui.png!web

如上,要有依赖关系的创建时间和更新时间,方便及时清理已经过期的依赖

部分写入代码如下 :

NRFRNjY.png!web

部署

添加参数

vim $HIVE_HOME/conf/hive-site.xml

aQZvYve.png!web

创建auxlib

cd $HIVE_HOME/

mkdir auxlib ## 这个目录主要存放用户自定义jar包,将编译好的jar上传至该目录

这样部署就完成了,执行hive sql会自动调用该方法,将依赖关系写入数据库,前端页面从数据库中读取信息展示

效果

测试案例:

--创建三张表

CREATE TABLE IF NOT EXISTS EXPOSURE (

session_id string COMMENT 'session_id',

kv map<string,string>

)

PARTITIONED BY (

day string

);

create table tmp_test_a (s1 string, s2 int);

create table tmp_test_b (s1 string, s2 int);


--insert语句

insert into table tmp_test_a

select

tmp.ss,

tmpb.s2

from

(

select session_id,kv['CC'] as ss from EXPOSURE where day=20190101

) tmp left join tmp_test_b tmpb on tmp.session_id=tmpb.s1

结果:

FJJzAje.png!web

总结

利用hive hooks有以下优点:

1、sql执行完后自动更新依赖关系

2、写入依赖关系模块的执行状态不会影响线上的任务,即如果依赖关系由于一些原因写入失败,不会影响线上任务的正常运行

QVBJVre.jpg!web

推荐阅读:

有关用户留存模型的一种设计方法

spark sql多维分析优化——细节是魔鬼

记录一次spark sql的优化过程

从一个sql引发的hive谓词下推的全面复盘及源码分析(上)

从一个sql引发的hive谓词下推的全面复盘及源码分析(下)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK