分片机制是Elastic-Job实现分布式任务调度的关键 💺
前不见古人,后不见来者。念天地之悠悠,独怆然而涕下。——陈子昂《登幽州台歌》
Elastic-Job 是一款基于 ZooKeeper 和 Quartz 实现的分布式任务调度框架,它提供了分片处理和分布式任务调度能力。
火中取栗子
Elastic-Job是一个分布式任务调度框架,它可以将一个任务拆分为多个分片,然后分发到多个作业执行器上进行并行处理。下面我将通过一个例子来详细解释这个过程。
假设我们有一个数据清洗任务,需要处理大量的用户数据。我们可以将这个任务拆分成多个分片,每个分片负责处理一部分用户数据。在Elastic-Job中,我们可以通过以下步骤来实现这个需求:
- 定义作业:
首先,我们需要创建一个作业类,继承com.dangdang.ddframe.job.api.simple.SimpleJob
,并实现execute
方法。
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
public class DataCleanJob implements SimpleJob {
@Override
public void execute(ShardingContext shardingContext) {
// 业务逻辑实现
}
}
- 实现作业逻辑:
在execute
方法中,我们需要根据shardingContext
的分片参数来执行不同分片的业务逻辑。
@Override
public void execute(ShardingContext shardingContext) {
int shardingItem = shardingContext.getShardingItem();
switch (shardingItem) {
case 0:
// 处理用户数据的第一部分
break;
case 1:
// 处理用户数据的第二部分
break;
// 其他分片
default:
throw new UnsupportedOperationException("sharding item " + shardingItem + " is not supported");
}
}
- 配置作业:
接下来,我们需要配置作业,包括作业名称、作业类、作业执行器数量等。
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.dangdang.ddframe.job.config.JobCoreConfiguration;
import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration;
import com.dangdang.ddframe.job.lite.api.JobScheduler;
import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter;
public class ElasticJobConfig {
public static void main(String[] args) {
// 配置Zookeeper注册中心
ZookeeperRegistryCenter regCenter = new ZookeeperRegistryCenter("localhost:2181", "elastic-job-demo");
// 配置作业核心配置
JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder("dataCleanJob", "0/10 * * * * ?", 2).build();
// 配置作业类型配置
SimpleJobConfiguration jobConfig = new SimpleJobConfiguration(coreConfig, DataCleanJob.class.getCanonicalName());
// 启动作业
new JobScheduler(regCenter, jobConfig).init();
}
}
上述配置中,我们将作业分成了两个分片,分片项分别为0和1。作业的cron表达式为0/10 * * * * ?
,表示每10秒执行一次作业。
当Elastic-Job作业启动时,Zookeeper注册中心会根据作业配置将作业分发到作业执行器。在这个例子中,我们有两个分片,所以Elastic-Job会将这两个分片分发到不同的作业执行器上。具体分片的过程如下:
-
Elastic-Job会在Zookeeper中创建相应的节点,包括分片节点和作业执行器节点。
-
作业执行器会从Zookeeper获取分片信息,包括分片项和分片参数。
-
Elastic-Job会根据分片策略,将分片分配给作业执行器。默认情况下,Elastic-Job使用平均分片策略,即将作业分片平均分配给所有可用的作业执行器。
-
作业执行器会根据获取到的分片信息执行对应的作业逻辑。在我们的例子中,执行器会根据分片项执行相应的数据清洗任务。
-
作业执行完毕后,作业执行器会向Zookeeper报告作业执行结果。
-
Elastic-Job会在Zookeeper中记录作业执行结果,并触发作业监听器,执行相应的后续操作。
通过上述过程,Elastic-Job实现了将一个任务拆分为多个分片,并将分片分发到多个作业执行器上进行并行处理。这样,我们可以充分利用分布式环境的计算能力,提高作业的处理速度。
需要注意的是,根据实际业务场景和需求,您可以选择不同的分片策略和作业类型。此外,Elastic-Job还提供了丰富的配置选项,可以灵活地满足各种调度需求。
作业执行器, 这个例子中就是DataCleanJob这个类吗? 我要清洗一批数据, 我用mybatis查出来以后放在shardingContext里面吗?还是我要在DataCleanJob的execute方法进行执行, 也就是说我要根据分片将我自己的数据一份为二查出来再进行处理吗?
在这个例子中,DataCleanJob
类是作业的具体实现,它是作业执行器执行的任务。execute
方法是作业执行器实际执行的方法,我们需要在这里实现具体的业务逻辑。关于数据清洗的问题,您可以选择以下两种方式来处理:
- 在
execute
方法中根据分片项查询数据并处理。这种方式下,您需要将数据查询和处理逻辑放在DataCleanJob
类的execute
方法中。根据分片项(shardingContext.getShardingItem()
),查询对应的数据并进行处理。例如:
@Override
public void execute(ShardingContext shardingContext) {
int shardingItem = shardingContext.getShardingItem();
List<UserData> userDataList;
switch (shardingItem) {
case 0:
// 根据分片项查询对应的数据
userDataList = mybatisMapper.findUserDataByShardingItem(0);
// 处理用户数据的第一部分
cleanUserData(userDataList);
break;
case 1:
// 根据分片项查询对应的数据
userDataList = mybatisMapper.findUserDataByShardingItem(1);
// 处理用户数据的第二部分
cleanUserData(userDataList);
break;
default:
throw new UnsupportedOperationException("sharding item " + shardingItem + " is not supported");
}
}
- 事先将数据划分好,放在
shardingContext
中。这种方式下,您需要在创建作业配置时,指定分片参数,将预先划分好的数据范围传递给各个作业执行器。例如:
// 配置作业核心配置
JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder("dataCleanJob", "0/10 * * * * ?", 2)
.shardingItemParameters("0=userData_0,1=userData_1")
.build();
然后,在execute
方法中,根据shardingContext.getShardingParameter()
获取对应的分片参数,查询相应的数据并进行处理。
@Override
public void execute(ShardingContext shardingContext) {
String shardingParameter = shardingContext.getShardingParameter();
List<UserData> userDataList = mybatisMapper.findUserDataByParameter(shardingParameter);
cleanUserData(userDataList);
}
这两种方式都可以实现数据清洗任务的分片处理。第一种方式适合动态数据分片的场景,第二种方式适合静态数据分片的场景。您可以根据实际业务需求选择合适的方式。
作业执行器究竟是什么?
作业执行器(Job Executor)在Elastic-Job中指的是承担任务执行的实例,通常就是部署了Elastic-Job的应用程序。执行器会根据Zookeeper注册中心的信息来执行作业,并将执行结果上报。实际上,当我们将Elastic-Job集成到我们的应用程序中并配置好作业时,应用程序就成为了作业执行器。
在分布式任务调度的场景中,作业执行器的作用是并行地处理作业的各个分片。Elastic-Job会将作业拆分成多个分片,并将分片分发到多个作业执行器上。每个作业执行器负责处理一个或多个分片,从而实现任务的并行处理。
作业执行器通常需要完成以下工作:
-
从Zookeeper注册中心获取作业的配置信息,包括作业名称、作业类型、分片项等。
-
根据作业类型和分片项执行相应的作业逻辑。例如,在
SimpleJob
类型的作业中,执行器需要实现execute
方法来处理具体的业务逻辑。 -
将作业执行结果上报给Zookeeper注册中心。执行器会在Zookeeper中记录作业执行结果,以便Elastic-Job进行监控和管理。
总的来说,作业执行器是Elastic-Job分布式任务调度过程中负责执行任务的实例,通常是集成了Elastic-Job的应用程序。
分片节点和作业执行器节点又是什么?
在Elastic-Job中,分片节点和作业执行器节点都是在Zookeeper注册中心中创建的节点。它们是用于存储作业相关信息和协调作业执行器之间的协作的。
- 分片节点(Sharding Node)
分片节点用于存储作业的分片信息,包括分片项、分片参数等。当作业启动时,Elastic-Job会在Zookeeper注册中心中创建相应的分片节点。作业执行器会根据分片节点的信息来获取自己需要处理的分片。
分片节点的结构如下:
/elastic-job-demo/sharding
├─0
└─1
上述结构中,/elastic-job-demo
是作业的根节点,sharding
是分片节点的父节点,0
和1
分别表示分片项0和分片项1。
- 作业执行器节点(Job Executor Node)
作业执行器节点用于存储作业执行器的信息,包括执行器的IP地址、端口号等。当作业执行器启动时,它会在Zookeeper注册中心中创建相应的执行器节点,并通过心跳机制向注册中心报告自己的状态。
作业执行器节点的结构如下:
/elastic-job-demo/instances
├─192.168.1.2@-@0
└─192.168.1.3@-@1
上述结构中,/elastic-job-demo
是作业的根节点,instances
是作业执行器节点的父节点,192.168.1.2@-@0
和192.168.1.3@-@1
分别表示IP地址为192.168.1.2
和192.168.1.3
的作业执行器。@-@
是分隔符,后面的数字表示分片项。
总结一下,分片节点和作业执行器节点都是在Zookeeper注册中心中创建的节点,用于存储作业的分片信息和执行器信息。这些节点在Elastic-Job的分布式任务调度过程中起到协调作业执行器之间的协作作用。
作业,任务,分片他们的关系是什么?
在Elastic-Job中,作业(Job)、任务(Task)和分片(Sharding)是密切相关的概念,它们之间的关系如下:
- 作业(Job)
作业是指需要执行的一项或多项业务逻辑。在Elastic-Job中,作业通常是由一个或多个任务组成的,它们共同完成一个业务目标。作业可以分为不同的类型,如简单作业(SimpleJob)、数据流作业(DataflowJob)和脚本作业(ScriptJob)等。
- 任务(Task)
任务是作业中的一个具体执行单元。在分布式环境中,一个作业可能需要在多个任务执行器上并行执行,以提高处理速度。这时,我们可以将作业拆分成多个任务,每个任务负责处理一部分数据或业务逻辑。
- 分片(Sharding)
为了实现任务的并行处理,Elastic-Job引入了分片的概念。分片是将一个作业拆分成多个独立的部分,每个部分包含一个或多个任务。通过分片,Elastic-Job可以将作业的各个部分分发到不同的任务执行器上进行处理,从而实现任务的并行执行。
在Elastic-Job中,一个作业(Job)通常是由多个分片(Sharding)组成的。这里的任务(Task)是泛指作业中的执行单元,可以理解为分片的另一种说法。因此,正确的说法应该是:一个作业是由多个分片组成的。
当我们在Elastic-Job中创建一个作业时,我们可以指定该作业的分片数量。Elastic-Job会根据分片数量将作业拆分成多个独立的部分,每个部分负责处理一部分数据或业务逻辑。然后,Elastic-Job会将这些分片分发到不同的作业执行器上进行处理,从而实现任务的并行执行。
所以,您可以说
一个作业是由多个分片组成的,而这些分片代表了作业中的具体执行单元(即任务)
通过将作业拆分成多个任务和分片,Elastic-Job可以充分利用分布式环境的计算能力,提高作业的处理速度。
是不是正是有了分片, 才让Elastic-Job分布式执行成为可能
正是因为有了分片(Sharding),Elastic-Job才能在分布式环境中执行。分片使得作业可以拆分成多个独立的部分,每个部分负责处理一部分数据或业务逻辑。通过这种方式,Elastic-Job可以将作业的各个部分分发到不同的作业执行器上进行处理,从而实现任务的并行执行。
Elastic-Job的分片机制在分布式环境中具有以下优势:
-
负载均衡:通过将作业拆分成多个分片,并将分片分发到不同的作业执行器上,Elastic-Job可以充分利用分布式环境的计算能力,实现负载均衡。
-
高可用:在分布式环境中,如果某个作业执行器发生故障,Elastic-Job可以自动将其承担的分片重新分配给其他可用的作业执行器,从而保证作业的高可用性。
-
弹性伸缩:Elastic-Job可以根据实际业务需求动态调整作业的分片数量。当业务量增长时,可以增加分片数量以提高处理速度;当业务量减少时,可以减少分片数量以节省资源。
-
故障恢复:如果某个作业执行器在执行过程中发生故障,Elastic-Job可以自动将其承担的分片重新分配给其他可用的作业执行器,从而实现故障恢复。
因此,分片机制是Elastic-Job实现分布式任务调度的关键,它使得Elastic-Job能够在分布式环境中实现作业的并行处理,提高处理速度和可靠性。