淺談數(shù)據(jù)血緣的實(shí)現(xiàn)原理
1、前言
大數(shù)據(jù)時(shí)代,數(shù)據(jù)的來源極其廣泛,各種類型的數(shù)據(jù)在快速產(chǎn)生,數(shù)據(jù)也是爆發(fā)性增長。從數(shù)據(jù)的產(chǎn)生,通過加工融合流轉(zhuǎn)產(chǎn)生新的數(shù)據(jù),到最終消亡,數(shù)據(jù)之間的關(guān)聯(lián)關(guān)系可以稱之為數(shù)據(jù)血緣關(guān)系。在數(shù)據(jù)中臺(tái)的大背景下,數(shù)倉的開發(fā)者經(jīng)常需要解決以下問題:
面對(duì)成百上千張的數(shù)據(jù)表,不知道該如何關(guān)聯(lián),也不知道這些表具有什么業(yè)務(wù)價(jià)值
執(zhí)行過長,慢的無法忍受的SQL腳本,卻不敢輕易進(jìn)行整改
數(shù)據(jù)表是否包含機(jī)密數(shù)據(jù)需要被清理,以及這些機(jī)密數(shù)據(jù)是否被轉(zhuǎn)存導(dǎo)致權(quán)限放大
其實(shí),以上的這些問題都可以統(tǒng)一歸類為數(shù)據(jù)發(fā)現(xiàn)問題。大部分企業(yè)會(huì)針對(duì)離線數(shù)倉任務(wù)進(jìn)行SQL分析,構(gòu)建表和字段的血緣關(guān)系,數(shù)據(jù)發(fā)現(xiàn)包括但不限于: 數(shù)據(jù) 表/列的業(yè)務(wù)分類分級(jí)和機(jī)密字段識(shí)別等。
2、數(shù)據(jù)血緣的基本概念
數(shù)據(jù)血緣(Data Lineage),指的是數(shù)據(jù)從產(chǎn)生、ETL處理、加工、融合、流轉(zhuǎn)到最終消亡,數(shù)據(jù)之間自然形成一種關(guān)系。這些關(guān)系就是描述數(shù)據(jù)的數(shù)據(jù)(元數(shù)據(jù))。掌握了這個(gè)元數(shù)據(jù),就能最大程度的做好數(shù)據(jù)的應(yīng)用和管理。
tips:有童鞋對(duì)元數(shù)據(jù)感興趣的,可以看這篇文章https://zhuanlan.zhihu.com/p/336504407
3、數(shù)據(jù)血緣的常見用途
業(yè)務(wù)域的劃分針對(duì)任務(wù)的表和字段,通過血緣關(guān)系可以確定表的上下游,以及對(duì)應(yīng)這個(gè)表所涵蓋的業(yè)務(wù)范圍包括哪些
提升調(diào)度性能
通過收集調(diào)度任務(wù)的開始結(jié)束時(shí)間,了解任務(wù)ETL鏈路的時(shí)間瓶頸,在根據(jù)JOB的執(zhí)行情況定位性能瓶頸,通過調(diào)整任務(wù)的基線、保證任務(wù)的資源提供,提升整條ETL鏈路的執(zhí)行效率。
數(shù)據(jù)異常定位
若在某天的調(diào)度中,發(fā)現(xiàn)數(shù)據(jù)異常,想確認(rèn)是什么造成,可根據(jù)DQC和血緣關(guān)系了解底層數(shù)據(jù)波動(dòng)情況,快速定位原因。
數(shù)倉鏈路優(yōu)化通過對(duì)表和字段的下游使用頻次,找到使用較多的,分析其是否有重復(fù)計(jì)算、浪費(fèi)資源的情況。再判斷是否可以因此建設(shè)事實(shí)或維度表、或者把計(jì)算的指標(biāo)或維度沉淀。
調(diào)度依賴的準(zhǔn)確性判斷
在平時(shí)的開發(fā)過程中,很可能修改過SQL,但是忘記在調(diào)度平臺(tái)上配置相對(duì)應(yīng)的依賴,這樣很可能會(huì)出現(xiàn)問題,其實(shí)通過調(diào)度平臺(tái)的調(diào)度關(guān)系的元數(shù)據(jù),和收集到的血緣關(guān)系進(jìn)行對(duì)比,可定時(shí)性的判斷調(diào)度任務(wù)依賴是否準(zhǔn)確。
4、數(shù)據(jù)血緣的實(shí)現(xiàn)原理(表級(jí)別)
本文只闡述最基本的表級(jí)別的血緣關(guān)系的實(shí)現(xiàn)思路,真實(shí)的血緣實(shí)現(xiàn),遠(yuǎn)比文章中的場景復(fù)雜。
原理一 SQL解析之正則表達(dá)式
在最開始時(shí),剛畢業(yè)的小白,如果讓你做好數(shù)倉的血緣元數(shù)據(jù)時(shí),你會(huì)怎么做?
在初期的小白根本就不懂編譯器、語法分析、詞法分析以及AST這些概念時(shí),想到的唯一辦法就是通過正則這個(gè)樸素的手段去解析SQL了,想法也非常直接,F(xiàn)ROM或者JOIN后面就是源表,INSERT INTO/INSERT OVERWRITE TABLE后面就是目標(biāo)表。
不過,若是我們的SQL是這樣的呢?
或者是這樣的:
你會(huì)發(fā)現(xiàn),這個(gè)思路有很多漏洞。事實(shí)上如果加上一些if-else的判斷,這個(gè)方案其實(shí)也滿足了大部分場景。但是!!??!身為開發(fā)人員一定要明白一個(gè)理念,當(dāng)你在生產(chǎn)環(huán)境中只要有一個(gè)場景沒有滿足,那就是bug。
原理二 AST語法樹的解析
首先針對(duì)思路二,大家可以提前了解AST的概念,參考https://blog.csdn.net/u013212754/article/details/106981084
其次在了解思路二前提下,需要知道Hive SQL的執(zhí)行過程(畢竟還是看的HQL的語法樹)以及一些名詞解釋。
- 名詞解釋
詞法分析器:詞法分析器的工作是分析量化那些本來毫無意義的字符流,將他們翻譯成離散的字符組(也就是一個(gè)一個(gè)的Token),供語法分析器使用。簡單說就是分析sql里每個(gè)單詞該怎么組成。
語法分析:語法分析器將把收到的Tokens組織起來,并轉(zhuǎn)換成語法規(guī)則定義的所允許的結(jié)構(gòu)。簡單說就是研究這些單詞該以怎樣的結(jié)構(gòu)組成一個(gè)SQL的。
Antlr:ANTLR (ANother Tool for Language Recognition ) 是一種語言識(shí)別工具,它提供了一個(gè)框架,可以通過包含 Java, C++, 或 C# 動(dòng)作(action)的語法描述來構(gòu)造語言識(shí)別器,編譯器和解釋器。
- Hive SQL的解析流程:
Hive根據(jù)Antlr定義的詞法、語法規(guī)則完成詞法、語法分析將HQL解析為AST Tree;
遍歷AST Tree,抽象出查詢的基本組成單元Query Block;
遍歷Query Block解析為操作樹Operator Tree(即,邏輯執(zhí)行計(jì)劃);
邏輯優(yōu)化器進(jìn)行操作樹變換,合并多余的ReduceSinkOperator,減少shuffle;
遍歷Operator Tree,將操作樹翻譯為對(duì)應(yīng)的MapReduce任務(wù);
物理優(yōu)化器進(jìn)行MapReduce任務(wù)變換,生成最終的執(zhí)行計(jì)劃。
具體步驟:
- 對(duì)Hive SQL進(jìn)行詞法分析和語法分析,獲取對(duì)應(yīng)的AST 原始的抽象語法樹
- AST語法樹剪枝優(yōu)化,減少遍歷次數(shù),提高語義解析的效率,具體主要做兩方面的優(yōu)化:
針對(duì)token中涉及到的無效解析節(jié)點(diǎn)進(jìn)行刪除,如order by,distributedby,cluster by,sort by以及l(fā)imit;
針對(duì)token中where/having的子查詢,在保證SQL語法正確性以及語義完整性的前提下,采用1=1 等價(jià)策略進(jìn)行等價(jià)替換,降低了血緣關(guān)系解析的復(fù)雜性;通過以上兩種剪枝操作,既可以減少SQL語句的復(fù)雜性,又可以降低AST語法樹的層級(jí),進(jìn)一步減少了遍歷AST樹遞歸次數(shù),降低血緣分析的復(fù)雜性,提高了語句解析效率。
遍歷AST獲取上游表名和下游表名,在SQL語句中存在大部分SQL語句片段即CTE。由于其在血緣關(guān)系解析中不起關(guān)鍵作用,且對(duì)SQL解析帶來很大困擾,因此血緣關(guān)系解析需對(duì)CTE類型進(jìn)行識(shí)別,并進(jìn)行替換與刪除。
5、總結(jié)
市面上其實(shí)針對(duì)數(shù)據(jù)血緣的產(chǎn)品有很多,像阿里DataWorks的數(shù)據(jù)地圖、字節(jié)的DataLeap以及非?;鸬拈_源產(chǎn)品Apache Atlas都是非常好用工具產(chǎn)品。但是本質(zhì)上是想通過這篇文章,讓小伙伴們?cè)谑褂眠@些產(chǎn)品的時(shí)候多去思考這些產(chǎn)品背后的實(shí)現(xiàn)原理。