定时任务扫表缺点解决方案

通过定时任务扫表,是我们在业务中经常会做的事情,一般是直接用xxl-job等定时任务去分页查询数据库,然后进行业务操作,这个方案,一般是最简单的,也是最有效的。

但是,他还是有一些缺点的,如:

  1. 数据量多扫表慢
  2. 集中式扫表会影响正常业务
  3. 定时扫表存在延迟问题

数据量多,扫表慢

随着需要扫描的表中的数据量越来越大,通过定时任务扫表的方式会越来越慢,那么想要解决这个问题,

  1. 首先可以考虑加索引。
  2. 其次,可以考虑多线程并发扫表.
    这里可以考虑采用线程池,在任务中开多个线程并发的从数据库中扫描数据进行处理。

但是这样做,会带来一个问题,那就是多个线程之间如何做好隔离,如何确保不会出现并发导致同一条记录被多个线程执行多次呢?

  1. 首先最基本的保障,扫表之后的处理逻辑要做好幂等控制,一旦出现了重复的情况,下游也能因为做了幂等而不会重复处理。
  2. 除此以外,在扫表的时候,可以通过分段的思想进行数据隔离。举个例子:
Long minId = messageService.getMinInitId();for(int i=1;i<= threadPool.size();i++){Long maxId = minId + segmentSize()*i;List<Message> messages = messageService.scanInitMessages(minId,maxId);proccee(messages);minId = maxId + 1;
}

像上面的例子中,假设有10个线程,那么第一个线程就扫描ID处于0-1000的数据,第二个线程扫描1001-2000的数据,第三个线程扫描2001-3000的数据。这样以此类推,线程之间通过分段的方式就做好了隔离,可以避免同一个数据被多个线程扫描到。

这个做法,有个小问题,那就是数据的ID可能不是连续的,那么就需要考虑其他的分段方式,比如在时间表中增加一个业务ID,然后根据这个biz_id做分片也可以。

比如:

for(int i=1;i<= threadPool.size();i++){List<Message> messages = messageService.scanInitMessages(i);proccee(messages);
}

这样在SQL中:

SELECT * FROM RETRY_MESSAGE WHERE 
STATE = "1"
AND BIZ_ID LIKE "${frontNumber}%"

那么,不同的线程执行的SQL就不一样了分别是:

SELECT * FROM RETRY_MESSAGE WHERE 
STATE = "1"
AND BIZ_ID LIKE "1%"SELECT * FROM RETRY_MESSAGE WHERE 
STATE = "1"
AND BIZ_ID LIKE "2%"SELECT * FROM RETRY_MESSAGE WHERE 
STATE = "1"
AND BIZ_ID LIKE "3%"SELECT * FROM RETRY_MESSAGE WHERE 
STATE = "1"
AND BIZ_ID LIKE "4%"

这样也是可以做分段的。

集中式扫表会影响正常业务

如果业务量比较大的话,集中式的扫描数据库势必给数据库带来一定的压力,那么就会影响到正常的业务。

那么想要解决这个问题,

  1. 首先可以考虑,不扫主库,而是扫描备库。之所以能这么做,是因为这个业务场景一般都是可以接受一定的数据延迟的,那么备库带来延迟就可以忽略,但是备库是没有业务操作的,所以对备库的扫描是不会对业务造成影响的。

当然,这里还要考虑一个问题,那就是备库扫描数据之后的执行,执行完该如何同步到主库,这里可以直接修改主库,主备库数据ID一致的,直接去修改主库的就行了。不建议直接在备库上修改。

但是不管怎么样,备库还是可以分担扫表的这个大量高峰请求的。

除了扫备库,还有一个方案,

  1. 那就是做分库了。把原来集中在同一个数据库的数据分散到不同的数据库中,这样用集群代替单库来整体对外提供服务,可以大大的提升吞吐量。

因为多个数据库的话,每个库提供的连接数就会多,并且多个实例的话,CPU、IO、LOAD这些指标也可以互相分担。

定时扫表存在延迟问题

定时任务都是集中式的定时执行的,那么就会存在延迟的问题。随着数据库越来越大,延时会越来越长。

