分布式定时任务框架Elastic-Job的使用

一、前言

    Elastic-Job是一个优秀的分布式作业调度框架。

    Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。

    Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。

    Elastic-Job-Cloud使用Mesos + Docker的解决方案,额外提供资源治理、应用分发以及进程隔离等服务。

1. Elastic-Job-Lite

  • 分布式调度协调

  • 弹性扩容缩容

  • 失效转移

  • 错过执行作业重触发

  • 作业分片一致性,保证同一分片在分布式环境中仅一个执行实例

  • 自诊断并修复分布式不稳定造成的问题

  • 支持并行调度

  • 支持作业生命周期操作

  • 丰富的作业类型

  • Spring整合以及命名空间提供

  • 运维平台

2. Elastic-Job-Cloud

  • 应用自动分发

  • 基于Fenzo的弹性资源分配

  • 分布式调度协调

  • 弹性扩容缩容

  • 失效转移

  • 错过执行作业重触发

  • 作业分片一致性,保证同一分片在分布式环境中仅一个执行实例

  • 支持并行调度

  • 支持作业生命周期操作

  • 丰富的作业类型

  • Spring整合

  • 运维平台

  • 基于Docker的进程隔离(TBD)

二、导读

    1、Elastic-Job的核心思想

    2、Elastic-Job的基本使用

三、Elastic-Job的核心思想

    对于分布式计算而言,分片是最基本的思想,Elastic-Job也是沿用了这个思想,每个job跑部分数据,所有job执行完成,便是全量数据,官网给出的SimpleJob例子如下:

public class MyElasticJob implements SimpleJob {
    
    @Override
    public void execute(ShardingContext context) {
        switch (context.getShardingItem()) {
            case 0: 
                // do something by sharding item 0
                break;
            case 1: 
                // do something by sharding item 1
                break;
            case 2: 
                // do something by sharding item 2
                break;
            // case n: ...
        }
    }
}

    用switch case循环来对应分片的业务逻辑,case分片的index,进入业务逻辑执行。当然这里也有不适应的场景,类似于MapReduce需要shuffle的场景就不适合了,比方说,要根据某一个字段全局分组聚合求结果,这时候怎么分片都可能会不合理,因为每个分片只能处理N分之一的数据,没办法shuffle再聚合,这一点,也要根据具体的业务来使用。

   那么ShardingContext可以拿到那些信息呢?源码如下

    

public final class ShardingContext {
    
    /**
     * 作业名称.
     */
    private final String jobName;
    
    /**
     * 作业任务ID.
     */
    private final String taskId;
    
    /**
     * 分片总数.
     */
    private final int shardingTotalCount;
    
    /**
     * 作业自定义参数.
     * 可以配置多个相同的作业, 但是用不同的参数作为不同的调度实例.
     */
    private final String jobParameter;
    
    /**
     * 分配于本作业实例的分片项.
     */
    private final int shardingItem;
    
    /**
     * 分配于本作业实例的分片参数.
     */
    private final String shardingParameter;
    
    public ShardingContext(final ShardingContexts shardingContexts, final int shardingItem) {
        jobName = shardingContexts.getJobName();
        taskId = shardingContexts.getTaskId();
        shardingTotalCount = shardingContexts.getShardingTotalCount();
        jobParameter = shardingContexts.getJobParameter();
        this.shardingItem = shardingItem;
        shardingParameter = shardingContexts.getShardingItemParameters().get(shardingItem);
    }
}

    以上代码,jobParameter和shardingItem是最有用的参数,shardingItem决定switch case循环的走向,shardingParameter可以用业务的查询条件,也可以用字符串拼接的方式组装很复杂的参数用于特定的业务。

四、Elastic-Job的基本使用

    1、Job配置项

public class ElasticJobConfig {
	private static CoordinatorRegistryCenter createRegistryCenter() {

		ZookeeperConfiguration zookeeperConfiguration = new ZookeeperConfiguration("127.0.0.1:2181", "elastic-job");
		CoordinatorRegistryCenter regCenter = new ZookeeperRegistryCenter(zookeeperConfiguration);
		regCenter.init();
		return regCenter;
	}

	private static LiteJobConfiguration createJobConfiguration() {

		JobCoreConfiguration simpleCoreConfig = JobCoreConfiguration.newBuilder("jobdemo", "0/5 * * * * ?", 3)
				.shardingItemParameters("0=A,1=A,2=B").failover(true).misfire(true).build();
		SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(simpleCoreConfig,
				MyElasticJob.class.getCanonicalName());
		LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite(true)
				.build();
		return simpleJobRootConfig;
	}

