日常工作中,資料開發上線完一個任務後並不是就可以高枕無憂,時常因上游鏈路資料異常或者自身處理邏輯的 BUG 導致產出的資料結果不可信。而問題發現可經歷較長週期(尤其離線場景),往往是業務方透過上層資料包表發現資料異常後 push 資料方去定位問題(對於一個較冷的報表,這個週期可能會更長)。
由於資料加工鏈路較長,需藉助資料血緣關係逐個任務排查,也會導致問題定位難度增大,嚴重影響開發效率。如資料問題未及時發現,可能導致業務方作出錯誤決策。此類問題可統一歸屬為大資料領域資料質量問題。本文將向大家介紹伴魚基礎架構資料團隊在應對該類問題時推出的平臺化產品-資料質量中心的設計與實現。
1 調研
業內資料質量平臺化產品介紹不多,主要對兩個開源產品和一個雲平臺產品進行調研。
1.1 Apache Griffin
Apache Griffin,eBay 開源基於 Apache Hadoop 和 Apache Spark 的資料質量服務平臺。
1.1.1 架構圖
資料質量平臺的核心流程:
- Define:資料質檢規則(指標)的定義
- Measure:資料質檢任務的執行,基於 Spark 引擎實現
- Analyze:資料質檢結果量化及視覺化展示
平臺對資料質檢規則進行了分類(業內普遍認可的資料質量的六大標準):
- Accuracy:準確性。如是否符合表的加工邏輯
- Completeness:完備性。如資料是否存在丟失
- Timeliness:及時性。如表資料是否按時產生
- Uniqueness:唯一性。如主鍵欄位是否唯一
- Validity:合規性。如欄位長度是否合規、列舉值集合是否合規
- Consistency:一致性。如表與表之間在某些欄位上是否存在矛盾
該專案僅在 Accuracy 類的規則上實現。Griffin是完全閉環的平臺化產品。質檢任務執行依賴內建定時排程器的排程,排程執行時間由使用者在 UI 上設定。任務將透過 Apache Livy 元件提交至配置的 Spark 叢集。即質檢實時性難保,無法強行阻斷產出異常資料的任務,二者不是在同一排程平臺被排程,時序也不能保持序列。
1.2 Qualitis
Qualitis,微眾銀行開源的一款資料質量管理系統。同樣,它提供了一整套統一的流程來定義和檢測資料集的質量並及時報告問題。從整個流程上看我們依然可以用 Define、Measure 和 Analyze 描述。它是基於其開源的另一款元件 Linkis 進行計算任務的代理分發,底層依賴 Spark 引擎,同時可以與其開源的 DataSphereStudio 任務開發平臺無縫銜接,也就實現了在任務執行的工作流中嵌入質檢任務,滿足質檢時效性的要求。可見,Qualitis 需藉助微眾銀行開源一系列產品才好用。
1.3 DataWorks 資料質量
DataWorks,阿里雲提供一站式大資料工場,包括資料質量在內的產品解決方案。實現依賴阿里雲其他產品元件支援。DataWorks 資料質量部分的使用介紹從產品形態上給了我們很大的幫助,對我們產品設計有指導性作用。
2 設計目標
- 暫只支援離線部分資料質量管理
- 支援通用規則描述和規則管理
- 質檢任務由公司內部統一的排程引擎排程執行,可支援對質檢結果異常的任務進行強阻斷。同時,儘量降低質檢功能對排程引擎的程式碼侵入
- 支援質檢結果視覺化
3 系統設計
3.1 背景
離線排程開發平臺基於 Apache Dolphinscheduler(簡稱DS)實現,分散式去中心化,易擴充套件的視覺化 DAG 排程系統,支援包括 Shell、Python、Spark、Flink 等多種型別的 Task 任務,並具有很好的擴充套件性。
3.2 架構
Master 節點負責任務的監聽和排程,Worker 節點則負責任務的執行。值得注意的是,每一個需要被排程的任務必然需要設定一個排程時間的表示式(cron 表示式),由 Quartz 定時為任務生成待執行的 DAG Command,有且僅有一個 Master 節點獲得執行權,掌管該 DAG 各任務節點的排程執行。
3.3 整體架構
平臺整體架構圖:
- DQC Web UI:質檢規則等前端操作頁
- DQC(GO):簡單的實體後設資料管理後臺。主要包括:規則、規則模板、質檢任務和質檢結果幾個實體。
- DS(資料質量部分):質檢任務依賴 DS 排程執行,需要對 DS 進行一定的改造。
- DQC SDK(JAR):DS 排程執行任務時,檢測到任務繫結了質檢規則,將生成一類新的任務 DQC Task (與 DS 中其他型別的 Task 同級,DS 對於 TasK 進行了很好的抽象可以方便擴充套件),本質上該 Task 將以指令碼形式呼叫執行 DQC SDK 的邏輯。DQC SDK 涵蓋了規則解析、執行的全部邏輯。
各模組設計權衡。
4 規則表述
4.1 標準與規則
業界資料質量有六大標準,但:
- 如何將標準與平臺的規則對應起來?
- 標準中涉及到的現實場景是否我們可以一一列舉?
- 即便可將標準一一細化,資料開發人員是否可輕鬆理解?
可將這些問題統一歸類為:平臺在規則設定上是否需要和業界資料質量標準所抽象出來的概念進行繫結。很遺憾沒找到有關資料質量標準更細化和指導性的描述,作為一個開發,這些概念比較費解,更貼近程式設計師視角是「show me the code」,因此我們決定將這一層概念弱化。未來實踐過程後再細思。
4.1.1 標量化
如何對規則提供一種通用描述(or DSL)?
跳脫出前文所描述一切背景和概念,仔細思考資料質檢過程,本質就是透過一次真實的任務執行產出結果,對比輸出結果與期望是否滿足,以驗證任務邏輯正確性。和 Unit Testing 類比:
- Unit Testing 是透過模擬資料構造的一次程式碼邏輯的執行
- 資料任務執行產生的結果是一張二維結構的 Hive 表,需加工才能獲取想要的統計結果
據此,可用 Unit Testing 概念從以下深入:
① Actual Value
資料任務執行產出結果是一張 Hive 表,要對這張 Hive 表資料加工、提取以獲得需要Actual Value。涉及 Hive 表加工,就想到以 SQL 實現,透過 Query 和 一系列 Aggregation 拿到結果,此結果結構又可分為:
- 二維陣列
- 單行或單列的一維陣列
- 單行且單列的標量
顯然單行且單列標量是期望,因為易於結果比較(就目前能想到的規則,都可透過 SQL 提取為一個標量結果)。因此,規則設計中,需要規則建立者輸入一段用於結果提取的 SQL,該段 SQL 執行結果需要為一個標量。
② Expected Value
既然 Actual Value 是標量,Expected Value 也是標量,需要規則建立者在平臺輸入。
③ Assert
上述標量的型別決定斷言比較方式。目前只支援數值型標量的比較方式,包含「大於」、「等於」及「小於」三種比較運算元。
三要素即可完整的描述規則想要表達的核心邏輯。如表述「欄位為空異常」規則(潛在含義:欄位為空的行數大於 0 時判定異常):
- Actual Value :出現欄位為空的行數
- Expected Value:0
- Assert: 「大於」
4.2 規則管理
4.2.1 規則模板
為了規則複用抽象出的一個概念,模板中包含規則的 SQL 定義、規則的比較方式、引數定義(注:SQL 中包含一些佔位符,這些佔位符將以引數的形式被定義,在規則實體定義時需要使用者明確具體含義)以及其他的一些元資訊。
「欄位空值的行數」模板示例:
4.2.2 規則實體
基於規則模板構建,是規則的具象表達。
在規則實體中將明確規則的 Expected Value、比較方式中具體的比較運算元、引數的含義以及其他的一些元資訊。基於同一個規則模板,可構造多個規則實體。
「某表 user_id 唯一性校驗」規則示例:
規則可能不僅針對單表校驗,多表case,這套規則模板同樣適用,只要能將邏輯用 SQL 表達。
4.3 規則繫結
在 DS 的前端互動上支援為任務直接繫結校驗規則,規則列表透過 API 從 DQC 獲取,這種方式在使用者的使用體驗上存在一定的割裂(規則建立和繫結在兩個平臺完成)。同時,在 DQC 的前端亦可以直接設定關聯排程,為已有任務繫結質檢規則,任務列表透過 API 從 DS 獲取。同一個任務可繫結多個質檢規則,這些資訊將儲存至 DS 的 DAG 元資訊中。但是:
- 規則的哪些資訊應該儲存至 DAG 的元資訊中?
- 規則的更新 DAG 元資訊是否可實時同步?
主要有兩種方式:
- 大JSON將規則資訊打包儲存,計算時解析 JSON 逐個執行校驗。在規則更新時,需要同步呼叫修改 JSON 資訊
- List 儲存規則 ID,計算時需執行一次 Pull 操作獲取規則具體資訊然後執行校驗。規則更新,無須同步更新 List 資訊
最終選型後者,ID List可使對 DS 侵入最低。
4.4 規則執行
強規則和弱規則
規則的強弱性質由使用者為任務繫結規則時設定,此性質決定了規則執行的方式。
強規則
和當前所執行的任務節點同步執行,一旦規則檢測失敗整個任務節點將置為執行失敗的狀態,後續任務節點的執行會被阻斷。對應 DS 中的執行過程:
- Step1:某一個 Master 節點獲取 DAG 的執行權,將 DAG 拆分成不同的 Job Task 先後下發給 Worker 節點執行。
- Step2:執行 Job Task 邏輯,並設定 Job Task 的 ExitStatusCode。
- Step3:判斷 Job Task 是否繫結了強規則。若是,則生成 DQC Task 並觸發執行,最後根據執行結果修正 Job Task 的 ExitStatusCode。
- Step4:Master 節點根據 Job Task 的 ExitStatusCode 判定任務是否成功執行,繼續進入後續的排程邏輯。
弱規則
和當前所執行的任務節點非同步執行,規則檢測結果對於原有的任務執行狀態無影響,從而也就不能阻斷後續任務的執行。對應 DS 中的執行過程:
- Step1:某一個 Master 節點獲取 DAG 的執行權,將 DAG 拆分成不同的 Job Task 先後下發給 Worker 節點執行。
- Step2:執行 Job Task 邏輯,並設定 Job Task 的 ExitStatusCode。
- Step3:判斷 Job Task 是否繫結了弱規則。若是,則在 Job Task 的 Context 中設定弱規則的標記 。
- Step4:Master 節點根據 Job Task 的 ExitStatusCode 判定任務是否成功執行,若成功執行再判定是否 Context 中帶有弱規則標記,若有則生成一個新的 DAG(有且僅有一個 DQC Task,且新生成的 DAG 與 當前執行的 DAG 沒有任何的關聯) 然後繼續進入後續的排程邏輯。
- Step5:各 Master 節點競爭新生成的 DAG 的執行權。
可以看出在強弱規則的執行方式上,對 DS 排程部分的程式碼有一定的侵入,但這個改動不大,成本是可以接受的。
DQC Task & DQC SDK
上文提及到一個 Job Task 繫結的規則(可能有多個)將被轉換為一個 DQC Task 被 DS 排程執行,接下來我們就討論下 DQC Task 的實現細節以及由此引出的 DQC SDK 的設計和實現。
DQC Task 繼承自 DS 中的抽象類 AbstractTask,只需要實現抽象方法 handle(任務執行的具體實現)即可。那麼對於我們的質檢任務,實際上執行邏輯可以拆分成以下幾步:
- 提取 Job Task 繫結的待執行的 Rule ID List。
- 拉取各個 Rule ID 對應的詳情資訊。
- 構建完整的執行 Query 語句(將規則引數填充至模板 SQL 中)。
- 執行 Query。
- 執行 Asset。
最核心的步驟為 Query 的執行。Query 的實現方式又可分為兩種:
Spark 實現
- 優點:實現可控,靈活性更高。
- 缺點:配置性要求較高。
Presto SQL 實現
- 優點:不需要額外配置,開發量少,拼接 SQL 即可。
- 缺點:速度沒有 Spark 快。
選擇後者,最易實現,離線場景計算耗時也可接受。同時由於一個 DQC Task 包含多條規則,在拼接 SQL 時將同表的規則聚合以減少 IO 次數。不同的 SQL 交由不同的執行緒並行執行。
上述執行邏輯其實是一個完整且閉環的功能模組,因此我們想到將其作為一個單獨的 SDK 對外提供,並以 Jar 包的形式被 DS 依賴,後續即便是更換排程引擎,這部分的邏輯可直接遷移使用(當然機率很低)。那麼 DS 中 DQC Task 的 handle 邏輯也就變得異常簡單,直接以 Shell 形式呼叫 SDK ,進一步降低對 DS 程式碼的侵入。
4.5 執行結果
單條規則的質檢結果將在平臺上直接展現,目前我們還未對任務級的規則進行聚合彙總,這是接下來需要完善的。對於質檢失敗的任務將向報警接收人傳送報警。
實踐中的問題
平臺解決了規則建立、規則執行的問題,而在實踐過程中,對使用者而言更關心:
- 一個任務應該需要涵蓋哪些的規則才能有效地保證資料的質量?
- 我們不可能對全部的表和欄位都新增規則,那麼到底哪些是需要新增的?
這些是很難透過平臺自動實現的,因為平臺理解不了業務的資訊,平臺能做的只能是透過質量檢測報告給與使用者反饋。因此這個事情需要具體的開發人員對核心場景進行梳理,在充分理解業務場景後根據實際情況進行設定。話又說回來,平臺只是工具,每一個資料開發人員應當提升保證資料質量的意識,這又涉及到組織內規範落地的問題了。
5 規劃
資料質量管理是一個長期的過程,未來在平臺化方向我們還有幾個關鍵的部分有待繼續推進:
- 基於血緣關係建立全鏈路的資料質量監控。當前的監控粒度是任務級的,如果規則設定的是弱規則,下游對於資料問題依舊很難感知
- 資料質量的結果量化。需建立一套指標用於定量衡量資料質量
- 支援實時資料的質量檢測
關注我,緊跟本系列專欄文章,我們們下篇再續!
作者簡介:魔都技術專家兼架構,多家大廠後端一線研發經驗,各大技術社群頭部專家博主,程式設計嚴選網創始人。具有豐富的引領團隊經驗,深厚業務架構和解決方案的積累。
負責:
- 中央/分銷預訂系統效能最佳化
- 活動&優惠券等營銷中臺建設
交易平臺及資料中臺等架構和開發設計
目前主攻降低軟體複雜性設計、構建高可用系統方向。
參考:
本文由部落格一文多發平臺 OpenWrite 釋出!