天天看點

分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考

分布式定時任務排程架構選型

背景

業務場景

  1. 定期執行任務:如每天0點做資源稽查;

需求和痛點

  1. 叢集部署服務時,如何確定任務不被重複執行?---最急迫
  2. 如何監控、告警等;
  3. 高可用、無單點故障;
  4. 優秀的并行處理能力、分片能力;

自研 or 開源

任何工具的使用都要結合自身的業務場景,脫落業務場景談技術選型就是耍流氓。

考慮私有雲場景業務量一般,高并發場景很少遇到,同一時間也不會有超大量定時任務同時需要執行,是以考慮自研也未嘗不可。

目前自研最急需解決的問題并不是高并發,而是如何避免任務被重複執行;

場景就變成了:

多個應用在同一個時間都嘗試去執行任務,但最終隻有一個應用真正執行。

這樣的話,立馬就會讓人聯想到使用

去解決,因為是多個應用,是以就是

分布式鎖

。那麼,場景又變了:

多個應用在同一個時間都嘗試去擷取

分布式鎖

,隻有一個應用能搶到這把鎖,搶到鎖的應用可以執行定時任務,其他應用則直接放棄,等待下一次執行時間。

搶鎖的時機是每次定時任務執行之前,這又讓我聯想到了

AOP

,那麼利用

注解

也就順理成章了。

下面的

ShedLock

就是基于AOP + 注解的思想。

ShedLock

與Spring的內建挺友善;

Distributed lock for your scheduled tasks

Github: start: 1K Fork: 192,最近一次代碼送出 6months ago

ShedLock makes sure that your scheduled tasks are executed at most once at the same time. If a task is being executed on one node, it acquires a lock which prevents execution of the same task from another node (or thread). Please note, that if one task is already being executed on one node, execution on other nodes does not wait, it is simply skipped.

ShedLock uses external store like Mongo, JDBC database, Redis, Hazelcast, ZooKeeper or others for coordination.

ShedLock is not a distributed scheduler

Please note that ShedLock is not and will never be full-fledged scheduler, it's just a lock. If you need a distributed scheduler, please use another project. ShedLock is designed to be used in situations where you have scheduled tasks that are not ready to be executed in parallel, but can be safely executed repeatedly.

重要資訊:

  1. ShedLock可使用MongoDB、JDBC-DB、Redis或Zookeeper等來實作分布式鎖,具體采用哪種方式,由使用者決定;
  2. 它僅僅是一個分布式鎖,并不是排程程式;

與Spring的內建很簡單(官方文檔的示例,自己并未測試過),示例:

假設一個task每15分鐘執行一次,每次運作的時間都不是很長(即:應該在15min分鐘内可以運作完),更重要的是,不管起多少個執行個體,都隻希望在15分鐘内該任務有且隻被運作一次!

//示例:與Spring的原生注解 @Scheduled配合使用
import net.javacrumbs.shedlock.core.SchedulerLock;
           

@Scheduled(cron = “0 */15 * * * *”)//每15分鐘運作一次

@SchedulerLock(name = “scheduledTaskName”, lockAtMostFor = “14m”, lockAtLeastFor = “14m”)

public void scheduledTask() {

// do something

}

//lockAtMostFor : 表示最多鎖定14分鐘,主要用于防止執行任務的節點挂掉(即使這個節點挂掉,在14分鐘後,鎖也被釋放),一般将其設定為明顯大于任務的最大執行時長;如果任務運作時間超過該值(即任務14分鐘沒有執行完),則該任務可能被重複執行!

//lockAtLeastFor : 至少鎖定時長,確定在15分鐘内,該任務不會運作超過1次;

額外補充一句,關于

@Scheduled

的一些不注意的細節(單線程執行),需要特别注意:SpringTask實作定時任務

Configure LockProvider

使用JdbcTemplete來實作分布式鎖

CREATE TABLE shedlock(
    name VARCHAR(),
    lock_until TIMESTAMP() NULL,
    locked_at TIMESTAMP() NULL,
    locked_by  VARCHAR(),
    PRIMARY KEY (name)
)
           

依賴

<dependency>
    <groupId>net.javacrumbs.shedlock</groupId>
    <artifactId>shedlock-provider-jdbc-template</artifactId>
    <version>.1</version>
</dependency>
           

配置

import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
           

@Bean

public LockProvider lockProvider(DataSource dataSource) {

return new JdbcTemplateLockProvider(dataSource);

}

@Bean

