鄭昀 創建於2015/11/10 最后更新於2015/11/12
關鍵詞:佣金計算、定時任務、數據抽取、數據清洗、數據計算、Java、Redis、MySQL、Zookeeper、azkaban2、oozie、mesos
提綱:
- 為什么要做“數據”並行計算調度?
- 他山之玉:azkaban2/oozie/mesos
- Summoner的特性
Summoner 是國璽部門推出的基於 MySQL+Redis+Zookeeper 的分布式並行計算調度和管理系統,李紅紅主設。
大家都可能做過
基於 MySQL 數據庫的,大規模的、有步驟的、步驟與步驟之間有依賴關系的數據計算。你可能定義了一堆彼此依賴的定時任務,也可能寫成一個大進程跑。
舉一個實際場景吧,在我們 O2O 業務體系下,我要做人員規模三四千人、有多條業務線、組織結構為大區-區域-城市-銷售組的銷售團隊的昨日佣金和當月佣金,這里的挑戰是:
- 涉及到商戶、門店、交易、折扣、核銷物料等等,數據量很大,至少每天都要算一次,要算得快,
- 激勵政策和佣金計算公式隨着競爭態勢變化,一般一兩個月變一次,
- 數據抽取盡可能少影響正常業務,
- 計算邏輯調整后要能快速部署和運行。
那么,以前可能會定義一些定時任務,每天凌晨從各個業務數據庫(畢竟全都拆庫分表了)里抽取:
- 人員組織架構
- 大區、區域和城市的對照關系
- 合同以及合同擁有者
- 商戶和門店
- 門店下的收單交易
- 佣金計算公式、規則以及各種權重因子
- ……
既有全量數據,也有增量數據,所以數據量是很大的。
先算簽約數、開店數、交易量等,再把業績歸結在 BD 身上,根據不同業務線的佣金計算公式依次對 BD、BD主管、城市經理等展開各種計算。
雖然我們的 JobCenter 是很優秀的定時任務調度和管理平台,但它沒有步驟(即定時任務之間的依賴關系)的概念,所以以前我們只好拍腦袋定 Job1 凌晨1點執行,Job2 凌晨2點執行,Job3和Job4放在3點執行,顯然這只是無奈之舉,
萬一 Job1 跑到凌晨3點才算完怎么辦?萬一 Job1 執行失敗了怎么辦?
什么是步驟?我們可以用下圖來理解一個大計算任務下步驟之間的依賴關系:

圖1
為了應對這種數據量很大的抽取和一環套一環的計算,我們需要
另行發展一個界面友好的、有步驟概念的、有集群調度的數據計算系統,以充分利用機器資源。
0x01,他山之玉:azkaban2/oozie/mesos
計算資源的調度,好學生有不少,如針對 hadoop 集群調度和管理的 azkaban2 和 oozie,抽象能力更高的分布式資源管理框架 apache mesos。
項目開始之初,我希望借鑒 oozie 和 azkaban2 的一些優秀設計思路,我們其實也是做調度和管理,只不過它們基於 hadoop,我們基於 mysql 而已。
給我深刻印象的調度系統特性有:
- 計算任務有步驟定義,輸入輸出都有靈活的定義,適合於數據收集、清洗、聚合、計算等各種常見計算場景;
- 步驟可以通過依賴關系來定義串行還是並行;
- 可以很直觀地看到當前任務執行時跑到了哪一個步驟,或者哪些計算小任務;
- 如 oozie 的界面
- 可以很直觀地收集和展示當前任務里的輸出流以及異常日志流;
- 可以很方便地暫停、終止、重啟任務,無需擔心遺留垃圾中間數據;
- 有報警機制,有一些簡單指標展示;
- 計算任務的步驟定義視覺化
- 如 azkaban2 的界面
於是,國璽李紅紅他們開始動手設計。最終出來的效果還不錯,下面介紹一下。
后來我們的容器私有雲用了 apache mesos,我覺得 mesos 這種高度抽象的資源調度和管理系統非常適合我們的數據並行計算應用場景,於是假想了一番:我們寫調度器去和 mesos 通信,告訴它要去執行什么命令,它去負責在整個 cluster 里調度;我們寫的工程以及控制台有點兒像 marathon,依托於 mesos+chronos;我們寫的從不同數據源抽取原始數據、計算佣金的代碼,打成 jar 包后放在 mesos master 上,配置好后,mesos slave 真的接到調度指令去運行時,會自己從 master 節點下載 jar 包並執行,blabla……這樣 mesos 能替我們省了不少開發工作。
0x02,Summoner的特性
下面介紹一下我們針對數據計算的分布式並行計算調度系統——Summoner(魔法師)。
我們命名一個大計算任務為『工作流』,工作流下有多個任務,任務彼此之間可以可視化地建立依賴關系。
工作流可以設定 Quartz cron 表示式從而定期執行,可以直觀地看到任務執行的進度,執行日志、異常日志,狀態。
我們還可以復用任務,一個任務可以隸屬於多個工作流。這樣當佣金計算規則變化時,我們只需要復用一部分任務,新增一些任務,另建一個新工作流把任務串起來即可,同時把原來的工作流禁用,這樣進退自如。
負責執行任務的客戶端(jar包)能夠自動注冊(通過 Zookeeper),於是系統知道現在有多少個機器節點可以執行某一個任務。
於是,假如任務B有了10個客戶端注冊,任務A抽取了一千萬條交易記錄,系統將這批記錄分拆為十份,發給10個任務B客戶端,於是任務B將在多個機器節點上並行計算,然后系統再去調度任務C。
它的菜單功能有:
- 資源配置管理
- 工作流管理
- 任務管理
- 依賴關系管理
- 注冊管理(客戶端注冊和服務器端注冊)
- 任務調度管理
- 調度管理
- 實時數據管理
- 工作流執行情況
- 調度日志管理
- 調度日志
下面是首頁工作台,我們可以看到自己帳號下有多少個工作流執行完成/失敗/暫停執行/取消執行,以及系統報警和信息的通知。

圖2 summoner首頁工作台
首先,我們需要建立工作流:
圖3 資源配置管理-工作流管理
我們還要把任務建起來,任務真正的執行者是一個 Java 實現的任務處理類:

圖4 任務管理
圖5 編輯任務
其次,我們要任務之間的依賴關系建立起來:

圖6 依賴關系管理
然后管理工作流:
圖7 工作流圖管理
我們可以讓工作流立即執行,來觀察它的進度:
圖8 調度日志管理
以及每一個任務的進度:

圖9 工作流執行詳情
集群里不同節點都可能會卷入工作流執行,它們產生的日志會被 flume 聚合,之后在平台上實時展示:

圖10 工作流執行日志
圖11 客戶端注冊
圖12 服務器端注冊
圖13 系統通知
Summoner 是 JobCenter 的延伸和有益補充,它們各自有各自的應用場景。我們還會借鑒 mesos 的先進理念,進一步提升 Summoner 的集群調度能力。
-EOF-
歡迎閱讀我的其他電商文章:
- 內部Hybrid App經驗解讀
- iDB是如何運轉的 一
- #研發解決方案#iDB-數據庫自動化運維平台
- 容器私有雲和持續發布都要解決哪些基礎問題 第二集
- 容器私有雲和持續發布都要解決哪些基礎問題 第一集
歡迎訂閱我的微信訂閱號『老兵筆記』,請掃描二維碼關注:
