數(shù)據(jù)倉庫系統(tǒng)建設(shè)中的工作流及優(yōu)化
文章作者:翟東波、邢汝峰 搜狐
編輯整理:Hoh
內(nèi)容來源:作者授權(quán)
出品平臺:DataFunTalk
注:歡迎轉(zhuǎn)載,轉(zhuǎn)載請留言。
01
數(shù)據(jù)倉庫建設(shè)
1. 數(shù)據(jù)倉庫基本概念
數(shù)據(jù)倉庫的概念在 1991 年被美國著名的信息工程專家 William Inmon 博士首次提出,它是數(shù)據(jù)庫技術(shù)發(fā)展到一定階段的產(chǎn)物。數(shù)據(jù)倉庫是面向主題的、集成的、穩(wěn)定的和隨時間變化的數(shù)據(jù)集合,是一個數(shù)據(jù)分析處理過程,而不僅僅是一個數(shù)據(jù)存儲軟件或產(chǎn)品。
OLAP ( On-line Analytical Processing,聯(lián)機(jī)分析處理 ) 是數(shù)據(jù)倉庫中最經(jīng)常使用的數(shù)據(jù)處理和分析技術(shù),最早由關(guān)系數(shù)據(jù)庫之父 E.F.Codd 于 1993 年提出。OLAP 委員會對聯(lián)機(jī)分析處理的定義為:使分析人員、管理人員或執(zhí)行人員能夠從多種角度對從原始數(shù)據(jù)中轉(zhuǎn)化出來的、能夠真正為用戶所理解的、并真實(shí)反映企業(yè)特性的信息進(jìn)行快速、一致、交互的存取,從而獲得對數(shù)據(jù)更深入了解的一類軟件技術(shù)。簡單來說,OLAP 就是幫助用戶更好的從多個角度去理解現(xiàn)有的數(shù)據(jù)。
多維模型 ( Multidimensional Model ) 是 OLAP 的數(shù)據(jù)存儲和組織范型,是 OLAP 操作的核心技術(shù)。OLAP 基于多維模型定義了一些常見的數(shù)據(jù)操作,包括下鉆 ( Drill-down )、 上卷 ( Roll-up )、切片 ( Slice )、切塊 ( Dice ) 以及旋轉(zhuǎn) ( Pivot ) 使決策者、分析者對數(shù)據(jù)進(jìn)行各種分析操作。
維度建模 ( Dimensional Modeling ) 是數(shù)據(jù)倉庫建設(shè)中的一種數(shù)據(jù)建模方法,將數(shù)據(jù)結(jié)構(gòu)化的邏輯設(shè)計方法,它將客觀世界劃分為度量和上下文,由 Kimball 最先提出這一概念。維度建模屬于一種關(guān)系建模方法,即將多維模型映射到關(guān)系模型,將關(guān)系模型中的表分為維度表 ( dimension table ) 和事實(shí)表 ( fact table ) 兩種,其中維度表表示對分析主題所屬類型的描述,而事實(shí)表表示對分析主題的度量。
2. 數(shù)據(jù)倉庫建設(shè)主要工作
數(shù)據(jù)倉庫體系架構(gòu)的核心組件有三個:原始數(shù)據(jù)層,數(shù)據(jù)倉庫,前端應(yīng)用。如下圖所示:

