天天看點

資料倉庫解決方案——ODPS元件化改造之路

場景還原

不知道你是否在寫離線代碼時遇到過以下幾種情況:

  1. 相同的業務代碼邏輯分散在各個地方,需要維護多份相似功能代碼;
  2. 存在多張相同結構的表輸入,需要經過相同或相似的邏輯計算加工,并輸出給下遊表;
  3. 有一個計算邏輯非常複雜,需要經過多個子流程或多個節點處理,如何理清楚這些這些節點的邏輯和層次關系?

這裡舉幾個場景,好讓你更形象地了解。

  1. 在某個系統中,資料分大促活動資料和日常資料。大促活動資料優先級較高,需要每小時地排程計算,日常資料優先級較低,隻需要天級排程。PS:在這個場景中,我們處理這些資料的邏輯高度地相似甚至相同,并且輸入表和輸出表的schema也是一樣的,唯一不同的是排程周期。
  2. 在某系統中需要統計分析不同次元下的銷售資料,比如城市、省份、時間段(天、周、月)、區域等等
  3. 某平台需要給多個業務輸出資料,希望不同業務間的資料做隔離,一個業務隻能讀取本業務範圍内的資料。

不知道現在有沒有體感了,如果有了,請繼續往下看。

解決思路

其實以上問題歸根結底,我們需要有一套代碼模闆來實作代碼的複用,我們可以通過參數的控制實作差異化的功能。

開始,筆者想到的是通過Java背景來生成這套模闆代碼,然後在ODPS 上建立Python腳本,通過Http請求Java背景的服務,以動态腳本的方式離線排程執行。

但很快發現這種方式存在諸多問題:

  1. 代碼在JAVA側,JAVA側拼接SQL極易出錯,需要經常釋出JAVA應用來實作某個離線小功能的疊代,并且離線代碼侵入背景系統本身也不太合理。
  2. SQL是動态生成的,缺少代碼格式化,隻能通過運作日志找到實際運作的代碼,可讀性差。
  3. 代碼存在兩個系統中,較為黑盒,代碼測試和debug都較為困難。

最後,在翻閱ODPS的官方文檔後發現,其實這些問題ODPS平台上已經具備相應的解決方案了——ODPS元件。

初識ODPS元件

▐ 元件的定義

元件是一種帶有多個輸入參數和輸出參數的SQL代碼過程模闆, SQL代碼的處理過程一般是引入一到多個源資料表,通過過濾,連接配接,聚合等操作,加工出新的業務需要的目标表。

▐ 元件的價值

如上,在實際業務實踐中,有大量的SQL代碼過程很類似,過程中輸入的表和輸出的表的結構是一樣的或者是類型相容的,僅僅是名字不同而已。這個時候元件的開發者就可以将這樣的一個 SQL 過程抽象成為一個SQL元件節點,将裡面可變的輸入表抽象成輸入參數,把裡面可變的輸出表抽象成輸出參數,就可以實作 SQL 代碼的複用。

元件的使用者在使用 SQL 元件節點的時候,隻要從元件清單中選擇和自己業務處理過程類似的元件,為這些元件配置上自己業務中特定的 輸入表和輸出表,不用再重複複制代碼,就可以直接生成新的元件 SQL 節點 進而極大提高了開發效率,避免了重複開發。

SQL 元件節點生成後的釋出,排程的操作方法都和普通的 SQL 節點的操作方式是一樣的。

▐ 元件的結構

一個元件就像一個函數的定義一樣,由輸入參數,輸出參數群組件代碼過程構成。

資料倉庫解決方案——ODPS元件化改造之路

元件的輸入參數

元件的輸入參數具有參數名,參數類型,參數描述,參數定義等屬性, 參數類型有兩種:一個是表類型 table,一種是字元串類型 string。

✎ 表類型的參數

指定元件過程中要引用到的表,在使用元件的時候,元件的使用者可以為該參數填入其特定業務需要的表。

✎ 字元串類型的參數

指定元件過程中需要變化的控制參數,比如指定過程的結果表隻輸出每個區域的頭 N 個城市的銷售額,這個 n 是 1 還是 3 就可以通過字元串類型的參數進行控制;另一個例子,要指定過程的結果表輸出那個省份的銷售總額,可以設定一個省份字元串參數,指定不同的省份,就能獲得指定省份的銷售資料。

✎ 元件的輸出參數

元件的輸出參數具有參數名,參數類型,參數描述,參數定義等屬性,參數類型隻有一種:表類型 table。字元串類型的輸出參數沒有邏輯意義。

✎ 元件的過程體

在過程體中參數的引用格式為:@@{參數名}

過程體通過編寫抽象的sql 加工過程,将指定的輸入表按照輸入參數進行控制加工出有業務價值的輸出表。

