分布式任务调度的几种实现(Redis实现分布式锁 MySQL实现任务调度 负载均衡)

需求背景

现在有一个计算搜索词热榜的任务,该服务部署在了多个节上,希望只有一个节点在执行这个任务。

常见方案

使用Redis实现分布式锁方案

使用一个分布式锁,确保整个分布式环境下,只有一个节点能够拿到锁。节点先抢占分布式锁,如果抢到了分布式锁的话,就执行计算搜索词热榜的任务,否则的话,就跳过该任务。

使用Redis实现的话,可以使用SexNX命令,SETNX task1_key pod1表示节点pod1正在尝试抢任务task1的分布式锁。设置的时候需要设置过期时间。如果上锁成功的话,说明该节点可以执行任务task1

解锁的话,采用lua脚本完成。这个脚本检查一个键的值是否等于给定的参数值,如果相等,则删除该键;否则,返回0。传入的KEYS[1] = "task1_key",ARGV[1]="pod1"

lua 复制代码
if redis.call('get', KEYS[1]) == ARGV[1] then  
    return redis.call('del', KEYS[1])  
else  
    return 0  
end

使用MySQL实现任务调度

在MySQL的数据库里创建一张表,里面是所有等待运行的定时任务。所有的节点都试着从表里抢占任务,如果成功的话就执行该任务。

这里的抢占,可以使用乐观锁来更新状态实现。先找到符合条件的任务,假设任务执行状态为等待开始,对应的数据库表字段为status=waiting_start,假设此时的version=1。然后尝试更新状态为update status = running。那么对于更新成功的节点来说,就相当于抢占到了该任务。如何保证更新的时候,没有其他节点抢占呢?更新的时候同时判断status=waiting_start,version=1,就能保证单节点抢占。

这里会存在的一个问题就是,如果已经抢占到任务但是任务还没执行完,该节点就异常退出了,但是其他节点都会认为该节点依旧在执行任务,就会陷入死锁的局面。想了一下解决方案就是,引入续约机制,对于MySQL实现而言,就是该节点需要不断地更新数据库的update_time字段,也就是更新时间,证明自己的状态正常;对于Redis实现而言,相当于延长锁的过期时间。

开源框架 XXL-JOB

XXL-JOB 是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习门槛低、功能强大并且轻量级。它支持自定义任务调度策略,支持多种执行模式,并且支持动态分片。

XXL-JOB主要由调度中心和执行器两部分组成。调度中心负责管理调度信息,按照调度配置发出调度请求,但自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块。执行器则负责接收调度请求并执行任务逻辑。

退一步而言,如果引入XXL-JOB的成本过高,可以考虑起一个单独的服务执行定时任务,运行在单pod上,这样的好处是开发快捷方便,缺点可能在于修改任务需要服务发版。

负载均衡

前两种方案在设计的时候,都是看哪个节点先抢占到任务,没有结合节点的情况考虑,如果一个本身就负载高的节点抢占到了任务,那么可能会影响到其他的业务逻辑,甚至引发节点OOM或崩溃。这种情况下,应该在调度的时候就引入一些负载均衡策略,

  • 检查节点的负载情况,超出健康阈值后就不抢占任务,比如内存使用率>=80%或CPU使用率>=80%,就不抢占该定时任务,同时设置一个定时任务未执行的报警,方便监控。
  • 每次选取负载最低的节点来进行,可以是内存最低也可以是CPU利用率最低,这就要求有一个控制中枢检测各个节点的负载情况,感觉需要借助中间件实现
  • 如果某个节点正在运行该任务,但是运行中的负载较高,就要及时中断并更换节点,做容错处理
  • 如果定时任务运行需要的资源较多,可以考虑使用XXL-JOB这种分布式任务调度框架
相关推荐
C++忠实粉丝18 分钟前
Redis 介绍和安装
数据库·redis·缓存
李洋-蛟龙腾飞公司18 分钟前
HarmonyOS Next 应用元服务开发-分布式数据对象迁移数据文件资产迁移
分布式·华为·harmonyos
ClouGence1 小时前
Redis 到 Redis 数据迁移同步
数据库·redis·缓存
苏三说技术1 小时前
Redis 性能优化的18招
数据库·redis·性能优化
Tttian6222 小时前
基于Pycharm与数据库的新闻管理系统(2)Redis
数据库·redis·pycharm
言之。2 小时前
redis延迟队列
redis
技术路上的苦行僧3 小时前
分布式专题(10)之ShardingSphere分库分表实战指南
分布式·shardingsphere·分库分表
苹果醋33 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
hanbarger3 小时前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
先睡3 小时前
MySQL的架构设计和设计模式
数据库·mysql·设计模式