整體來看,數(shù)據(jù)倉庫系統(tǒng)對業(yè)務(wù)數(shù)據(jù)和 server 日志等原始數(shù)據(jù)進(jìn)行匯聚,數(shù)據(jù)分析處理后,提供給前端應(yīng)用系統(tǒng)進(jìn)行使用,包括 BI ( Business Intelligence )、搜索、推薦等各類應(yīng)用場景。
在數(shù)據(jù)倉庫系統(tǒng)內(nèi)部,需要對數(shù)據(jù)進(jìn)行分層,主要有如下好處:
防止煙囪式開發(fā),減少重復(fù)開發(fā),開發(fā)通用中間層數(shù)據(jù),減少重復(fù)計算;
將復(fù)雜問題簡單化,將復(fù)雜任務(wù)的多個步驟分解到各個層次中,每一層只處理較少的步驟,使單個任務(wù)更容易理解;
可進(jìn)行數(shù)據(jù)血緣追蹤,便于快速定位問題;
整個數(shù)據(jù)層次清晰,每個層次的數(shù)據(jù)都有職責(zé)定位,便于使用和理解。
數(shù)據(jù)倉庫主要分為 STG、ODS、DWD、DWS、ADS 和 DIM 共 6 個層次,數(shù)據(jù)從底層開始,向上層進(jìn)行傳遞、轉(zhuǎn)換、重組等操作,可以理解為,根據(jù)數(shù)據(jù)分析業(yè)務(wù)的需要,對原有的 OLAP 多維數(shù)據(jù),進(jìn)行維度和指標(biāo)的重新組合。層次的具體描述如下:
STG原始數(shù)據(jù)層:用來表示原始數(shù)據(jù)在數(shù)據(jù)倉庫的落地,數(shù)據(jù)結(jié)構(gòu)和原始系統(tǒng)發(fā)送上來的保持一致。
ODS數(shù)據(jù)操作層:用于原始數(shù)據(jù)在數(shù)據(jù)平臺的落地。數(shù)據(jù)從數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)之間的邏輯關(guān)系上都與原始數(shù)據(jù)層基本保持一致。在源數(shù)據(jù)裝入這一層時,要進(jìn)行諸如業(yè)務(wù)字段提取或去掉不用字段、臟數(shù)據(jù)處理等等。
DWD數(shù)據(jù)明細(xì)層:用于源系統(tǒng)數(shù)據(jù)在數(shù)據(jù)平臺中的永久存儲。它用以支撐 DWS 層和 ADS 層無法覆蓋的需求,比如像用戶購買詳單類業(yè)務(wù)需求。這一層主要解決一些數(shù)據(jù)質(zhì)量問題和數(shù)據(jù)的完整度問題。
DWS數(shù)據(jù)服務(wù)層:數(shù)據(jù)匯總層,該層會在 DWD 層的數(shù)據(jù)基礎(chǔ)上。對數(shù)據(jù)做輕度的聚合操作,生成一系列的中間表,提升公共指標(biāo)的復(fù)用性,減少重復(fù)加工。按照業(yè)務(wù)劃分,如流量、產(chǎn)品、用戶等,生成字段比較多的寬表,用于提供后續(xù)的業(yè)務(wù)查詢,OLAP 分析,數(shù)據(jù)分發(fā)等。
ADS應(yīng)用數(shù)據(jù)層:該層存放數(shù)據(jù)產(chǎn)品個性化的統(tǒng)計指標(biāo)數(shù)據(jù),一般以某個業(yè)務(wù)應(yīng)用為出發(fā)點(diǎn)進(jìn)行建設(shè), ADS 層只關(guān)心自己需要的數(shù)據(jù),不會全盤考慮企業(yè)整體的數(shù)據(jù)架構(gòu)和應(yīng)用。面向?qū)嶋H的業(yè)務(wù)數(shù)據(jù)需求,以 DWD 或者 DWS 層的數(shù)據(jù)為基礎(chǔ),組成各種統(tǒng)計報表。
DIM維度層:主要存儲公共的屬性數(shù)據(jù),比如產(chǎn)品類別、地理位置、時間詳情等信息。綜上所述,數(shù)據(jù)倉庫建設(shè)的主要工作,就是對原始業(yè)務(wù)數(shù)據(jù)進(jìn)行匯聚,進(jìn)行分層次的數(shù)據(jù)處理,生成業(yè)務(wù)需要的數(shù)據(jù),提供給前端業(yè)務(wù)使用。
根據(jù)數(shù)據(jù)層次和數(shù)據(jù)分析維度,工作流節(jié)點(diǎn)通過數(shù)據(jù)流向依賴在一起;
對于規(guī)模稍大的數(shù)據(jù)倉庫,可涉及到多位數(shù)開發(fā)人員的工作協(xié)調(diào);
可以根據(jù)數(shù)據(jù)處理或數(shù)據(jù)分析工作需要,隨時增加工作流節(jié)點(diǎn)。





