標籤:

分散式輕量級批量任務框架設計思想

批量任務在不同的公司都在使用,如每天定時生成訂單、處理特定的任務等等,當數據量一大的時候,批量任務就會變得執行非常慢,有的要跑幾個小時,甚至更久,如何來提高批量任務執行的速度呢?方法有多線程+分片,這兩種結合起來執行速度是非常快的,單純使用多線程也會提高處理速度(一般的批量任務偏IO密集型,用多線程會提高處理速度)。

有多個批量處理框架,如Quartz、Spring-batch、Tbschedule、Elastic-job......,本文自己來介紹一種自已設計的分散式輕量極批量任務框架。

基本的原理如下:

  1. 選擇一個節點作為master節點(一般集群通過前端請求會路由到一台機器上,它就是Master節點),它負責不斷從數據源撈數據,並發送mq消息(同一批數據用一條消息發送出去);
  2. 其它的節點監聽消息,有消息過來就進行處理。

上面看上去好簡單,先看兩個基本的問題。

  1. 如何撈數據?
  2. java代碼如何執行呢?

答1:一台機器作為Master節點進行撈數據,它必要要做到數據不能重複,拿從Mysql資料庫表中撈數據來講,每次取1000條數據,可以指定一個主鍵id,對select 結果排序,開始指定這個id集合不會小於0,以後把最後一條數據的id作為下次撈數據的最小id,這樣就可以做到數據不會重複。

答2:有同學會問,為什麼要講java代碼如何執行呢?直接new出對象不就行了嗎?我們是提供界面運行,就是你把寫好的代碼放到界面中,點擊運行就ok了。此時如何來實現呢?其實JDK已經提供了相應的工具來幫忙我們來編譯java源碼,然後通過自定義的classloader來loadclass到內存中並實例化對象,一定要允許同名的類多次載入,因為有時寫錯了,再修改,這裡的做法有多種,最簡單的方法是破壞類的載入機制,每次可以載入,熱部署也就是這個道理。

實現暫停、停止的功能,這個也比較簡單,每次執行功能時,先從分散式緩存中取該消息對應的開關變數,如果是執行狀態,就繼續執行,如果是停止狀態,就跳過執行;暫停則在Master節點上做,如果發現是暫停狀態,則發跳過撈數據邏輯。

上面都理解好了,還有一個問題是如何遇到發版本,機器重啟怎麼辦?我們不怕Worker節點重啟,因為開機就會啟動消息監聽類,數據都存儲在mq集群,只要我不去消息它,消息只是堆積,不會丟失。最擔心的Master節點掛了,這個問題如何來解決呢?

解決的方法是Master節點在開始執行任務的時候,就註冊任務,並任務狀態是Running狀態,如果正常結束後,任務remove掉,並任務狀態是Finish狀態。如果是非正常狀態,註冊中心會感知這個節點的變化,並通知其它的機器節點,任務有異常情況,其它的節點通過分散式鎖去獲取Master的權力,這裡有一點要注意就是上次執行數據到數據主鍵id值一定要記住,否則就會有問題。

這次先概述的描述整個設計思想,後續會對其中的細節加以分析和介紹。

推薦閱讀:

分散式事務入門指南 · 常用分散式事務解決方案
分散式架構的套路No.74

TAG:分散式計算 |