public ScheduledLockConfiguration scheduledLockConfiguration(LockProvider lockProvider) {

return ScheduledLockConfigurationBuilder

.withLockProvider(lockProvider)

.withPoolSize()

.withDefaultLockAtMostFor(Duration.ofMinutes())

.build();

}

基于Piston的思路(異步監控),重寫一個

todo

思路:

  1. 還是基于Innodb引擎的行鎖;
  2. 狀态:應該基于排程時間去判斷狀态;

選型參考

  1. 簡單、易上手;
  2. 額外依賴較少,比如是否需要依賴MQ、Zookeeper等;
  3. 是否友善內建;

開源産品對比

開源産品:任務排程系統彙總

Quartz

Java事實上的定時任務标準。但Quartz關注點在于定時任務而非資料,并無一套根據資料處理而定制化的流程。雖然Quartz可以基于資料庫實作作業的高可用,但缺少分布式并行排程的功能

原理

分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考

獨立的Quratz節點之間是不需要通信的,不同節點之間是通過資料庫表來感覺另一個應用,隻有使用持久的JobStore才能完成Quartz叢集。如果某一個節點失效,那麼Job會在其他節點上執行。

如何保證隻在一台機器上觸發?

  • 資料庫悲觀鎖
  • 一旦某一節點線程擷取了該鎖,那麼Job就會在這台機器上被執行,其他節點進行鎖等待;

缺點

  1. 不适合大量的短任務 & 不适合過多節點部署;
  2. 解決了高可用的問題,并沒有解決任務分片的問題,存在單機處理的極限(即:不能實作水準擴充)。
  3. 需要把任務資訊持久化到業務資料表,和業務有耦合
  4. 排程邏輯和執行邏輯并存于同一個項目中,在機器性能固定的情況下,業務和排程之間不可避免地會互相影響。
  5. quartz叢集模式下,是通過資料庫獨占鎖來唯一擷取任務,任務執行并沒有實作完善的負載均衡機制。

Elastic-Job

官方文檔

分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考

GitHub: star 5.7K Fork:2.6K

Elastic-Job is a distributed scheduled job framework, based on Quartz and Zookeeper

Elastic Job是當當網架構師開發,是一個分布式排程解決方案,由兩個互相獨立的子項目Elastic-Job-Lite和Elastic-Job-Cloud組成;定位為輕量級無中心化解決方案,使用 jar 包的形式提供分布式任務的協調服務。支援分布式排程協調、彈性擴容縮容、失效轉移、錯過執行作業重觸發、并行排程、自診斷和修複等等功能特性。

Elastic-Job-Lite定位為輕量級無中心化解決方案,使用jar包的形式提供分布式任務的協調服務;Elastic-Job-Cloud采用自研Mesos Framework的解決方案,額外提供資源治理、應用分發以及程序隔離等功能;

Elastic-Job-Lite并沒有宿主程式,而是基于部署作業架構的程式在到達相應時間點時各自觸發排程。它的開發也比較簡單,引用Jar包實作一些方法即可,最後編譯成Jar包運作。Elastic-Job-Lite的分布式部署全靠ZooKeeper來同步狀态和原資料。實作高可用的任務隻需将分片總數設定為1,并把開發的Jar包部署于多個伺服器上執行,任務将會以1主N從的方式執行。一旦本次執行任務的伺服器崩潰,其他執行任務的伺服器将會在下次作業啟動時選擇一個替補執行。如果開啟了失效轉移,那麼功能效果更好,可以保證在本次作業執行時崩潰,備機之一立即啟動替補執行。

Elastic-Job-Lite的任務分片也是通過ZooKeeper來實作,Elastic-Job并不直接提供資料處理的功能,架構隻會将分片項配置設定至各個運作中的作業伺服器,開發者需要自行處理分片項與真實資料的對應關系。架構也預置了一些分片政策:平均配置設定算法政策,作業名哈希值奇偶數算法政策,輪轉分片政策。同時也提供了自定義分片政策的接口。

另外Elastic-Job-Lite還提供了一個任務監控和管理界面:Elastic-Job-Lite-Console。它和Elastic-Job-Lite是兩個完全不關聯的應用程式,使用ZooKeeper來交換資料,管理人員可以通過這個界面檢視、監控和管理Elastic-Job-Lite的任務,必要的時候還能手動觸發任務

