數據倉庫解決方案——ODPS組件化改造之路

ODPS簡介:ODPS(Open Data Processing Service),是阿里巴巴通用計算平臺提供的一種快速、完全託管的 GB/TB/PB 級數據倉庫解決方案,現在已更名爲MaxCompute,MaxCompute 向用戶提供了完善的數據導入方案以及多種經典的分佈式計算模型,能夠更快速的解決用戶海量數據計算問題,有效降低企業成本,並保障數據安全。

場景還原

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

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

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

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

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

解決思路

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

開始,筆者想到的是通過Java後臺來生成這套模板代碼,然後在ODPS 上創建Python腳本,通過Http請求Java後臺的服務,以動態腳本的方式離線調度執行。

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

  • 代碼在JAVA側,JAVA側拼接SQL極易出錯,需要經常發佈JAVA應用來實現某個離線小功能的迭代,並且離線代碼侵入後臺系統本身也不太合理。
  • SQL是動態生成的,缺少代碼格式化,只能通過運行日誌找到實際運行的代碼,可讀性差。
  • 代碼存在兩個系統中,較爲黑盒,代碼測試和debug都較爲困難。

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

初識ODPS組件

組件的定義

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

組件的價值

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

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

SQL 組件節點生成後的發佈,調度的操作方法都和普通的 SQL 節點的操作方式是一樣的。

組件的結構

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

組件的輸入參數

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

✎ 表類型的參數

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

✎ 字符串類型的參數

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

✎ 組件的輸出參數

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

✎ 組件的過程體

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

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

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

牛刀小試

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

創建組件

過程體開發

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

填寫輸入輸出參數

調試&運行

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

發佈

組件具有版本號的功能,每次發佈,版本號會自增,後面組件使用的地方會用到。

組件引用

在數據開發頁面,在文件夾目錄先右鍵選擇創建SQL組件節點。

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

進階使用

進階思考

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

能不能根據數據的重要程度,分配不同的調度優先級呢?想到這,立馬有了靈感~

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

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

通過以上分析,可以看出大促優先級較高,而日常優先級較低。因此我們可以將數據切分爲大促數據和日常數據,大促走小時級調度鏈路,日常走天級調度鏈路。

通過統計可以看出數據分佈大約爲日常:大促=10:1

按需調度,省時又省力

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

  • 優化前,整個節點調度週期平均爲:20分鐘
  • 優化後,日常天級調度週期平均爲:15分鐘
  • 大促小時級調度週期平均:2分鐘

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

感想

  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

本文轉載自公衆號淘系技術(ID:AlibabaMTT)。

原文鏈接

數據倉庫解決方案——ODPS組件化改造之路

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章