綜合來看,目前應(yīng)用于數(shù)據(jù)倉庫建設(shè)場景的工作流管理系統(tǒng),主要存在以下幾個問 題:
都是以工作流為單位進(jìn)行編輯、管理和發(fā)布部署,但是在實(shí)際的數(shù)據(jù)倉庫建設(shè)過程中,經(jīng)常是多個數(shù)據(jù)開發(fā)工程師協(xié)同完成整個工作流的開發(fā)部署工作,每個人只負(fù)責(zé)部分工作流任務(wù)節(jié)點(diǎn),不同開發(fā)者的任務(wù)相互依賴,現(xiàn)有的工作流管理系統(tǒng)不能很好滿足多人的開發(fā)協(xié)同工作。
針對一些復(fù)雜的任務(wù)依賴,比如兩個任務(wù)都是小時調(diào)度,小時調(diào)度之間存在某種對應(yīng)關(guān)系,現(xiàn)有工作流管理系統(tǒng)都是按任務(wù)進(jìn)行依賴配置,不能做到每個任務(wù)不同調(diào)度時間之間的依賴配置,或者要寫大量的輔助代碼實(shí)現(xiàn),給用戶帶來極大的使用不便。
對于新增或修改 ( 如發(fā)現(xiàn)某個統(tǒng)計指標(biāo)計算有錯 ) 的任務(wù)節(jié)點(diǎn),經(jīng)常需要針對這樣的任務(wù)節(jié)點(diǎn)及其子任務(wù)節(jié)點(diǎn)進(jìn)行歷史數(shù)據(jù)修補(bǔ),以工作流為單位進(jìn)行調(diào)度的系統(tǒng),不太適合這種場景的處理。
計算機(jī)系統(tǒng)中軟件體系結(jié)構(gòu)采用一種分層的結(jié)構(gòu),有句名言:"計算機(jī)科學(xué)領(lǐng)域的 任何問題都可以通過增加一個間接的中間層來解決"。結(jié)合數(shù)據(jù)倉庫建設(shè)工作的特點(diǎn),本文所優(yōu)化的工作流管理系統(tǒng),將數(shù)據(jù)倉庫建設(shè)工作流中的節(jié)點(diǎn),抽象成任務(wù)和實(shí)例兩個層次:數(shù)據(jù)開發(fā)人員專注于單個任務(wù)的設(shè)計,配置任務(wù)的依賴和周期等調(diào)度屬性,構(gòu)建任務(wù)的工作流;根據(jù)任務(wù)的依賴和周期屬性,工作流管理系統(tǒng)自動生成任務(wù)對應(yīng)的實(shí)例,構(gòu)建實(shí)例的工作流。這樣可以解決上節(jié)中提到的現(xiàn)有開源工作流管理系統(tǒng)的問題,提升開發(fā)協(xié)同、減少重復(fù)性工作。
1. 工作流層次
工作流管理系統(tǒng)將數(shù)據(jù)倉庫建設(shè)中的數(shù)據(jù)處理工作流分成任務(wù)和實(shí)例兩個層次,任務(wù)是對實(shí)例的抽象,實(shí)例是對任務(wù)的具化,任務(wù)是數(shù)據(jù)處理的本體,負(fù)責(zé)創(chuàng)建實(shí)例,而實(shí)例是具體的執(zhí)行單元。這樣系統(tǒng)就包含兩個相互獨(dú)立又相互關(guān)聯(lián)的工作流,即任務(wù)工作流和實(shí)例工作流。
① 任務(wù)工作流
任務(wù)工作流層面,用戶根據(jù)數(shù)據(jù)分析的需要,手動增加或修改單個任務(wù)。任務(wù)除了包括數(shù)據(jù)處理內(nèi)容 ( 如 Shell、HIVE SQL、Spark 等代碼 ),還要包括依賴和周期等任務(wù)屬性。通過依賴屬性,所有任務(wù)可以形成任務(wù)工作流 DAG,用戶只需定義本任務(wù)依賴的父任務(wù) ( 也可依賴自身 ),工作流管理系統(tǒng)會進(jìn)行相關(guān)校驗(yàn),保證 DAG 屬性 ( 如無環(huán)等 ) 不被破壞等;通過周期屬性,確定任務(wù)一天中被調(diào)度的次數(shù)和時間。
只需要配置依賴和周期屬性,便能滿足任務(wù)依賴自身上一次運(yùn)行結(jié)果或一天中多個時間點(diǎn)要被調(diào)度等復(fù)雜配置場景,極大簡化了任務(wù)配置難度。
② 實(shí)例工作流
實(shí)例工作流層面,工作流管理系統(tǒng)根據(jù)任務(wù)工作流的任務(wù)屬性等信息,按照預(yù)定的生成規(guī)則 ( 規(guī)則具體說明參見后面章節(jié) ),創(chuàng)建出任務(wù)對應(yīng)的實(shí)例,形成實(shí)例工作流。
工作流管理系統(tǒng)根據(jù)實(shí)例工作流,按照 DAG 方式進(jìn)行調(diào)度,當(dāng)實(shí)例滿足如下兩個條件時,才能被調(diào)度執(zhí)行:
該實(shí)例所有的父實(shí)例節(jié)點(diǎn)都已完成調(diào)度執(zhí)行;
到達(dá)本實(shí)例的調(diào)度時間。
③ 兩者關(guān)聯(lián)
任務(wù)工作流是一個靜態(tài)的工作流,不會被系統(tǒng)調(diào)度;實(shí)例工作流是任務(wù)工作流在某 一時刻的鏡像,會被系統(tǒng)調(diào)度執(zhí)行,完成數(shù)據(jù)處理工作。
工作流管理系統(tǒng)一般按天為單位,在固定時間點(diǎn)生成所有任務(wù)一天的所有實(shí)例信息, 即依據(jù)任務(wù)工作流構(gòu)建實(shí)例工作流;也可以按照其他時間間隔單位生成實(shí)例,比如以小時為單位,在每個小時的某個時間點(diǎn),生成所有任務(wù)在對應(yīng)小時時間段的實(shí)例信息。
下面兩張圖為具體的任務(wù)工作流和實(shí)例工作流,其中左圖為任務(wù)工作流,右圖為實(shí)例工作流。

