1. 程式人生 > 資料庫 >【原理】元資料管理原理和圖資料庫應用

【原理】元資料管理原理和圖資料庫應用

一、背景 大資料挑戰

大資料時代,餓了麼面臨資料管理、資料使用、資料問題等多重挑戰。具體可以參考下圖:

 

  • 資料問題:多種執行、儲存引擎,分鐘、小時、天級的任務排程,怎樣梳理資料的時間線變化?

  • 資料使用:任務、表、列、指標等資料,如何進行檢索、複用、清理、熱度Top計算?

  • 資料管理:怎樣對錶、列、指標等進行許可權控制、任務治理以及上下游依賴影響分析?

元資料定義與價值

元資料打通資料來源、資料倉庫、資料應用,記錄了資料從產生到消費的完整鏈路。它包含靜態的表、列、分割槽資訊(也就是MetaStore);動態的任務、表依賴對映關係;資料倉庫的模型定義、資料生命週期;以及ETL任務排程資訊、輸入輸出等。

元資料是資料管理、資料內容、資料應用的基礎。例如可以利用元資料構建任務、表、列、使用者之間的資料圖譜;構建任務DAG依賴關係,編排任務執行序列;構建任務畫像,進行任務質量治理;資料分析時,使用資料圖譜進行字典檢索;根據表名查看錶詳情,以及每張表的來源、去向,每個欄位的加工邏輯;提供個人或BU的資產管理、計算資源消耗概覽等。

開源解決方案

 

WhereHows是LinkedIn開源的元資料治理方案。Azkaban排程器抓取job執行日誌,也就是Hadoop的JobHistory,Log Parser後儲存DB,並提供REST查詢。WhereHows太重,需要部署Azkaban等排程器,以及只支援表血緣,功能侷限。

 

Atlas是Apache開源的元資料治理方案。Hook執行中採集資料(比如HiveHook),傳送Kafka,消費Kafka資料,生成Relation關係儲存圖資料庫Titan,並提供REST介面查詢功能,支援表血緣,列級支援不完善。

二、餓了麼元資料系統架構

 

  • DB儲存任務的SQL資料、任務基礎資訊、執行引擎上下文資訊;

  • Extract迴圈抽取SQL並解析成表、列級血緣Lineage;

  • DataSet包含Lineage關係資料+任務資訊+引擎上下文;

  • 將DataSet資料集儲存到Neo4j,並提供關係查詢;儲存ES,提供表、欄位等資訊檢索。

SQL埋點與採集

 

餓了麼的SQL資料,以執行中採集為主+儲存前submit為輔。因為任務的SQL可能包含一些時間變數,比如dt、hour,以及任務可能是天排程、小時排程。執行中採集SQL實時性更高,也更容易處理。

EDW是餓了麼的排程系統,類比開源的AirFlow。排程系統執行任務,並將任務相關的資訊,比如appId、jobId、owner、SQL等資訊存入DB。

計算引擎實現相關的監聽介面,比如Hive實現Execute With Hook Context介面;Spark實現Spark Listener介面;Presto實現Event Listener介面。將計算引擎相關的上下文Context、元資料MetaData、統計Statistics等資訊存入DB。

SQL解析

解析SQL的方案,以Hive為例。先定義詞法規則和語法規則檔案,然後使用Antlr實現SQL的詞法和語法解析,生成AST語法樹,遍歷AST語法樹完成後續操作。

但對於SELECT *、CTAS等操作,直接遍歷AST,不去獲取Schema資訊來檢查表名、列名,就無法判定SQL的正確性,導致資料汙染。

綜上所述,餓了麼的SQL解析方案,直接參考Hive的底層原始碼實現。

以本土做簡單示例,先經過Semantic Analyzer Factory類進行語法分析,再根據Schema生成執行計劃QueryPlan。關於表、列的血緣,可以從LineageInfo、LineageLogger類中獲得解決方案。

當然,你需要針對部分型別SQL設定Hive Conf,比如“開啟動態分割槽非嚴格模式”。對於CTAS型別,需要設定Context。UDF函式需要修改部分Hive原始碼,避免UDF Registry檢查。

 

