网站建设功能需求,佛山网站建设的市场,网上购物哪个平台最好,五年级上册优化设计答案需求背景
现在有一个计算搜索词热榜的任务#xff0c;该服务部署在了多个节上#xff0c;希望只有一个节点在执行这个任务。
常见方案
使用Redis实现分布式锁方案
使用一个分布式锁#xff0c;确保整个分布式环境下#xff0c;只有一个节点能够拿到锁。节点先抢占分布式…需求背景
现在有一个计算搜索词热榜的任务该服务部署在了多个节上希望只有一个节点在执行这个任务。
常见方案
使用Redis实现分布式锁方案
使用一个分布式锁确保整个分布式环境下只有一个节点能够拿到锁。节点先抢占分布式锁如果抢到了分布式锁的话就执行计算搜索词热榜的任务否则的话就跳过该任务。
使用Redis实现的话可以使用SexNX命令SETNX task1_key pod1表示节点pod1正在尝试抢任务task1的分布式锁。设置的时候需要设置过期时间。如果上锁成功的话说明该节点可以执行任务task1。
解锁的话采用lua脚本完成。这个脚本检查一个键的值是否等于给定的参数值如果相等则删除该键否则返回0。传入的KEYS[1] task1_keyARGV[1]pod1。
if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1])
else return 0
end使用MySQL实现任务调度
在MySQL的数据库里创建一张表里面是所有等待运行的定时任务。所有的节点都试着从表里抢占任务如果成功的话就执行该任务。
这里的抢占可以使用乐观锁来更新状态实现。先找到符合条件的任务假设任务执行状态为等待开始对应的数据库表字段为statuswaiting_start假设此时的version1。然后尝试更新状态为update status running。那么对于更新成功的节点来说就相当于抢占到了该任务。如何保证更新的时候没有其他节点抢占呢更新的时候同时判断statuswaiting_start,version1就能保证单节点抢占。
这里会存在的一个问题就是如果已经抢占到任务但是任务还没执行完该节点就异常退出了但是其他节点都会认为该节点依旧在执行任务就会陷入死锁的局面。想了一下解决方案就是引入续约机制对于MySQL实现而言就是该节点需要不断地更新数据库的update_time字段也就是更新时间证明自己的状态正常对于Redis实现而言相当于延长锁的过期时间。
开源框架 XXL-JOB
XXL-JOB 是一个轻量级分布式任务调度平台其核心设计目标是开发迅速、学习门槛低、功能强大并且轻量级。它支持自定义任务调度策略支持多种执行模式并且支持动态分片。
XXL-JOB主要由调度中心和执行器两部分组成。调度中心负责管理调度信息按照调度配置发出调度请求但自身不承担业务代码。调度系统与任务解耦提高了系统可用性和稳定性同时调度系统性能不再受限于任务模块。执行器则负责接收调度请求并执行任务逻辑。
退一步而言如果引入XXL-JOB的成本过高可以考虑起一个单独的服务执行定时任务运行在单pod上这样的好处是开发快捷方便缺点可能在于修改任务需要服务发版。
负载均衡
前两种方案在设计的时候都是看哪个节点先抢占到任务没有结合节点的情况考虑如果一个本身就负载高的节点抢占到了任务那么可能会影响到其他的业务逻辑甚至引发节点OOM或崩溃。这种情况下应该在调度的时候就引入一些负载均衡策略
检查节点的负载情况超出健康阈值后就不抢占任务比如内存使用率80%或CPU使用率80%就不抢占该定时任务同时设置一个定时任务未执行的报警方便监控。每次选取负载最低的节点来进行可以是内存最低也可以是CPU利用率最低这就要求有一个控制中枢检测各个节点的负载情况感觉需要借助中间件实现如果某个节点正在运行该任务但是运行中的负载较高就要及时中断并更换节点做容错处理如果定时任务运行需要的资源较多可以考虑使用XXL-JOB这种分布式任务调度框架