圖中 parent 的任務(wù)節(jié)點(diǎn),周期屬性為天,每天 8 點(diǎn)被調(diào)度;依賴屬性為自身依賴,即依賴上一天的執(zhí)行結(jié)果。
圖中 child 的任務(wù)節(jié)點(diǎn),周期屬性為小時,從 0 點(diǎn)開始,每隔 4 小時調(diào)度一次;依賴屬性,parent 為其依賴的父任務(wù)節(jié)點(diǎn),即父任務(wù) parent 執(zhí)行完后,child 任務(wù)節(jié)點(diǎn)才可以被調(diào)度執(zhí)行。
2. 任務(wù)屬性
任務(wù)屬性,主要包括周期屬性和依賴屬性,工作流管理系統(tǒng)根據(jù)這兩個屬性,將任務(wù)工作流轉(zhuǎn)換成實(shí)例工作流。
① 周期屬性
周期屬性用于指定任務(wù)的調(diào)度周期及具體的調(diào)度時間。
調(diào)度周期,可以設(shè)置為月、周、日、小時等 ( 一般不考慮分鐘級別,分鐘級別的數(shù)據(jù)處理任務(wù)可以使用 Storm、Flink 或 Spark Streaming 等實(shí)時數(shù)據(jù)處理系統(tǒng) )。一般設(shè)置為日級別周期,即每天都被調(diào)度一次;對于月、周級別,需要制定每個月或周的哪幾天進(jìn)行調(diào)度,即不是每天都被調(diào)度;對于小時級別,需要設(shè)定一天當(dāng)中哪幾個小時進(jìn)行調(diào)度,即每天被調(diào)度多次。
調(diào)度時間,設(shè)置任務(wù)具體的執(zhí)行時間。對于月、周、日級別任務(wù),設(shè)置一個調(diào)度時間即可;對于小時級別任務(wù),需要設(shè)置對應(yīng)的多個調(diào)度時間。
② 依賴屬性
依賴屬性分為任務(wù)間依賴和任務(wù)自身依賴:
任務(wù)間依賴,用于指定任務(wù)的父任務(wù),即上游任務(wù)。例如 DWD 層的任務(wù) A,需要用到 ODS 層的任務(wù) B 和 C 產(chǎn)出的數(shù)據(jù),在配置任務(wù) A 的任務(wù)間依賴屬性時,就要設(shè)置依賴任務(wù) B 和 C。針對天級別任務(wù)依賴小時級別任務(wù)的場景,還可以設(shè)置就近依賴屬性,則子任務(wù)調(diào)度執(zhí)行依賴父任務(wù)中第一個不小于子任務(wù)調(diào)度執(zhí)行時間的調(diào)度執(zhí)行。
任務(wù)自身依賴,用于指定任務(wù)各周期之間的依賴,當(dāng)前的調(diào)度執(zhí)行,依賴上一次的調(diào)度執(zhí)行結(jié)果。例如某個天級別任務(wù),當(dāng)天的調(diào)度執(zhí)行就依賴昨天的調(diào)度執(zhí)行結(jié)果;某個小時級別任務(wù),每天 8 點(diǎn)和 16 點(diǎn)執(zhí)行,當(dāng)天 8 點(diǎn)的調(diào)度執(zhí)行就依賴昨天 16 點(diǎn)的調(diào)度執(zhí)行,當(dāng)天 16 點(diǎn)的調(diào)度執(zhí)行就依賴當(dāng)天 8 點(diǎn)的調(diào)度執(zhí)行。
3. 實(shí)例生成
工作流管理系統(tǒng),在設(shè)定的時間,根據(jù)各個任務(wù)的周期和依賴屬性,結(jié)合預(yù)定義的生成規(guī)則,生成任務(wù)對應(yīng)的實(shí)例,形成實(shí)例工作流,用于實(shí)際的數(shù)據(jù)處理任務(wù)執(zhí)行。
① 生成規(guī)則
生成規(guī)則受到任務(wù)的周期和依賴屬性影響:
首先根據(jù)周期屬性生成實(shí)例,比如天級任務(wù),根據(jù)調(diào)度時間每天生成一個實(shí)例;小時級任務(wù),根據(jù)調(diào)度時間,每天生成一個或多個實(shí)例;月和周任務(wù),根據(jù)調(diào)度時間,在對應(yīng)日期生成一個實(shí)例。
然后就是根據(jù)依賴屬性,構(gòu)建實(shí)例間的依賴關(guān)系,具體如下圖所示。