想要降低延迟,那就要抛弃定时任务的方案,可以考虑延迟消息,基于延迟消息来做定时执行。

用了延迟消息之后,还可以缓解数据库的压力。也能比定时扫表的性能要好,实时性也更高。

当然,引入另外一个中间件也需要考虑成本的。

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

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

相关文章

【elastic search】JAVA操作elastic search

目录 1.环境准备 2.ES JAVA API 3.Spring Boot操作ES 1.环境准备 本文是作者ES系列的第三篇文章&#xff0c;关于ES的核心概念移步&#xff1a; https://bugman.blog.csdn.net/article/details/135342256?spm1001.2014.3001.5502 关于ES的下载安装教程以及基本使用&…

节省时间:AI 模型靠谱下载方案汇总

这篇文章&#xff0c;想分享下我日常是如何下载模型的&#xff0c;包括下载来源和工具使用细节&#xff0c;希望对折腾模型的你也有帮助。 也希望开源和 AI 领域的研究者、从业者在做技术调研和落地实践的时候&#xff0c;都能节约一些时间。 写在前面 之前写了很多模型相关…

微信小程序:发送小程序订阅消息

文档&#xff1a;小程序订阅消息&#xff08;用户通过弹窗订阅&#xff09;开发指南 目录 步骤一&#xff1a;获取模板 ID步骤二&#xff1a;小程序端获取参数2.1、获取消息下发权限2.2、获取登录凭证&#xff08;code&#xff09; 步骤三&#xff1a;后端调用接口下发订阅消息…

【Web】CTFSHOW PHP命令执行刷题记录(全)

目录 web29 web30 web31 web32 web33 web34 web35 web36 web37-39 web40 web41 &#xff08;y4✌脚本&#xff09; web42 -44 web45 web46 -49 web50 web51 web52 web53 web54 web55-56 web57 web58 web59 web60 web61 web62 web63-65 web66-67 w…

2024秋招—国科微电子—系统测试工程师一面

前言 笔试后的3天约面 过程 自我介绍实习经历实习过程中最困难的一件事你的沟通能力怎么样项目经历介绍常见数据结构和算法介绍CS科班课程主要内容测试场景题Linux相关&#xff08;管道、进程&#xff09;如果在年终评级时&#xff0c;你的上司给了你完全不符的负面评价&…

QT 信号与槽

.h文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();public slots:void buttonLable();priv…

rke2 Online Deploy Rancher v2.8.0 latest (helm 在线部署 rancher v2.8.0)

文章目录 1. 简介2. 预备条件3. 安装 helm4. 安装 cert-manager4.1 yaml 安装4.2 helm 安装 5. 安装 rancher6. 验证7. 界面预览 1. 简介 Rancher 是一个 Kubernetes 管理工具&#xff0c;让你能在任何地方和任何提供商上部署和运行集群。 Rancher 可以创建来自 Kubernetes 托…

多平台多账号一站式短视频管理矩阵营销系统下载

矩阵营销系统多平台多账号一站式管理&#xff0c;一键发布作品。智能标题&#xff0c;关键词优化&#xff0c;排名查询&#xff0c;混剪生成原创视频&#xff0c;账号分组&#xff0c;意向客户自动采集&#xff0c;智能回复&#xff0c;多账号评论聚合回复&#xff0c;免切换&a…

Go语言的指针(深度解析)

指针是Go语言中的一个重要概念&#xff0c;它提供了对内存地址的直接访问和操作能力。通过指针&#xff0c;我们可以高效地传递和修改变量的值&#xff0c;避免了值传递所带来的拷贝开销。在本文中&#xff0c;我们将深入探讨Go语言指针的概念、使用方法和注意事项。 指针的本…

文档扫描与矫正-仿射变换

图像变换是计算机视觉和图像处理中的关键技术之一&#xff0c;它允许我们对图像进行各种形式的变形、调整和校正。其中&#xff0c;仿射变换是一种常见的变换方式。 在文档扫描过程中&#xff0c;由于拍摄角度和畸变等原因&#xff0c;文档图像可能存在一定程度的形变。仿射变…

