
一 概述
ADC(Alibaba DChain Data Converger)項目的主要目的是做一套工具,使用者在前端簡單配置下名額後,就能在系統自動生成的大寬表裡面查詢到他所需要的實時資料,資料源支援跨庫并支援多種目标媒體。說的更高層次一點, 資料的全局實時可視化這個事情本身就是解決供應鍊資料“神龍效應”的有效措施(參考施雲老師的《供應鍊架構師》[1]一書)。做ADC也是為了這個目标,整個ADC系統架構如下圖所示:
架構解析:
- 初始資料來自于中繼資料中心。
- 經過中繼資料适配層後轉換為内部格式資料。
- 排程中心把内部格式的資料傳到計劃中心,計劃中心分析資料需求并模組化,通過SQL生成器生成資源和SQL,分别通過告警中心、對賬中心設定監控标準和對賬标準。
-
- 對賬中心定時對賬,檢視資料的對齊情況。
-
- 告警中心可以針對任務錯誤、延遲高等情況發送報警。
- 資源的生命周期管控在資源管理中心下,view删除時資源管理中心負責回收資源。
- 基礎資源适配層主要借助集團基礎資源管理能力串聯阿裡各類資料服務, 比如阿裡雲MaxComputer、Flink、阿裡雲AnalyticDB等。
其中,SQL生成器的上遊和下遊主要涉及:
- 上遊計劃中心
-
- 配置名額:使用者在前端配置他想看的資料有哪些。
-
- 生産原始資料:根據使用者輸入得到哪些表作為資料源, 以及它們之間的連接配接關系。
- 下遊基礎資源适配層擴充卡
- 把SQL釋出到Flink, 根據建表資料建實體表。
本文主要從技術角度介紹下SQL生成器相關的内容。
二 技術實作
在項目實施階段,需要從需求分析、技術方案設計、測試聯調幾個步驟展開工作。本文重點不放在軟體開發流程上, 而是就設計模式選擇和資料結構算法設計做下重點講解。
需求分析
在需求分析階段, 我們明确了自動生成SQL子產品所需要考慮的需求點, 主要包含如下幾點:
- 需要支援多個事實表(流表)、多個次元表連表,其中一個事實表是主表,其他的均為輔助表。
- 維表變動也應當引起最終資料庫更新。
- 主表對輔助表為1:1或N1,也就是說主表的粒度是最細的, 輔表通過唯一鍵來和主表連接配接。
- 流表中可能存在唯一鍵一緻的多張流表, 需要通過全連接配接關聯。唯一鍵不同的表之間通過左連接配接關聯。
- 隻有連表和UDF,沒有groupby操作。
- 要求同步延時較小,支援多種源和目标媒體。由于查詢壓力在目标媒體,是以查詢qps沒有要求。
系統流程圖
明确需求後, 我們把SQL生成器總體功能分為兩塊:
- 同步生成SQL和建表資料
- 異步釋出SQL和建表
之是以把生成SQL階段做成同步是因為同步階段記憶體操作為主,如果發現資料有問題無法生成SQL能做到快速失敗。釋出階段調用基礎資源适配層需要同步等待較長時間, 每個釋出步驟要做到有狀态記錄, 可復原或者重試。是以異步實作。SQL生成器同步階段的整體功能細化到小子產品,如下圖所示:
檢查階段
檢查原始資料是否有問題, 無法生成SQL則快速失敗。
- 參數檢查:檢查上遊是否提供了基本的參數, 比如事實表資訊(可以沒有維表, 但是必須有事實表)。
- 表類型檢查:檢查資料來源類型是否支援。
- 分區字段檢查:是否提供了大寬表分區字段。
- 連接配接限制:檢查流表,維表連接配接資訊是否正确。
- 主表唯一性限制:檢查主表是否含連接配接資訊,唯一鍵是否有ETL資訊。
- 中繼資料檢查:檢查是否包含HBase配置資訊。
- 主鍵修正:修正維表連接配接鍵, 必須是維表的唯一鍵。
資料同步
- 同步所有原始表和原始表的連接配接資料(比如源表同步進來, 生成1:1的HBase表)。
- 生成優先級隊列:生成連接配接和釋出等任務的執行優先級。
- 同步填充:填充源表對應的同步階段HBase表資料,和對應的配置項, 類型轉換(比如源表是MySQL表,字段類型要轉換為HBase的類型), ETL填充, 添加消息隊列(通過發送消息的方式通知下遊節點運作)。
- 重複列修剪:删除重複的列。
- 空白列打标:對于滿足一定條件(比如不需要在大寬表展示, 不是唯一鍵列, 連接配接鍵列, 保序列)的列打上空白列辨別。
- 保序字段填充:如果上遊提供了表示資料建立時間的字段, 則用該字段作為資料保序字段, 沒有則填充系統接收到資料的時間作為保序字段。
計算階段
生成大寬表,填充SQL。
- 中間表填充:填充全連接配接産生的中間表。
- 連接配接關系更新:會在本文後面說明。
- 反向索引填充:填充“反向索引”資訊。
- 消息填充:中間表添加消息隊列(中間表更新可以觸發下遊節點)。
- 大寬表填充:填充大寬表資料。
- 連接配接鍊對齊:中間表和大寬表連接配接鍵對齊。
- ETL填充:填充大寬表列的ETL資訊。
- 分區字段填充:填充大寬表分區字段。
- SQL填充:填充Flink同步表映射SQL語句, Flink計算SQL語句, Flink結果表映射SQL語句。
- 儲存:把SQL和建表資料存入資料庫, 之後的請求可以複用已有的資料, 避免重複建表。
異步釋出階段會把SQL語句釋出到Flink。
添加反向索引的原因
假如有A、B兩表連接配接,那麼連接配接方式為A表的非主鍵連接配接B表主鍵。從時序上來說可能有以下三種情況:
- B表資料先于A表資料多天産生
- B表資料後于A表資料多天産生
- B表資料和A表資料同時産生
下面我們就這三種情況逐一分析。
場景1:B表資料先于A表資料多天産生
我們假如B表資料存儲于某個支援高qps的資料庫内,我們可以直接讓A表資料到來時直接連接配接此表(維表)來實作連表。
場景2:B表資料後于A表資料多天産生
這種場景比較麻煩。A表資料先行産生,是以過早的落庫,導緻B表資料到來時即使連接配接B維表也拿不到資料。這種場景還有一個類似的場景:如果AB連接配接完成後B發生了更新,如何讓B的更新展現在寬表中?
為了解決這種問題,我們增加了一個“反向索引表”。假如A的主鍵是id,連接配接鍵是ext_id,那麼我們可以将ext_id和id的值存儲在一張表内,當B的資料更新時,用B的主鍵連接配接這種表的ext_id字段,拉取到所有的A表id字段,并将A表id字段重新流入Flink。
三 設計模式
對系統整體流程有了解以後, 我們再來看看系統的設計模式選擇,選擇設計模式時,我們考慮到資料處理相關的開發工作存在一些共性:
- 拆解後小功能多
- 小功能存在複用情況
- 小功能執行有嚴格的先後順序
- 需要記錄小功能運作狀态, 流程執行可復原或者中斷可恢複執行
由于資料處理任務的步奏比較冗長,而且由于每個階段的結果與下階段的執行有關系,又不能分開。
參考 PipeLine(流水線)設計模式[2],綜合考慮後我們系統的整體設計如下圖所示:
首先有一個全局的PipeLineContainer管理多個pipeLine和pipeline context, 每個pipeline可獨立執行一個任務, 比如pipeline1執行同步生成sql任務。pipeline2執行異步釋出任務。釋出必須在生成SQL結束後執行, pipeline有狀态并且按一定順序串聯。每個pipeline包含多個可重用的valve(功能)。valve可以重用, 任意組合,友善完成更多的資料處理任務(比如以後如果要支援Tisplus dump平台接入, 則簡單拼接現有的valve就可以)。
四 資料結構和算法
問題說明
SQL生成器關鍵點, 就是把各個表(Meta節點)之間的關系表示出來。Meta之間的關系分為兩類,分别是全連接配接關聯和左連接配接關聯(因為左連接配接關聯涉及到資料的時序問題, 需要添加反向索引較為複雜, 是以和全連接配接區分了一下, 為了簡化問題我們先執行全連接配接, 再執行左連接配接)。
我們要解決的問題是, 多個資料源同步資料進來之後, 按一定的優先級關聯, 最終得到一個大寬表并需要自動釋出。抽象到資料結構層面就是:
- 每個同步進來的資料源對應一個葉子節點
- 節點之間有關聯關系,關聯關系有多類并有執行優先級
- 所有節點和關聯關系組成一棵樹
- 最終得到一個根節點(大寬表)并釋出
算法思路
下面說明下解決該問題的算法思路。
優先級隊列
因為葉子節點之間連接配接執行優先級不同,先放入優先級隊列。之後每次取出高優先級任務執行。相同優先級任務可以複用, 連續執行多次。優先級隊列示意圖如下:
建構樹
有了優先級隊列的概念, 我們來建構樹。建構主要分以下步驟:
1.首先得到四種優先級的任務, 優先級從高到低分别為:
- 優先級1, 六個節點的同步任務
- 優先級2,節點1、2、3和節點4、5的Full Join任務
- 優先級3,節點1、4和節點6的Left Join任務
- 優先級4, 釋出任務
2.取優先級1的任務執行,同步進來六個資料源對應六個葉子。
3.取優先級2的任務并執行得到中間表1,2。
4.取優先級3的任務并執行,發現節點1、4有父節點, 則執行中間節點1、2分别和節點6 Left Join得到根節點。
5.取優先級4的任務并執行,釋出根節點。
可以看到最終的資料結構是一棵樹, 通過這種方式我們能支援複雜sql的自動建構。進一步抽象, 這種“一個隊列驅動一棵樹生成”的模式可以解決一類問題:
- 問題的解決由一系列不同優先級的任務組成, 任務需要複用。
- 通過從隊列取優先級高的任務的方式建構任務關系樹。
- 最後周遊樹完成各個節點任務。
五 總結
限于篇幅, 本文重點在于介紹自動生成sql功能開發中運用到的主要資料結構和設計模式思想。
目前我們實作了任意張表關聯sql自動生成并釋出, 整體延遲控制在2s以内。之後SQL生成器主要會針對友善接入更多第三方實時計算平台(比如Tisplus), 降低整體系統延遲工作展開。友善接入主要考驗的是架構的設計, 也是本文着重寫的點(包括資料結構和算法設計、設計模式的選擇)。降低系統延遲則包括消息中間件優化,代碼執行效率提升等。
最後
阿裡巴巴供應鍊國際化團隊歡迎廣大有識之士加入,共同打造東半球零售業首選的國際化供應鍊平台。有意請聯系:[email protected]
相關連結
[1]
https://book.douban.com/subject/26995807/[2]
https://blog.csdn.net/buyoufa/article/details/51912262