實(shí)例數(shù)相同:基于調(diào)度時間分別排序當(dāng)前任務(wù)和父任務(wù)實(shí)例,當(dāng)前任務(wù)實(shí)例依賴父任務(wù)中與之排序序號相同的實(shí)例。例如下圖,節(jié)點(diǎn) A 中實(shí)例 A1 是第一個實(shí)例節(jié)點(diǎn),則節(jié)點(diǎn) B 中第一個實(shí)例節(jié)點(diǎn)實(shí)例 B1 就依賴于實(shí)例 A1。

實(shí)例數(shù)不同:當(dāng)前任務(wù)實(shí)例只依賴父任務(wù)實(shí)例中第一個不大于本任務(wù)實(shí)例調(diào)度時間的實(shí)例。例如下圖中,在自身實(shí)例數(shù)大于父節(jié)點(diǎn)實(shí)例數(shù)時,節(jié)點(diǎn) B 中的實(shí)例 B1 和實(shí)例 B2 都依賴于節(jié)點(diǎn) A 中的 A1,在自身實(shí)例數(shù)小于父節(jié)點(diǎn)實(shí)例數(shù)時,節(jié)點(diǎn) B 中的實(shí)例 B1 會依賴于節(jié)點(diǎn) A 中的實(shí)例 A1。