PS:其實作為碼農,我們能很好地了解元件的概念,因為即使你沒寫過ODPS代碼,不知道ODPS的元件,但你一定在你曾經用過的語言裡找到類似的概念,例如,前端領域中的UI元件,移動Android開發中的元件,Java開發中的各種架構,Jar包等等都是一些元件。

牛刀小試

作為初識ODPS元件的小白,我們先嘗試寫一個helloword,實作從一張大表中按業務拆分出多張子表,分别給到各自業務各自的表。

▐ 建立元件

資料倉庫解決方案——ODPS元件化改造之路

過程體開發

資料倉庫解決方案——ODPS元件化改造之路

PS: 元件過程的開發具有一定的技巧,元件過程的代碼需要巧妙的利用輸入參數和輸出參數,使得元件過程能夠在使用的時刻填入不同的輸入參數和輸出參數也能生成正确的可運作的sql代碼。

填寫輸入輸出參數

資料倉庫解決方案——ODPS元件化改造之路

調試&運作

在做完以上兩步後,我們可以直接在元件開發的界面點選運作,輸入測試的參數進行調試運作。

資料倉庫解決方案——ODPS元件化改造之路

釋出

資料倉庫解決方案——ODPS元件化改造之路

元件具有版本号的功能,每次釋出,版本号會自增,後面元件使用的地方會用到。

▐ 元件引用

在資料開發頁面,在檔案夾目錄先右鍵選擇建立SQL元件節點。

資料倉庫解決方案——ODPS元件化改造之路
資料倉庫解決方案——ODPS元件化改造之路

使用元件節點與SQL節點,大部分開發使用習慣都是一樣的,包括排程配置也都一樣,唯獨不同的是元件節點關聯了一個元件,如果需要更新節點,需要先更新元件的代碼,然後更新節點的代碼版本。

資料倉庫解決方案——ODPS元件化改造之路

進階使用

▐ 進階思考

筆者在項目開發過程中,碰到一個問題,項目開始的時候給很多離線節點設定了小時級排程,但随着項目的資料日益增長,離線節點的排程時長很快接近一小時,離線排程很快将達到瓶頸。比較自然地想到的解決方法是,将每小時排程改為每2小時排程一次,或者将小時級排程切換成天級排程,但明顯不是一種根本的解決方案。

能不能根據資料的重要程度,配置設定不同的排程優先級呢?想到這,立馬有了靈感~

經過分析後,我們系統中存在兩種類型的資料,大促資料和日常資料。大促資料由于具有時效性,過期的資料往往會進行清理,是以大促資料随時間不會大幅增長;而日常資料由于具有長期有效,随時間必然會持續的上漲。

另外大促資料時效性要求較高,日常資料變更頻率慢時效性低。

通過以上分析,可以看出大促優先級較高,而日常優先級較低。是以我們可以将資料切分為大促資料和日常資料,大促走小時級排程鍊路,日常走天級排程鍊路。

資料倉庫解決方案——ODPS元件化改造之路

通過統計可以看出資料分布大約為日常:大促=10:1

▐ 按需排程,省時又省力

下面舉一個已優化過後的例子:

優化前,整個節點排程周期平均為:20分鐘

優化後,日常天級排程周期平均為:15分鐘

大促小時級排程周期平均:2分鐘

資料倉庫解決方案——ODPS元件化改造之路
資料倉庫解決方案——ODPS元件化改造之路
資料倉庫解決方案——ODPS元件化改造之路

可以看出,經過改造後,大幅節省了原來小時級排程的計算資源和存儲成本。

感想

  1. 遇到一個問題,經過思考後往往有不止一種方案可以去解決它,也許我們最終隻會采用其中的一種方案,而被采納的方案一定是經過仔細地比較優缺點,衡量投入産出成本等多方面評估之後才做的決定。在本文中,筆者也不是一開始就知道可以通過ODPS的元件來解決問題,而是經過反複地查資料,咨詢ODPS平台的同學等方式後才行成通過ODPS元件化的方式來解決問題。
  2. 開發中我們會遇到各式各樣的問題,但很多問題,很多知識,我們可以做到融彙貫通,舉一反三。就像本文的案例中,元件這一概念,其實我們在其他領域中已經接觸過,如果我們能做到融會貫通,我們是不是一開始就會聯想到在ODPS裡會不會有元件(或者模闆)呢?

參考文獻:

1、什麼是ODPS

https://www.alibabacloud.com/help/zh/doc-detail/27800.htm?spm=ata.13261165.0.0.664b57baosPRBJ

2、什麼是DataWorks

https://www.alibabacloud.com/help/zh/doc-detail/73015.htm?spm=ata.13261165.0.0.664b57baosPRBJ

3、ODPS元件

https://www.alibabacloud.com/help/zh/doc-detail/137562.htm?spm=ata.13261165.0.0.664b57baosPRBJ