火山引擎DataLeap資料血緣技術建設實踐

陶然陶然發表於2023-03-31

   經驗一:資料血緣模型的分層架構

  1. 挑戰

  首先介紹一下位元組內部資料血緣遇到的挑戰。

  隨著公司業務擴張、使用者數量持續增長以及數倉建設不斷完善,後設資料種類和數量也經歷了非線性增長,並在此期間湧現出一些問題。

  第一,擴充套件性。好的擴充套件性可以在面對新型後設資料血緣時保證快速接入和迭代,而擴充套件性不佳則會導致在業務變化時需要不停地重構來適應業務,對業務造成很多影響。

  第二,效能。一個模型本身的插入和更新效率會直接影響資料的匯入匯出的流程,這些都會帶來更直觀的業務上的感受,所以需要考慮如何保證環節高效性。

  第三,時效性。很多應用場景對正確率格外敏感,如果血緣資料有延遲,其實就等於血緣的不準確,會對業務造成影響。

  最後,賦能業務。技術服務於業務,業務增長會幫助技術升級迭代,技術創新也會促進業務發展。在位元組內部,我們會根據業務特點,考慮業務需要,將技術成本與業務收益做平衡,最終做出資料模型決策。總而言之,資料模型沒有完美的方案,只有最適合企業自身業務、適合當前階段的資料血緣方案。

  2. 資料血緣模型 - 展示層

  位元組內部有很多種後設資料型別,包括線上傳統的離線數倉 Hive、OLAP 分析引擎 ClickHouse,以及實時側後設資料,如 Kafka 和 ES 以及 Redis。這些後設資料所對應的表/Topic 都統一維護在後設資料平臺上,目前血緣展示層是以這些資料資產作為主視角。

  如下圖所示,中心資料資產包含普通欄位和分割槽欄位等資訊,還可以從圖中看到中心資產上下游資產資訊。圖中資產和資產之間連線的邊,代表的是生產關係:1個任務讀取了上游的資產,產生了下游的資產。  

  3. 資料血緣模型 - 抽象層

  接下來介紹,火山引擎 DataLeap 如何設計抽象層。

  抽象層是整個資料血緣的資料模型,主要包含兩種節點,一種是資產節點,另外一種是任務節點。

  在圖中,資產節點用圓形表示,任務節點用菱形表示。具體舉個例子:

  一個 FlinkSQL 任務消費了 Kafka 的 topic,然後寫入到一個 Hive 的表裡,那麼 Kafka 的 topic 和 hive 表就是表資產節點,而 FlinkSQL 消費任務就是中間的任務節點。

  一個 Kafka 的 topic 裡面可能會定義自己的 schema,包括多個欄位,例如 schema 裡包含欄位 a、b、c,透過 FlinkSQL 任務,比如一個 SQL:insert into hiveTable select a,b,c from kafka Topic,透過進行這樣的處理,欄位 a、b、c 和這個 hive 的欄位 d 就產生了血緣關係。

  建立子任務的節點,把幾個欄位節點連線起來,每個子任務節點會和子任務節點透過從屬關係的邊來進行連線,欄位節點和每一個表資產節點也會透過從屬關係的邊進行連線。本身這個任務和資產之間會有消費生產關係的邊連線。

  以上就是整個血緣資料模型在抽象層的展現。

  這樣設計有以下好處:

  首先,任務資產的抽象是對生產平臺上和在各種任務平臺上廣泛直接的任務關係的抽象,當再去接入新後設資料或新任務型別時,我們只需要擴充套件當前抽象的資產節點和任務節點,即可把新加入進來的任務鏈路所對應的血緣接入到儲存中。這種資料模型也能方便地更新和刪除血緣鏈路,維持時效性。

  其次,在位元組內部的血緣建設中,還存在接入各種血緣鏈路的難點。基於目前設計可以減少開發成本,在更新血緣的時只需要更新中心任務節點,並且把中心任務節點所對應的子任務節點的邊也做相應的更新和刪除,就完成了血緣資訊的插入和更新。  

  4. 資料血緣模型 - 實現層

  在實現層,火山引擎 DataLeap 主要基於 Apache Atlas 來實現。Apache Atlas 本身也是一個資料治理的產品,它預定義了一些後設資料的型別,整個型別系統有比較好的擴充套件性。在 Atlas 本身的 DataSet 和 Process 後設資料定義上,我們引入了位元組內部獨有的業務後設資料的屬性和子任務定義,最終把任務相關的後設資料儲存起來。

  Atlas 本身也支援血緣的查詢能力,透過 Apache Atlas 暴露的介面來轉換成圖上查詢某個節點對應血緣關係的邊,以此實現血緣查詢。  

  5. 資料血緣模型 - 儲存層

  在儲存層,目前主要基於 Apache Atlas 原生圖資料庫——JanusGraph。JanusGraph 底層支援 HBase。我們將每條邊的關係作為兩邊的資產節點的屬性,存入到對應 RowKey 的獨立 cell 中。

  另外,我們也對儲存做了相關的改造,如位元組內部自研的存算分離 key-value 儲存。我們也在獨立環境中會做輕量級部署,同時基於效能或成本,以及部署複雜度,把儲存切換為 OLTP 資料庫,比如 MYSQL 資料庫。  

  以上就是整個資料血緣模型的設計部分。透過這樣的資料血緣模型,我們可以減少新的資料血緣鏈路接入開發成本,同時也很方便更新和刪除血緣。

   經驗二:三個資料血緣最佳化方向

  第二部分將主要介紹在火山引擎 DataLeap 中典型的資料血緣最佳化,包括實時資料血緣更新最佳化、血緣查詢最佳化和血緣資料開放式匯出。

  1.實時資料血緣最佳化

  首先,實時資料血緣的更新。位元組內部現在資料血緣的更新方式是透過 T+1 的鏈路和實時鏈路來更新。由於內部有很多場景對時效性的要求特別高,如果資料血緣更新不太及時,就會影響血緣準確率,甚至影響業務使用。

  在資料血緣的架構設計之初就已經支援了 T+1 的匯入,不過時效性始終是按天為週期的。

  資料血緣任務週期性的拉取所有在執行任務的配置資訊,呼叫平臺的API拉取對應任務相關的配置或者 SQL

  對於 SQL 型別的任務會呼叫另外一個解析引擎服務提供的解析能力來去解析資料血緣的資訊

  再和後設資料平臺登記的資產資訊相匹配,最後構建出一個任務資產節點的上下游,把這個任務資產節點和表資產節點之間的邊更新到圖資料庫中去。

  在實時更新的時候,我們有兩種方案:

  方案一:是在引擎側,即在任務執行時,透過任務執行引擎把該任務在構建 DAG 後生成的血緣資訊透過 Hook 送入。

  優點:在引擎側的血緣採集是相對獨立的,每個引擎在採集血緣的時候不會互相影響。

  缺點:

  每個引擎都需要適配一個血緣採集的 Hook,一些中小企業在引擎側都可能面臨的一個問題是同一個引擎可能線上上執行會有多個版本,那麼適配的成本就會比較高,需要每個版本都適配一次。

  Hook 還有一定的侵入性,會對本身的作業有一定的負擔。

  方案二:在任務開發的平臺上把這個任務變更的訊息送出,當任務的生命週期變化的時候,透過 Hook 訊息把任務狀態變更訊息透過呼叫API進行登記或者傳送到 MQ 進行解耦,血緣服務收到這份通知之後,再主動呼叫解析服務來更新這個任務血緣。

  優點:擴充套件性好,不會受到引擎側限制,未來要接入新的引擎時,只需要在這個任務平臺上去建立對應的任務,把這個任務變更的訊息送出,就可以得到這個血緣更新的通知,然後去更新血緣。

  缺點:對血緣解析服務平臺會有一定的改造成本,任務間的訊息可能會互相影響

  綜合比較,我們採用了第二種方案,並且引入了 MQ 進一步的降低任務平臺和血緣平臺的耦合,這種做法可能犧牲了部分的延遲,但是會讓整個鏈路變得更加可靠,最終減低了血緣這邊整體的延遲,時間週期從天減低到了分鐘級別。

  以上就是我們在血緣時效性上的最佳化。  

  2.資料查詢最佳化

  第二個最佳化點是查詢。目前位元組資料血緣查詢依賴 Apache Atlas。在使用該血緣查詢服務時,有一個很普遍的場景,就是多節點查詢的場景。在影響分析的過程中,我們經常會查詢一張表的全部欄位血緣,會轉化成查詢多個節點的血緣上下游關係,需要解決查詢效率的問題。

  有兩種基本的解決方案:

  一種是直接在應用層進行封裝,對 Apache Atlas 血緣服務的暴露層新增一個介面,比如透過迴圈遍歷去執行單個查詢,這樣改造的內容是很少的,但是其實效能並沒有提升,而且實現比較暴力。

  另外一種方式是改造 Apache Atlas 血緣服務對相簿查詢的呼叫。因為 Atlas 使用 JanusGraph 作為底層的實現,提供了一部分的抽象,但是隻暴露了單節點的查詢,而沒有批次查詢的方法,我們還需要適配 JanusGraph 這邊批次查詢的介面,才可以達到提速的效果。

  所以我們在圖資料庫的操作入口增加了一個新的批次查詢的方法,透過這種方式對血緣節點進行批次查詢,來進一步提升效能。同時 Atlas 在查詢血緣節點回來之後,需要進行一個對映,對映到具體的實體上去拿回它的一些屬性,在這個過程中我們也加入了非同步批次的操作方式來進一步的提升效能。經過最佳化之後,我們在對一些引用熱度比較高的表資產節點或者查詢表資產或者對應列的時候,效率都可以得到明顯提升。  

  3.血緣資料開放式匯出

  第三個最佳化點是在血緣的匯出上提供了多種方式,除了在頁面上視覺化的查詢血緣的能力之上,我們也陸續提供了很多使用血緣的方式,包括下載到 Excel 或者查詢這個血緣資料匯出的數倉表,或者直接使用服務平臺側開放的 API,還可以訂閱血緣變更的 topic,來直接監聽血緣的變更,下游的使用者可以根據自己的開發場景,以及業務對準確率、覆蓋率的要求,來決定到底使用哪種方式來消費血緣資料。  

   經驗三:四大資料血緣用例解析

  接下來第三部分主要介紹資料血緣的具體用例,介紹位元組內部是如何使用資料血緣的。在位元組內部資料血緣用例的典型使用領域主要包括:資產領域、開發領域、治理領域和安全領域。

  1.資料血緣用例 – 資產領域

  首先在資產領域,資料血緣主要應用在資產熱度的計算。在資產熱度計算時,有些資產會被頻繁消費和廣泛引用。某個資產被眾多下游引用,是其自身權威性的體現,而這種權威性的證明需要一種定量的度量,因此需要引入“資產熱度”的概念。資產熱度本身是參考網頁排名演算法 PageRank 演算法實現的,同時我們也提供了資產熱度值,根據資產的下游血緣依賴的情況,定義了資產引用的熱度值,如果某個資產引用熱度值越高,就代表了這個資產更應該被信任,資料更可靠。

  另外,血緣也可以幫助我們理解資料。比如使用者在後設資料平臺或者血緣平臺上查詢資料資產節點的時候,可能是想要進行下一步的作業開發或者是排查一些問題,那麼他就需要首先找到這個資料資產。使用者不瞭解資料產生的過程,就無法瞭解資料的過去和未來。也就是哲學上經典的問題:這個表到底是怎麼來的?它具體有哪些含義?我們就可以透過資料血緣來找到具體表的上下游資訊。  

  2.資料血緣用例 – 開發領域

  資料血緣的第二個用例是開發領域。在開發領域中會有兩個應用:影響分析和歸因分析。

  影響分析應用

  影響分析即事前分析,指當表資產產生變更時,能夠事前感知影響。血緣上游的資產負責人在修改對應的生產任務時,需要透過血緣檢視資產下游,由此判斷資產修改產生的影響,從而針對修改的相容性或者某條鏈路的重要性,完成通知等操作,否則會因為缺少通知而造成嚴重的生產事故。

  歸因分析應用

  歸因分析應用是事後分析。比如當某個任務所產生的表出現了問題,我們就可以透過查詢血緣的上游,逐級尋找到血緣上游改動的任務節點或者資產節點來排查出造成問題的根因是什麼。在發現和定位出了問題之後,我們會去修復資料,在修復資料的時候,我們可以透過血緣來查詢任務或者表的依賴關係,對於離線數倉可能就需要重跑某個分割槽的輸出資料,我們需要根據血緣來劃定範圍,只需要回溯對應受影響的下游任務就可以了,減少一些不必要的資源浪費。  

  3.資料血緣用例 – 治理領域

  在治理領域應用中,血緣關係在位元組內部也有典型的使用場景:鏈路狀態追蹤和數倉治理。

  鏈路狀態追蹤

  比如在重要的節日或者活動的時候,我們需要事先挑選一些需要重要保障的任務,這時就需要透過血緣關係來梳理出鏈路的主幹,即核心鏈路。然後去對應的做重點的治理和保障,比如簽署 SLA。

  數倉治理

  資料血緣也會用來輔助數倉建設,如規範化治理。數倉規範化治理包括清理數倉分層不合理的引用、數倉分層不規範、冗餘表等。例如,來自同一個上游表,但屬於不同層級的兩個表,屬於冗餘,將透過資料血緣輔助清理。  

  4.資料血緣用例 – 安全領域

  安全相關問題在一些跨國企業或國際化產品會比較常見,每個國家地區的安全政策是不一樣的。我們在做安全合規檢查時,每個資產都有對應的資產安全等級,這個資產安全等級會有一定的規則,比如我們規定下游資產的安全等級一定要高於上游的安全資產等級,否則就會有許可權洩露問題或者是其他的安全問題。基於血緣,我們可以掃描到這些規則涉及的資產下游,來配置相應掃描規則,然後進行安全合規排查,以便做出對應的治理。

  另外,血緣在標籤傳播方面也有所應用,可以透過血緣的傳播鏈路來進行自動化工作,比如對資產進行安全標籤打標的時候,人工的打標方式會相對比較繁瑣而且需要關注鏈路的資訊,那麼就可以藉助血緣資訊來完成自動的打標,比如配置一些規則讓安全標籤明確場景、節點和終止規則。  

  以上這些都是資料血緣在位元組內部的一些典型用例,我們也在探索更多的使用場景。

  根據其對血緣質量的要求,這些場景被分成了幾個區域。根據血緣覆蓋率、血緣準確率的要求,可以分為四個象限,比如其中一類是需要覆蓋全鏈路且血緣準確率要求異常高的,例如開發項的兩個用例,因為在開發項的用例中,血緣的延遲會嚴重影響決策上的判斷,對血緣質量要求是最高的。

  血緣建設過程也會劃分不同的建設時期,我們可以根據現在要支援的業務場景和業務優先順序來輔助制定血緣建設規劃,決定血緣迭代的節奏和具體方向。  

   未來展望

  1.資料血緣技術趨勢

  在業界,血緣的發展趨勢主要關注以下幾點:

  通用的血緣解析能力

  血緣是後設資料平臺的核心能力,很多時候後設資料平臺會接入多樣化後設資料,這些業務後設資料也會依賴血緣不同的血緣解析能力,現在的解析往往是依賴各個引擎團隊來支援的,但是其實在更加廣泛的場景,我們需要有一個兜底的方案來提供一個更通用的血緣解析能力,所以未來我們會提供標準 SQL 解析引擎,以達到通用解析的目的。

  非侵入式的非 SQL 型別血緣採集

  除了可解析的 SQL 或可配置的任務,日常還會涉及到程式碼型別的任務,如 JAR 任務。JAR 任務現在的解析方式是根據一些埋點資訊或者使用者錄入的上下游資訊去完成血緣的收集,這部分未來會出現一種非侵入式的非 SQL 型別血緣採集的技術,比如 Flink 或者 Spark 的 JAR 任務,我們可以在任務執行時拿到這些血緣,來豐富平臺側血緣的資料。

  時序血緣

  時序血緣也是位元組內部的考慮點。目前血緣資訊圖資料庫相當於是對當前血緣拓撲的一次快照,其實血緣是會變化的,比如使用者在修改一個任務的時候,上線任務變更或是修改表結構,然後對應的修改自己生產任務,這裡涉及到時序的概念,這個時序可以方便我們去追溯一些任務的變化,支援我們去做事前事後影響分析,所以時序血緣如何在圖資料庫中引入也是未來的一個趨勢。

  2.資料血緣的應用趨勢

  標準化

  前文提到很多應用場景的底層能力都是透過介面來獲得,獲得介面的資料也涉及到應用的標準化,標準化的應用可以讓我們移植到更多的業務上,提供更好的血緣資料分析幫助。

  端到端的血緣打通

  另一個應用趨勢是端到端的血緣能力,現在平臺主要接入資產節點,端到端則會涉及到更上游,如 App 端和 Web 端採集的資料,或者是下游報表,以及 API 之後最終的節點。在血緣收集中,這部分資訊目前缺失,端到端血緣打通將是未來應用上的趨勢之一。

  3. 雲上的全鏈路血緣能力

  在位元組跳動內部,血緣能力會進行上雲,雲上涉及各類資料型別,因此血緣發展方向之一是把各類異構資料型別統一接入,並且支援雲上使用者來自定義接入新型別血緣。

  同時,當資料應用標準化之後,也可以把血緣應用提供給雲上使用者,雲上使用者也可以反向加入到血緣應用的開發中,最後把資料血緣模型作為一種標準來推廣,由此衍生出更好的血緣應用、血緣服務生態。

來自 “ 位元組跳動技術團隊 ”, 原文作者:彭洪劍;原文連結:http://server.it168.com/a2023/0331/6796/000006796976.shtml,如有侵權,請聯絡管理員刪除。

相關文章