功能清單

  • 分布式排程協調
  • 彈性擴容縮容
  • 失效轉移
  • 錯過執行作業重觸發
  • 作業分片一緻性,保證同一分片在分布式環境中僅一個執行執行個體
  • 自診斷并修複分布式不穩定造成的問題
  • 支援并行排程
  • 支援作業生命周期操作
  • 豐富的作業類型
  • Spring整合以及命名空間提供
  • 運維平台

優缺點

優點:

  • 基于成熟的定時任務作業架構Quartz cron表達式執行定時任務;
  • 支援任務分片:可以拆分任務,分别由不同節點執行;
  • 官網文檔齊全,全中文;
  • 彈性擴容縮容:運作中的作業伺服器崩潰,或新增N台作業伺服器,作業架構将在下次作業執行前重新分片,不影響目前作業執行;
  • 任務監控和管理界面;
分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考

缺點:

  • 依賴Zookeeper;

XXL-JOB

官方文檔

GitHub: star: 12.9K Fork:5.5K

使用該架構的公司:>300家

XXL-Job官網是大衆點評員工徐雪裡于2015年釋出的分布式任務排程平台,其核心設計目标是開發迅速、學習簡單、輕量級、易擴充。現已開放源代碼并接入多家公司線上産品線,開箱即用。

設計思想

将排程行為抽象形成“排程中心”公共平台,而平台自身并不承擔業務邏輯,“排程中心”負責發起排程請求。

将任務抽象成分散的JobHandler,交由“執行器”統一管理,“執行器”負責接收排程請求并執行對應的JobHandler中業務邏輯。

是以,“排程”和“任務”兩部分可以互相解耦,提高系統整體穩定性和擴充性;

分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考
分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考

系統組成

  • 排程子產品(排程中心):

    負責管理排程資訊,按照排程配置發出排程請求,自身不承擔業務代碼。排程系統與任務解耦,提高了系統可用性和穩定性,同時排程系統性能不再受限于任務子產品;

    支援可視化、簡單且動态的管理排程資訊,包括任務建立,更新,删除,GLUE開發和任務報警等,所有上述操作都會實時生效,同時支援監控排程結果以及執行日志,支援執行器Failover。

  • 執行子產品(執行器):

    負責接收排程請求并執行任務邏輯。任務子產品專注于任務的執行等操作,開發和維護更加簡單和高效;

    接收“排程中心”的執行請求、終止請求和日志請求等。

其他

uncode-schedule

基于zookeeper,比較小衆,不推薦

基于zookeeper+spring task/quartz的分布式任務排程元件,確定所有任務在叢集中不重複,不遺漏的執行。支援動态添加和删除任務。

LTS

最近一次更新在2年前,目前不是很活躍;也比較小衆,不推薦

light-task-scheduler

LTS(light-task-scheduler)主要用于解決分布式任務排程問題,支援實時任務,定時任務和Cron任務。有較好的伸縮性,擴充性;

TBSchedule

阿裡早期開源的分布式任務排程系統。代碼略陳舊,使用timer而非線程池執行任務排程。衆所周知,timer在處理異常狀況時是有缺陷的。而且TBSchedule作業類型較為單一,隻能是擷取/處理資料一種模式。還有就是文檔缺失比較嚴重。

依賴Zookeeper;

TBSchedule是一款非常優秀的高性能分布式排程架構,廣泛應用于阿裡巴巴、淘寶、支付寶、京東、聚美、汽車之家、國美等很多網際網路企業的流程排程系統。tbschedule在時間排程方面雖然沒有quartz強大,但是它支援分片功能。和quartz不同的是,tbschedule使用ZooKeeper來實作任務排程的高可用和分片。

TBSchedule的分布式機制是通過靈活的Sharding方式實作的,分片的規則由用戶端決定,比如可以按所有資料的ID按10取模分片、按月份分片等等。TBSchedule的宿主伺服器可以進行動态擴容和資源回收,這個特點主要是因為它後端依賴的ZooKeeper,這裡的ZooKeeper對于TBSchedule來說是一個NoSQL,用于存儲政策、任務、心跳資訊資料,它的資料結構類似檔案系統的目錄結構,它的節點有臨時節點、持久節點之分。排程引擎啟動後,随着業務量資料量的增多,目前Cluster可能不能滿足目前的處理需求,那麼就需要增加伺服器數量,一個新的伺服器上線後會在ZooKeeper中建立一個代表目前伺服器的一個唯一性路徑(臨時節點),并且新上線的伺服器會和ZooKeeper保持長連接配接,當通信斷開後,節點會自動摘除。

