Quartz调度引擎基于MySQL的高可用架构调度延迟分析与解决方案

1、Quartz默认使用的高可用架构

在Quartz的官方文档中,介绍了一种默认的高可用架构,基于数据库实现。该方案中,多台Quartz服务器连接同一个数据库,单台服务器每次调度检索并锁定一批Trigger用于触发,锁定过程中将先从QRTZ_LOCKS表中获取一把全局排他锁TRIGGER_ACCESS,因此多个服务器在获取Trigger这一过程只能串行进行,各服务器轮流获取Trigger,直至所有需要触发的Trigger都被获取完毕,完成触发过程。

2、调度延迟分析

现象: 当同一时刻触发的定时任务过多(1500+)时,部分任务的触发时间出现非常明显的延迟(10s+),并且延迟时间呈现出调度批次内相近,批次间递增的情况,同时从使用的MySQL观察到在QRTZ_LOCKS表的TRIGGER_ACCESS这条数据上锁竞争非常激烈(400+查询同时抢一把锁)。
尝试的方案: 调整批量参数,未能解决,批量增大,则单次获取Trigger数量增加、耗时增加,位于后面批次的调度延迟增加。批量减小,单次获取Trigger数量减少、耗时减少,但批次增加,延迟累积导致位于后面的批次延迟增加。
疑惑: 即使是第一批次的调度延迟都可以达到10s以上,为什么从MySQL获取/更新几百条数据需要这么久?为什么一次调度会出现几百次锁竞争(按理说应该是几台Quartz服务器就有几个锁竞争才对,但是事实上看并不是这样)?
分析源码找出原因
调度逻辑主要代码位置:QuartzSchedulerThread.run()
在Quartz中,并不是只在调度获取Trigger时才去对TRIGGER_ACCESS进行加锁,而是在每个任务完成后在JobRunShell中会触发QuartzScheduler.notifyJobStoreJobComplete(),这个过程也会去对TRIGGER_ACCESS进行加锁,因此如果有任务刚好在调度时完成,就会造成锁竞争,并且激烈程度直接与同时完成的任务规模成正比,所以在同时触发的任务量很大的场景下,就出现了比较严重的调度延迟。

3、改进方案

按理说,调度过程中的加锁与任务执行完成后的加锁锁定的对象粒度应该是不一样的,前者是面向一批任务,后者是面向单个任务,这里应该是一个锁粒度过粗导致的竞争问题,尝试升级Quartz版本解决,但是在查看Quartz最新版本代码后发现,该问题依然存在,在现有的代码架构下,基于DB的高可用方案带来的调度延迟是无法消除的。

然而,要更换使用别的调度框架或者自研调度引擎成本又太高,只能想一些其他办法了。

观察发现,调度延迟主要来源于MySQL锁竞争的等待时间累积,应用程序通过MySQL锁竞争来保证一致性是性能较低的选择,因为涉及到网络通信,而使用更加轻量级的JVM锁能将耗时降低1-2个数量级,考虑到Quartz需要调度的任务数据并不多(不足1G),因此完全可以使用基于内存的JobStore进行调度,也就是使用单个Quartz实例调度所有的任务,而高可用则采用多实例+redis保证触发唯一性实现,任务更新采用多实例+MQ广播消息实现,最终调度延迟降低到5s以内,P95在1s以内。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/588353.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes网络-VXLAN

一. 网络基础 1. 计算机网络的分层 如今连接方式也越来也丰富,网线、WiFi、蓝牙、光纤,甚至我们普通的电线、照明所用的灯光,都可以作为接入网络的介质。如此庞大的网络,丰富多样的设备,计算机网络技术能把它们统一起…

认识计算机网络——计算机网络的组成

计算机网络是由多个计算机和网络设备组成的系统,通过通信协议实现数据传输和信息交换。它是现代社会信息技术的重要支撑,广泛应用于各个领域。本文将介绍计算机网络的主要组成部分,包括硬件设备、软件协议和网络服务。 一、硬件设备 计算机网…

46、激活函数 - Relu 激活

本节介绍一个在神经网络中非常常见的激活函数 - Relu 激活函数。 什么是ReLU激活函数 ReLU 英文名为 Rectified Linear Unit,又称修正线性单元,是一种简单但很有效的激活函数,它的定义如下: 即当输入 x 大于零时,输出等于他自己;当输入小于等于零时,输出为零,下面是re…

【Android进阶篇】Android中PreferenceScreen的作用和详细用法介绍

1,PreferenceScreen的作用 在Android开发中,PreferenceScreen是一个非常重要的布局控件,主要用于创建设置界面(settings page)。它可以包含多个Preference子项,如CheckBoxPreference, ListPreference等&am…

C++继承与派生——(8)多继承

归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言​📝 苦难和幸福一样,都是生命盛…

【多传感器融合导航论文阅读】

多传感器融合导航论文积累 知识点总结因子图一致因子图 文献阅读笔记[IF 18.6] 知识点总结 因子图 Factor Graph 是概率图的一种,是对函数因子分解的表示图,一般内含两种节点,变量节点和函数节点。 因子图存在着:两类节点&#…

