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