利用 XXL-JOB 實現靈活控制的分片處理

本文講述了一種利用 XXL-JOB 來進行分片任務處理的方法,另外加入對執行節點數的靈活控制。

場景

現在一張數據表裏有大量數據需要某個服務端應用來處理,要求:

  1. 能夠並行處理;
  2. 能夠較靈活地控制並行任務數量。
  3. 壓力較均衡地分散到不同的服務器節點;

思路

因爲需要並行處理同一張數據表裏的數據,所以比較自然地想到了分片查詢數據,可以利用對 id 取模的方法進行分片,避免同一條數據被重複處理。

根據第 1、2 點要求,本來想通過對線程池的動態配置來實現,但結合第 3 點來考慮,服務器節點數量有可能會變化,節點之間相互無感知無通信,自己在應用內實現一套調度機制可能會很複雜。

如果有現成的獨立於這些服務器節點之外的調度器就好了——順着這個思路,就想到了已經接入的分佈式任務調度平臺 XXL-JOB,而在閱讀其 官方文檔 後發現「分片廣播 & 動態分片」很貼合這種場景。

方案

  1. 利用 XXL-JOB 的路由策略「分片廣播」來調度定時任務;
  2. 通過任務參數傳入執行任務節點數量;
  3. 定時任務邏輯裏,根據獲取到的分片參數、執行任務節點數量,決策當前節點是否需要執行,分片查詢數據並處理:
    • 如果 分片序號 > (執行任務節點數量 - 1),則當前節點不執行任務,直接返回;
    • 否則,取 分片序號執行任務節點數量 作爲分片參數,查詢數據並處理。

這樣,我們可以實現靈活調度 [1, N] 個節點並行執行任務處理數據。

主要代碼示例

JobHandler 示例:

@XxlJob("demoJobHandler")
public void execute() {
    String param = XxlJobHelper.getJobParam();
    if (StringUtils.isBlank(param)) {
        XxlJobHelper.log("任務參數爲空");
        XxlJobHelper.handleFail();
        return;
    }

    // 執行任務節點數量
    int executeNodeNum = Integer.valueOf(param);
    // 分片序號
    int shardIndex = XxlJobHelper.getShardIndex();
    // 分片總數
    int shardTotal = XxlJobHelper.getShardTotal();

    if (executeNodeNum <= 0 || executeNodeNum > shardTotal) {
        XxlJobHelper.log("執行任務節點數量取值範圍[1,節點總數]");
        XxlJobHelper.handleFail();
        return;
    }

    if (shardIndex > (executeNodeNum - 1)) {
        XxlJobHelper.log("當前分片 {} 無需執行", shardIndex);
        XxlJobHelper.handleSuccess();
        return;
    }

    shardTotal = executeNodeNum;

    // 分片查詢數據並處理
    process(shardIndex, shardTotal);

    XxlJobHelper.handleSuccess();
}

分片查詢數據示例:

select field1, field2 
from table_name 
where ... 
    and mod(id, #{shardTotal}) = #{shardIndex} 
order by id limit #{rows};

進一步思考

  1. 如果需要更大的併發量,需要有大於應用節點數量的任務並行,如何處理?

    兩種思路:

    • 通過任務參數傳入一個併發數,單個節點在處理任務時,將查詢到的數據按這個數字進行再分片,交由線程池並行處理;
    • 配置 M 個定時任務,指定相同的 JobHandler,給它們編號 0、1、2...M,並將定時任務編號和 M 這兩個數,由任務參數傳入,定時任務邏輯裏,先根據分片參數、定時任務編號、M,重新計算出新的分片參數,如 分片序號 = (分片序號 * M) + 定時任務編號分片總數 = 分片總數 * M,再查詢數據並處理。
  2. 如果有可能頻繁調整任務執行邏輯,包括可能要新增任務參數等,而不想重啓服務器,如何解決?

    可以考慮使用 XXL-JOB 的「GLUE模式」任務,能夠在線編輯和更新定時任務執行邏輯。

參考


本篇文章由一文多發平臺ArtiPub自動發佈
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章