餓了麼解析血緣的SQL支援的操作有:Query(包含select\insert into\insert overwrite)、CreateTable、CreateTableAsSelect、DropTable、CreateView、AlterView。基本覆蓋餓了麼生產環境99%+的SQL語法。

舉個栗子

舉個栗子,根據上面的SQL,分別產生表、列血緣結構。

input是表、列輸入值;output是表、列輸出值;operation代表操作型別。比如表A+B通過insert,生成表C,則延展成A insert C; B insert C。

列式也一樣:

input:name, 

operation: coalesce(name,count(id)), 

output: lineage_name;

input: id, 

output:lineage_name

表血緣結構

列血緣結構

圖儲存

有了input、operation、output關係,將input、output儲存為圖節點,operation儲存為圖邊。圖資料庫選用Gremlin+Neo4j。

Gremlin是圖語言,儲存實現方案比較多,Cypher查詢不太直觀,且只能Neo4j使用。社群版Neo4j只能單機跑,我們正在測試OrientDB。

三、餓了麼部分使用場景

下面是餓了麼在元資料應用上的部分場景:

靜態的Hive MetaStore表,比如DBS、TBLS、SDS、COLUMNS_V2、TABLE_PARAMS、PARTITIONS,儲存表、欄位、分割槽、Owner等基礎資訊,便於表、欄位的資訊檢索功能。

提供動態的表依賴血緣關係查詢。節點是表基礎資訊,節點之間的邊是Operation資訊,同時附加任務執行Id、執行時間等屬性。列血緣結構展示等同表血緣結構。

根據SQL的input、output構建表的依賴關係,進一步構建任務的DAG依賴結構。可以對任務進行DAG排程,重新編排任務執行序列。

 

Q & A

Q1:咱們的資料生命週期是如何管理的,能具體說下嗎?

A:表級資料進行熱度分析,比如近三個月沒人訪問,是否可以下線,特別是一些臨時表 需要定時清理。

 

Q2:質量監控會影響到任務排程編排麼?

A:會影響質量編排,構建DAG依賴執行。

 

Q3:把從SQL中的埋點資料儲存到MySQL中,是如何規劃的?這些埋點資訊不應該像是日誌資料一樣被處理嗎?儲存在MySQL中是有自增全域性ID的麼?還是說你們是對任務和表分別有MySQL表,然後更新MySQL表中任務和表甚至列的資訊麼?這裡的MySQL表就是您說的DataSet麼?

A:任務jobid進行唯一,MySQL只儲存執行的SQL,以及任務本身的資訊,比如owner time jobid等等。

 

Q4:當前的支援非SQL形式生成表麼?比如直接用Spark RDD任務或者Spark MLlib任務取表和生成表?

A:只支援SQL表達。

 

Q5:你們是怎麼做熱度分析的?剛才的講解裡,這個點講得比較少。

A:任務操作的SQL產生input output表,對錶進行counter就能top counter,列也一樣。

 

Q6:你們管理的表分線上表和線下表麼?在處理的時候用到了一些臨時表該怎麼處理?

A:對的,線上還是線下,任務排程系統埋點,臨時表根據temp就知道了。

 

Q7:資料血緣關係如果使用Hive hook方式獲取,是需要在每個執行節點中做捕捉嗎?

A:Hive hook就是執行時呼叫,可以去了解下底層。

 

Q8:解析那種複雜度很高的HQL的血緣,你們平臺的解析思路是什麼樣子的?如何保證正確率呢?

A:會有很多複雜的ppt有程式碼示例,會有部分SQL需要修改Hive解析實現。

 

Q9:表血緣圖裡面的上下級關係就是資料的流向?從上到下?欄位的血緣是什麼樣子的跟表的血緣有什麼不同?有欄位的血緣圖嗎?

A:ppt裡解析那裡可以看到,欄位也一樣,input output列然後operation

 

Q10:SQL埋點,引擎埋點,是要去重寫Hive等的原始碼嗎?

A:重寫倒不至於,只要實現ppt裡的介面,很簡單。