小時任務(wù)依賴天任務(wù):
小時任務(wù)依賴于天任務(wù)即所有小時實(shí)例的都依賴于當(dāng)天執(zhí)行的天實(shí)例。

天任務(wù)依賴小時任務(wù):
天任務(wù)依賴小時任務(wù)也可以分為兩種,一是天實(shí)例依賴父任務(wù)生成的全部小時實(shí)例,二是天實(shí)例就近依賴其自身執(zhí)行時間節(jié)點(diǎn)前父任務(wù)執(zhí)行的最近的一個小時實(shí)例。
依賴全部小時實(shí)例:
天實(shí)例依賴全部小時實(shí)例的依賴情況

就近依賴小時實(shí)例

任務(wù)自身依賴:
任務(wù)自身依賴可以與任務(wù)間依賴一起作用構(gòu)建實(shí)例間依賴關(guān)系,任務(wù)實(shí)例依賴本任務(wù)上一次調(diào)度執(zhí)行的實(shí)例。例如下圖節(jié)點(diǎn) A 為小時任務(wù),且配置自身依賴屬性,則 2019-11-21 的實(shí)例 1 依賴于 2019-11-20 的實(shí)例 24,21 號的實(shí)例 2 依賴于 21 號的實(shí)例 1。

4. 優(yōu)化效果
通過上述的方案,將數(shù)據(jù)倉庫建設(shè)中的工作流節(jié)點(diǎn),抽象成任務(wù)和實(shí)例兩個層次,可達(dá)到以下的優(yōu)化效果:
配置工作流任務(wù)節(jié)點(diǎn)時,無需變更整個工作流配置信息,只需配置當(dāng)前任務(wù)節(jié)點(diǎn)的周期和依賴屬性等內(nèi)容,提升工作流配置靈活性;
通過任務(wù)的周期和依賴屬性,可以生成復(fù)雜的實(shí)例依賴關(guān)系,降低工作流節(jié)點(diǎn)依賴配置的復(fù)雜度;
能夠以某個任務(wù)節(jié)點(diǎn)為根節(jié)點(diǎn),構(gòu)造子工作流 ( 包含此任務(wù)節(jié)點(diǎn),及其子任務(wù)節(jié)點(diǎn)、孫子任務(wù)節(jié)點(diǎn)等 ),覆蓋歷史數(shù)據(jù)修復(fù)等場景。
本文主要根據(jù)數(shù)據(jù)倉庫建設(shè)過程中的 workflow 相關(guān)特點(diǎn),將 workflow 中的節(jié)點(diǎn)抽象成任務(wù)和實(shí)例兩個層次,用戶只需要定義任務(wù)的周期屬性和依賴屬性,workflow 管理系統(tǒng)根據(jù)任務(wù)的這些屬性自動轉(zhuǎn)換成實(shí)例間的依賴,提升數(shù)據(jù)倉庫工作流管理系統(tǒng)的易用性。當(dāng)然,數(shù)據(jù)倉庫工作流管理系統(tǒng)不僅僅包含本文描述的任務(wù)依賴和調(diào)度管理,還包括數(shù)據(jù)質(zhì)量監(jiān)控、數(shù)據(jù)處理任務(wù)追蹤、數(shù)據(jù)處理流程優(yōu)化等等,需要深入融合 workflow 和數(shù)據(jù)倉庫兩個技術(shù)領(lǐng)域,提升數(shù)據(jù)倉庫建設(shè)工作的效率。