【LeetCode】组合两个表(mysql)

题目 编写解决方案&#xff0c;报告 Person 表中每个人的姓、名、城市和州。如果 personId 的地址不在 Address 表中&#xff0c;则报告为 null 。 以 任意顺序 返回结果表。 结果格式如下所示。 答 select firstName ,lastName,city,state from Person left join Address …

软路由之爱快基于L2TP 实现

申明&#xff1a;本文仅针对国内SSTP&#xff0c;适用于国内的游戏加速&#xff0c;禁止一切利用该技术的翻墙行为。 相信很多接触过爱快的人都需要连接L2TP或PPTP&#xff0c;本文主要介绍通过爱快iKuai的L2TP 来实现异地组网。 一、准备工作 1、爱快 v3.x 2个&#xff08;免…

【linux 多线程并发】线程退出自动清理函数的使用,释放线程申请的资源,异常退出自动调用

线程退出回调函数 ​专栏内容&#xff1a; 参天引擎内核架构 本专栏一起来聊聊参天引擎内核架构&#xff0c;以及如何实现多机的数据库节点的多读多写&#xff0c;与传统主备&#xff0c;MPP的区别&#xff0c;技术难点的分析&#xff0c;数据元数据同步&#xff0c;多主节点的…

React与Vue性能对比

React 和 Vue 是目前前端开发中最流行的两个框架&#xff0c;它们在性能方面有一些不同。下面是一些关于这两个框架性能的说明和代码示例。 React React 的虚拟 DOM 使其具有很高的性能。React 的核心思想是将组件视为虚拟 DOM 的树形结构&#xff0c;当数据发生变化时&#…

SpringMVC源码解析——HTTP请求处理

在SpringMVC源码解析——DispatcherServlet的逻辑处理中&#xff0c;最后介绍到了org.springframework.web.servlet.DispatcherServlet的doDispatch方法中关于处理Web HTTP请求的核心代码是调用AbstractHandlerMethodAdapter类的handle方法&#xff0c;源码如下&#xff1a; /*…

iOS 按钮添加点击震动

1. 方法说明&#xff1a; iOS10后系统提供了一套API来简单实现震动&#xff1a; init时传入一个style定义好的枚举就可以实现不同的震动 typedef NS_ENUM(NSInteger, UIImpactFeedbackStyle) {UIImpactFeedbackStyleLight,UIImpactFeedbackStyleMedium,UIImpactFeedbackStyle…

作业:通过两台linux主机配置ssh实现互相免密登陆

做题步骤&#xff1a; 一.开启两个Linux主机&#xff0c;并且用ssh连接&#xff0c;要能够ping通 我这里是server&#xff1a;192.168.81.129 client&#xff1a;192.168.81.130 举例 步骤&#xff1a; 1.安装服务软件 2.运行软件程序 3.根据自定配置提供对应的服务/etc/chr…

Leaflet + Vue使用案例

区域边界及级联 1.获取区域边界JSON数据&#xff0c;下载后放到项目里 https://datav.aliyun.com/portal/school/atlas/area_selector data() {return {areaFeaturesData: null, // 南通市json数据areaLayer: null, // 区域边界图层isCheckClick: false,currentArea: null, //…

期末查分系统(c,链表实现)

主要功能&#xff1a; 分为三个身份: 学生:可以通过学号查询个人分数 老师&#xff1a;可以看所有学生成绩&#xff0c;单科排名&#xff08;正序&#xff0c;倒序&#xff09;&#xff0c;统计绩点&#xff0c;查看绩点排名前百分之n的学生 管理员端&#xff1a;可以创建链…

用React给XXL-JOB开发一个新皮肤(二):目录规划和路由初始化

目录 一. 简述二. 目录规划三. Vite 配置 3.1. 配置路径别名3.2. 配置 less 四. 页面 4.1. 入口文件4.2. 骨架文件4.3. 普通页面 五. 路由配置六. 预览启动 一. 简述 上一篇文章我们介绍了项目初始化&#xff0c;此篇文章我们会先介绍下当前项目的目录规划&#xff0c;接着对…