quartz 的常见集群方案如下,通过在数据库中配置定时器信息, 以数据库悲观锁的方式达到同一个任务始终只有一个节点在运行。
优点:
缺点:
问题:
elastic-job 是由当当网基于quartz 二次开发之后的分布式调度解决方案 , 由两个相对独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成 。
Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。
Elastic-Job-Cloud使用Mesos + Docker(TBD)的解决方案,额外提供资源治理、应用分发以及进程隔离等服务 亮点:
分片的好处:
Example:你们公司刚成立,只有几十万用户,需要做一个用户订单每日统计分析,你每天凌晨触发任务,只用一个小时就跑完了。过了一年你们的用户量暴增,3000万。你们的分析任务更加复杂了,这个时候跑批任务需要6个小时,等产品经理上班来要结果的时候你发现还没跑完,他被老板骂了一顿,然后回来怼你。
你虽然受气了心理很难受,但是确实是你的锅。于是在想你有这么多机器为啥非得在一台上跑呢,咋样才能将任务分解上多台机器上独立执行。
不足:
quartz:
Elastic-Job:
Elastic-Job-Lite并无作业调度中心节点,而是基于部署作业框架的程序在到达相应时间点时各自触发调度。
注册中心仅用于作业注册和监控信息存储。而主作业节点仅用于处理分片和清理等功能。
Elastic-Job-Lite提供最安全的方式执行作业。将分片总数设置为1,并使用多于1台的服务器执行作业,作业将会以1主n从的方式执行。
一旦执行作业的服务器崩溃,等待执行的服务器将会在下次作业启动时替补执行。开启失效转移功能效果更好,可以保证在本次作业执行时崩溃,备机立即启动替补执行。
Elastic-Job-Lite也提供最灵活的方式,最大限度的提高执行作业的吞吐量。将分片项设置为大于服务器的数量,最好是大于服务器倍数的数量,作业将会合理的利用分布式资源,动态的分配分片项。
例如:3台服务器,分成10片,则分片项分配结果为服务器A=0,1,2;服务器B=3,4,5;服务器C=6,7,8,9。 如果服务器C崩溃,则分片项分配结果为服务器A=0,1,2,3,4;服务器B=5,6,7,8,9。在不丢失分片项的情况下,最大限度的利用现有资源提高吞吐量。注册中心仅用于作业注册和监控信息存储。而主作业节点仅用于处理分片和清理等功能。
图片来自于官网:
弹性分布式实现:
注册中心数据结构
注册中心在定义的命名空间下,创建作业名称节点,用于区分不同作业,所以作业一旦创建则不能修改作业名称,如果修改名称将视为新的作业。作业名称节点下又包含4个数据子节点,分别是config, instances, sharding, servers和leader。
config节点
作业配置信息,以JSON格式存储
instances节点
作业运行实例信息,子节点是当前作业运行实例的主键。作业运行实例主键由作业运行服务器的IP地址和PID构成。作业运行实例主键均为临时节点,当作业实例上线时注册,下线时自动清理。注册中心监控这些节点的变化来协调分布式作业的分片以及高可用。 可在作业运行实例节点写入TRIGGER表示该实例立即执行一次。
sharding节点
作业分片信息,子节点是分片项序号,从零开始,至分片总数减一。分片项序号的子节点存储详细信息。每个分片项下的子节点用于控制和记录分片运行状态。节点详细信息说明查看文档。
servers节点
作业服务器信息,子节点是作业服务器的IP地址。可在IP地址节点写入DISABLED表示该服务器禁用。 在新的cloud native架构下,servers节点大幅弱化,仅包含控制服务器是否可以禁用这一功能。为了更加纯粹的实现job核心,servers功能未来可能删除,控制服务器是否禁用的能力应该下放至自动化部署系统。
leader节点
作业服务器主节点信息,分为election,sharding和failover三个子节点。分别用于主节点选举,分片和失效转移处理。leader节点是内部使用的节点,如果对作业框架原理不感兴趣,可不关注此节点。子节点可查看文档。
在github地址https://github.com/elasticjob/elastic-job-lite,下载源码。
clone 然后编译:
mvn clean install -Dmaven.test.skip=true
提供两种账户,管理员及访客,管理员拥有全部操作权限,访客仅拥有察看权限。默认管理员用户名和密码是root/root,访客用户名和密码是guest/guest,可通过conf\auth.properties修改管理员及访客用户名及密码。
elastic-job的运维平台设计理念
所以运维平台配置zookeeper的信息才是关键,只有连通了zookeeper才能对定时任务进行操作,操作步骤:
左边菜单点击【全局配置】选中【注册中心配置】,然后出现一个已配置列表,在列表的分页显示下方有个【添加】按钮进行添加:
添加字段说明:
注册中心名称:自定义,用于当前列表显示,便于区分
注册中心地址: zookeeper的地址,需要连接哪个就填写哪个 【IP:端口】
命名空间: 任务创建ZookeeperRegistryCenter的时候填写namespace,要对应上,才能看到对应下的任务
登录凭证: 可不填,默认zookeeper不需要填写,除非设置了zookeeper相关信息
作业操作
作业维度:
查看当前挂在zookeeper的命名空间下的所有任务,提供删除,编辑,触发,失效等一系列功能
查看当前连着zookeeper的服务器,提供删除,失效,终止等一些列功能。
见github:https://github.com/rickiyang/springboot-learn/tree/master/elastic-job
全路径:
com.dangdang.ddframe.job.lite.api.strategy.impl.AverageAllocationJobShardingStrategy
策略说明:
基于平均分配算法的分片策略,也是默认的分片策略。
如果分片不能整除,则不能整除的多余分片将依次追加到序号小的服务器。如:
如果有3台服务器,分成9片,则每台服务器分到的分片是:1=[0,1,2], 2=[3,4,5], 3=[6,7,8]
如果有3台服务器,分成8片,则每台服务器分到的分片是:1=[0,1,6], 2=[2,3,7], 3=[4,5]
如果有3台服务器,分成10片,则每台服务器分到的分片是:1=[0,1,2,9], 2=[3,4,5], 3=[6,7,8]
Elastic-Job提供了事件追踪功能,可通过事件订阅的方式处理调度过程的重要事件,用于查询、统计和监控。Elastic-Job目前提供了基于关系型数据库两种事件订阅方式记录事件。
Elastic-Job-Lite在配置中提供了JobEventConfiguration,目前支持数据库方式配置。
事件追踪的event_trace_rdb_url属性对应库自动创建JOB_EXECUTION_LOG和JOB_STATUS_TRACE_LOG两张表以及若干索引。
JOB_EXECUTION_LOG字段含义:
字段名称 | 字段类型 | 是否必填 | 描述 |
---|---|---|---|
id | VARCHAR(40) | 是 | 主键 |
job_name | VARCHAR(100) | 是 | 作业名称 |
task_id | VARCHAR(1000) | 是 | 任务名称,每次作业运行生成新任务 |
hostname | VARCHAR(255) | 是 | 主机名称 |
ip | VARCHAR(50) | 是 | 主机IP |
sharding_item | INT | 是 | 分片项 |
execution_source | VARCHAR(20) | 是 | 作业执行来源。可选值为NORMAL_TRIGGER, MISFIRE, FAILOVER |
failure_cause | VARCHAR(2000) | 否 | 执行失败原因 |
is_success | BIT | 是 | 是否执行成功 |
start_time | TIMESTAMP | 是 | 作业开始执行时间 |
complete_time | TIMESTAMP | 否 | 作业结束执行时间 |
JOB_EXECUTION_LOG记录每次作业的执行历史。分为两个步骤:
JOB_STATUS_TRACE_LOG字段含义:
字段名称 | 字段类型 | 是否必填 | 描述 |
---|---|---|---|
id | VARCHAR(40) | 是 | 主键 |
job_name | VARCHAR(100) | 是 | 作业名称 |
original_task_id | VARCHAR(1000) | 是 | 原任务名称 |
task_id | VARCHAR(1000) | 是 | 任务名称 |
slave_id | VARCHAR(1000) | 是 | 执行作业服务器的名称,Lite版本为服务器的IP地址,Cloud版本为Mesos执行机主键 |
source | VARCHAR(50) | 是 | 任务执行源,可选值为CLOUD_SCHEDULER, CLOUD_EXECUTOR, LITE_EXECUTOR |
execution_type | VARCHAR(20) | 是 | 任务执行类型,可选值为NORMAL_TRIGGER, MISFIRE, FAILOVER |
sharding_item | VARCHAR(255) | 是 | 分片项集合,多个分片项以逗号分隔 |
state | VARCHAR(20) | 是 | 任务执行状态,可选值为TASK_STAGING, TASK_RUNNING, TASK_FINISHED, TASK_KILLED, TASK_LOST, TASK_FAILED, TASK_ERROR |
message | VARCHAR(2000) | 是 | 相关信息 |
creation_time | TIMESTAMP | 是 | 记录创建时间 |
JOB_STATUS_TRACE_LOG记录作业状态变更痕迹表。可通过每次作业运行的task_id查询作业状态变化的生命周期和运行轨迹。