	public static void main(String[] args) {
		new JobScheduler(createRegistryCenter(), createJobConfiguration()).init();
	}
}

    几点说明:

    注册中心配置项,设置zookeeper集群地址,我这里用的本地单节点,所以只有一个,当然可以配置任务名称,命名空间(namespace,本质上会在zk里生成一个目录),超时时间,最大重试次数等等

    LiteJobConfiguration simpleJobRootConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).overwrite(true).build()中,overwrite参数非常重要,设置这个参数为true,修改过job配置信息才会覆盖zookeeper里的数据,要不然不会生效。

    2、SimpleJob的实现

public class MyElasticJob implements SimpleJob {

	@Override
	public void execute(ShardingContext shardingContext) {
		switch (shardingContext.getShardingItem()) {
		case 0: {
			System.out.println("当前分片:" + shardingContext.getShardingItem() + "=====" + "参数:"
					+ shardingContext.getShardingParameter() + " =====" + Thread.currentThread());
			break;
		}
		case 1: {
			System.out.println("当前分片:" + shardingContext.getShardingItem() + "=====" + "参数:"
					+ shardingContext.getShardingParameter() + " =====" + Thread.currentThread());
			break;
		}
		case 2: {
			System.out.println("当前分片:" + shardingContext.getShardingItem() + "=====" + "参数:"
					+ shardingContext.getShardingParameter() + " =====" + Thread.currentThread());
			break;
		}
		default: {
			System.out.println("当前分片:" + shardingContext.getShardingItem() + "=====" + "参数:"
					+ shardingContext.getShardingParameter() + " =====" + Thread.currentThread());
			break;
		}
		}
	}
}

    上面设置每5秒钟执行一次,执行ElasticJobConfig的main方法,执行结果如下:

    e2f825efa854fc514fa69bd305ce79df77c.jpg

    从上面的结果,可以看出,执行每个分片的任务,其实是放到一个线程池去执行的,对应的分片信息和参数信息在shardingContext可以拿到,实现业务非常方便。

    最后,如果启动多个JVM,那么这些任务就分散到各个节点里,如果一个节点宕机,下次触发任务时,将把该分片任务丢到健康机器执行,这里做到了节点容错。但是某个分片的任务在执行过程中失败了,那么这里是不会重新触发改分片任务的执行的。

 

 

    

Elastic-Job是ddframe中dd-job的作业模块中分离出来的分布式弹性作业框架。去掉了和dd-job中的监控和ddframe接入规范部分。该项目基于成熟的开源产品Quartz和Zookeeper及其客户端Curator进行二次开发。       ddframe其他模块也有可独立开源的部分,之前当当曾开源过dd-soa的基石模块DubboX。elastic-job和ddframe关系见下图Elastic-Job 主要功能定时任务: 基于成熟的定时任务作业框架Quartz cron表达式执行定时任务。作业注册中心: 基于Zookeeper和其客户端Curator实现的全局作业注册控制中心。用于注册,控制和协调分布式作业执行。作业分片: 将一个任务分片成为多个小任务项在多服务器上同时执行。弹性扩容缩容: 运行中的作业服务器崩溃,或新增加n台作业服务器,作业框架将在下次作业执行前重新分片,不影响当前作业执行。支持多种作业执行模式: 支持OneOff,Perpetual和SequencePerpetual三种作业模式。失效转移: 运行中的作业服务器崩溃不会导致重新分片,只会在下次作业启动时分片。启用失效转移功能可以在本次作业执行过程中,监测其他作业服务器空闲,抓取未完成的孤儿分片项执行。运行时状态收集: 监控作业运行时状态,统计最近一段时间处理的数据成功和失败数量,记录作业上次运行开始时间,结束时间和下次运行时间。作业停止,恢复和禁用:用于操作作业启停,并可以禁止某作业运行(上线时常用)。被错过执行的作业重触发:自动记录错过执行的作业,并在上次作业完成后自动触发。可参考Quartz的misfire。多线程快速处理数据:使用多线程处理抓取到的数据,提升吞吐量。幂等性:重复作业任务项判定,不重复执行已运行的作业任务项。由于开启幂等性需要监听作业运行状态,对瞬时反复运行的作业对性能有较大影响。容错处理:作业服务器与Zookeeper服务器通信失败则立即停止作业运行,防止作业注册中心将失效的分片分项配给其他作业服务器,而当前作业服务器仍在执行任务,导致重复执行。Spring支持:支持spring容器,自定义命名空间,支持占位符。运维平台:提供运维界面,可以管理作业和注册中心。相关文档下载Release Notes1.0.2接口变更声明何为分布式作业?目录结构说明使用步骤开发指南使用限制运维平台阅读源码编译问题说明实现原理作业分片策略监控快速上手(感谢第三方志愿者 泽伟@心探索科技 提供文档)InfoQ新闻Elastic-Job Wiki (由社区志愿者自由编辑的) 标签:作业调度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值