TBSchedule會定時掃描目前伺服器的數量,重新進行任務配置設定。TBSchedule不僅提供了服務端的高性能排程服務,還提供了一個scheduleConsole的war包,随着宿主應用的部署直接部署到伺服器,可以通過web的方式對排程的任務、政策進行監控管理,以及實時更新調整。

Saturn

Saturn是唯品會在github開源的一款分布式任務排程産品。它是基于當當elastic-job 1.0版本來開發的,其上完善了一些功能和添加了一些新的feature。

亮點:

支援多語言開發 python、Go、Shell、Java、Php。

管理控制台和資料統計分析更加完善

缺點:

技術文檔較少 , 該架構是2016年由唯品會的研發團隊基于elastic-job開發而來

Opencron

比較小衆,不推薦

Antares

Antares 是一款基于 Quartz 機制的分布式任務排程管理平台,内部重寫執行邏輯,一個任務僅會被伺服器叢集中的某個節點排程。使用者可通過對任務預分片,有效提升任務執行效率;也可通過控制台 antares-tower 對任務進行基本操作,如觸發,暫停,監控等。

Antares 是基于 Quartz 的分布式排程,支援分片,支援樹形任務依賴,但是不是跨平台的

sia-task

沒有仔細研究,依賴Zookeeper,感覺更偏向于解決編排和跨平台

無論是網際網路應用或者企業級應用,都充斥着大量的批處理任務。我們常常需要一些任務排程系統幫助我們解決問題。随着微服務化架構的逐漸演進,單體架構逐漸演變為分布式、微服務架構。在此的背景下,很多原先的任務排程平台已經不能滿足業務系統的需求。于是出現了一些基于分布式的任務排程平台。這些平台各有其特點,但各有不足之處,比如不支援任務編排、與業務高耦合、不支援跨平台等問題。不是非常符合公司的需求,是以我們開發了微服務任務排程平台(SIA-TASK)。

SIA是我們公司基礎開發平台Simple is Awesome的簡稱,SIA-TASK(微服務任務排程平台)是其中的一項重要産品,SIA-TASK契合目前微服務架構模式,具有跨平台,可編排,高可用,無侵入,一緻性,異步并行,動态擴充,實時監控等特點。

對比和結論

分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考
分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考
分布式定時任務排程架構選型分布式定時任務排程架構選型背景開源産品對比QuartzElastic-JobXXL-JOB其他對比和結論其他參考

XXL-Job 側重的業務實作的簡單和管理的友善,學習成本簡單,失敗政策和路由政策豐富。推薦使用在“使用者基數相對少,伺服器數量在一定範圍内”的情景下使用

Elastic-Job 關注的是資料,增加了彈性擴容和資料分片的思路,以便于更大限度的利用分布式伺服器的資源。但是學習成本相對高些,推薦在“資料量龐大,且部署伺服器數量較多”時使用

對于并發場景不是特别高的系統來說,xxl-job配置部署簡單易用,不需要引入多餘的元件,同時提供了可視化的控制台,使用起來非常友好,是一個比較好的選擇。

Elastic-Job

這個架構大概在2年前很火,當時使用的公司很多,想必很多人也聽過了,但是很可惜現在已經不在維護了,代碼已經有2年沒有更新了,這裡違反了更新頻率的原則,如果出現問題可能都沒什麼人幫助你,是以并不是很推薦使用。

更傾向于選擇XXL-JOB:

  1. 輕量級,支援通過Web頁面對任務進行動态CRUD操作,操作簡單
  2. 隻依賴資料庫作為叢集注冊中心,接入開發簡單,不需要ZK
  3. 高可用、解耦、高性能、監控報警、分片、重試、故障轉移
  4. 團隊持續開發,社群活躍
  5. 支援背景直接檢視每個任務執行實時日志,ELASTIC-JOB中應該是沒有這個功能

ShedLock內建更簡單,如果驗證通過,也未必不是一個好選擇!

其他

中心化排程 vs 去中心化排程

中心化 去中心化
實作難度
部署難度
觸發時間統一控制 可以 不可以
觸發延遲
異構語言支援 容易 不容易

中心化排程

  • XXL-Job:有排程中心;

去中心化排程

  • Quartz
  • Elastic-Job:實作時,就是基于Quartz的基于資料庫的分布式思想;

參考

XXL-JOB 和 Elastic-Job對比

分布式定時任務排程架構實踐

繼續閱讀