主浏览器优化之路1——你现在在用的是什么浏览器?Edge?谷歌?火狐?360!?

上一世,我的浏览器之路 引言为什么要用两个浏览器为什么一定要放弃火狐结尾给大家一个猜数字小游戏(测运气) 引言 小时候,我一开始上网的浏览器是2345王牌浏览器吧, 因为上面集成了很多网站,我记得上面有7…

使用axios发送get和post请求

使用axios发送get和post请求的方法如下: 1.发送GET请求: axios.get(url).then(response > {// 请求成功的处理逻辑console.log(response.data);}).catch(error > {// 请求失败的处理逻辑console.error(error);});2.发送POST请求: ax…

Loading 加载 Taro + vue3 自定义组件的封装和 分页 优化

1.需求 当需要实现一个组件 上拉加载的组件 我们可以选择某些组件库的组件。 但是有的组件没有这个组件&#xff0c;比如跟Taro 框架配套的京东nut-ui组件库 没有提供这个功能, 2.Loading组件 ①封装 <template><div class"container"><div class&…

原型继承在 JavaScript 中是如何工作

原型继承是 JavaScript 中实现面向对象编程的一种机制。在 JavaScript 中&#xff0c;每个对象都有一个原型&#xff0c;原型是一个对象&#xff0c;它包含了对象的属性和方法。当我们试图访问一个对象的属性或方法时&#xff0c;JavaScript 先在对象本身中查找&#xff0c;如果…

<Icon-ResizER>support

If you get any questions in using app, email me caohechunhotmail.com.

vscode调试 反汇编c/c++ 查看汇编代码gdb/lldb

先看下流程&#xff01; 先看下流程&#xff01; 有问题请留言&#xff01; 文章目录 必备F5开启调试左侧侧边栏->确保打开回调栈右键函数栈->查看反汇编 方法二&#xff1a;手动输入命令查看 必备 使用c/c 插件&#xff0c;这应该是必备的。 F5开启调试 左侧侧边栏-&…

[Verilog] 加法器实现

1. 4位的加法器 先来一个最基本的的Verilog加法器 设计代码 module adder_4bit (input [3:0] a, b, output [3:0] sum, output carry);assign

react18框架笔记

React React 是 facebook 出的一款针对视图层的库(library)。它是基于单向数据流思想开发的&#xff0c;主要的一个功能就是针对视图显示&#xff0c;让我们把一个项目拆分成一个一个组件进行开发维护。 官网 目前我们讲的 react 是基于 18.2 的版本。react 每一个版本更新之…

Java多线程<二>多线程经典场景

leetcode 多线程刷题 上锁上一次&#xff0c;还是上多次&#xff1f; 同步的顺序。 1. 交替打印字符 使用sychronize同步锁使用lock锁使用concurrent的默认机制使用volitale关键字 Thread.sleep() / Thread.yield机制使用automic原子类 方式1 &#xff1a;使用互斥访问st…

acwing 二分

如&#xff1a;1&#xff0c;3&#xff0c;3&#xff0c;3&#xff0c;5&#xff0c;6&#xff0c;8&#xff0c;9找左端点的3&#xff1a; mid (right - left) / 2 left;if(nums[mid] < key) left mid 1; else right mid; 找右端点的3&#xff1a; mid (right - left…

window 服务使用powershell 调用office进行文档内存不够的处理

在项目中为了实现office文件的预览&#xff0c;专门做了个service进行文件的定时转换。 在测试时发现&#xff0c;服务程序 双击执行的时候&#xff0c;文件的转换一切正常&#xff0c;但是当把服务程序安装为服务的时候吗&#xff0c;就会出现如下错误&#xff1a; $PowerPo…

Matlab figure窗口最大化 窗口全屏 图表窗口最大化

我有一个项目&#xff0c;需要把多个数据文件画成的曲线一个个保存为图片&#xff0c;然后再进行集中对比分析。程序运行后&#xff0c;打开目录下保存的图片&#xff0c;发现图片的尺寸都很小&#xff0c;画质也不清晰&#xff0c;后来发现原来matlab显示图片的时候&#xff0…

java常见面试题:什么是装箱和拆箱?装箱和拆箱有哪些应用场景

装箱和拆箱是计算机科学中常用的术语&#xff0c;主要用于描述将数据从一种类型转换为另一种类型的操作。 装箱是将值类型转换为引用类型的过程。在装箱时&#xff0c;需要了解编译器内部的操作。首先&#xff0c;在托管堆中分配好内存&#xff0c;分配的内存量是值类型的各个…

UCi数据集处理技巧记录

如何起步使用UCI数据集 这里记录一下如何把带分号的数据变成经常使用的csv形式。这里使用wine的例子 https://archive.ics.uci.edu/dataset/186/winequality 原始数据 Wine UCI数据操作 这种带分号的使用python的不好阅读&#xff0c;可以尝试以下步骤&#xff1a; 转变为t…