当前位置: 首页 > news >正文

Redis打包事务,分批提交

一、需求背景

      接手一个老项目,在项目启动的时候,需要将xxx省整个省的所有区域数据数据、以及系统字典配置逐条保存在Redis缓存里面,这样查询的时候会更快;
      区域数据+字典数据一共大概20000多条,,前同事直接使用 list.forEach()逐条写入Redis,如下:

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
/*** @author xxx* @version 1.0* @date 2022/7/21 15:29* @Description: 项目启动成功后初始化区域数据到redis*/
@Component
@Slf4j
public class AreasInitialComponent implements ApplicationRunner {@AutowiredprivateAreaMapper areaMapper;private static boolean isStart = false;/*** 项目启动后,初始化字典到缓存*/@Overridepublic void run(ApplicationArguments args) throws Exception {if (isStart) {return;}try {log.info("Start*******************项目启动后,初始化字典到缓存*******************");QueryWrapper<Area> wrapper = new QueryWrapper<>();wrapper.eq("del", "0");List<Area> areas = areaMapper.selectList(wrapper);if (!CollectionUtils.isEmpty(areas )) {RedisCache redisCache = SpringUtils.getBean(RedisCache.class);//先将区域集合整体做个缓存log.info("*******************先将区域集合整体做个缓存*******************");AreaUtil.setAreaListCache(redisCache, areas);//再将每一条区域进行缓存areas.stream().forEach(a -> {AreaUtil.setAreaCache(redisCache, a.getId(), a);});}isStart = true;log.info("End*******************项目启动后,初始化字典到缓存*******************");}catch (Exception e) {e.printStackTrace();}}
}

image.png

导致项目启动速度巨慢,再加上需要使用代理软件才能连接公司的数据库,每次启动项目都需要10几分钟,当真是苦不堪言;由于受不了这样的启动速度,因此决定自己动手优化。

二、解决思路

      联想到MySQL的事务打包方式,于是自己动手尝试通过Redis打包事务+分批提交的方式来提高启动速度,具体实现如下:

三、实现方法

  1. 实现方法
   @Autowiredpublic RedisTemplate redisTemplate;  /*** 逐条设置区域缓存** @param areas* @throws InterruptedException*/public void setAreaCacheItemByItem(List<Area> areas) throws InterruptedException {MoreThreadCallBack<Area> callBack = new MoreThreadCallBack<>();callBack.setThreadCount(10);callBack.setLimitCount(50);callBack.setTitle("设置区域缓存批量任务");callBack.setAllList(areas);callBack.call((list, threadNum) -> {//使用自定义线程回调工具分摊任务redisTemplate.execute(new SessionCallback<Object>() {@Overridepublic Object execute(RedisOperations operations) throws DataAccessException {//开启redis事务operations.multi();list.forEach(item -> {operations.opsForValue().set(item.getId(), item);});// 提交事务operations.exec();return null;}});});}
  1. 线程回调工具MoreThreadCallBack()
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;@Data
@Slf4j
public class MoreThreadCallBack<P> {public int limitCount = 1000;private int threadCount = 10;private List<P> allList;private AtomicInteger errorCheck;private String title;public interface CallBack<P> {void call(List<P> list, Integer threadNum);}public boolean call(CallBack<P> callBack) throws InterruptedException, RuntimeException {if (allList.isEmpty()) {return false;}// 线程池ExecutorService exec = Executors.newCachedThreadPool();// 根据大小判断线程数量if (allList.size() <= limitCount) {threadCount = 1;}// 等待结果类final CountDownLatch countDownLatch = new CountDownLatch(threadCount);// 分摊多份List<List<P>> llist = Lists.newArrayList();for (int i = 0; i < threadCount; i++) {llist.add(Lists.newArrayList());}int index = 0;for (P p : allList) {llist.get(index).add(p);index = index == (threadCount - 1) ? 0 : index + 1;}// 异常记录errorCheck = new AtomicInteger(0);// 执行for (int i = 0; i < llist.size(); i++) {List<P> list = llist.get(i);final Integer threadNum = i;exec.execute(() -> {long startTime = System.currentTimeMillis();//抛出异常 自身不处理log.info("标题:{}-{}号线程开始回调执行 数量:{}", this.getTitle(), threadNum, list.size());callBack.call(list, threadNum);long endTime = System.currentTimeMillis();log.info("标题:{}-{}号线程回调执行完毕 耗时:{}", this.getTitle(), threadNum, +(endTime - startTime));countDownLatch.countDown();});}// 等待处理完毕countDownLatch.await();// 关闭线程池exec.shutdown();return errorCheck.get() <= 0;}public boolean next() {// 检测是否有线程提前结束if (errorCheck.get() > 0) {return false;}return true;}public void error() {errorCheck.incrementAndGet();}public String getTitle() {return title == null ? "" : title;}
}
  1. 经过如上处理以后,项目启动速度大大提升,由原本的10几分钟缩短至1分钟左右,成果如下:
    image.png

相关文章:

Redis打包事务,分批提交

一、需求背景 接手一个老项目&#xff0c;在项目启动的时候&#xff0c;需要将xxx省整个省的所有区域数据数据、以及系统字典配置逐条保存在Redis缓存里面&#xff0c;这样查询的时候会更快; 区域数据字典数据一共大概20000多条,&#xff0c;前同事直接使用 list.forEach…...

深度学习毕设项目 深度学习 python opencv 动物识别与检测

文章目录 0 前言1 深度学习实现动物识别与检测2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存…...

leetcode 611. 有效三角形的个数(优质解法)

代码&#xff1a; class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int lengthnums.length;int n0; //三元组的个数//c 代表三角形最长的那条边for (int clength-1;c>2;c--){int left0;int rightc-1;while (left<right){if(nums[left]nums[r…...

Ubuntu使用Nginx部署前端项目——记录

安装nginx 依次执行以下两条命令进行安装&#xff1a; sudo apt-get update sudo apt-get install nginx通过查看版本号查看是否安装成功&#xff1a; nginx -v补充卸载操作&#xff1a; sudo apt-get remove nginx nginx-common sudo apt-get purge nginx nginx-common su…...

小航助学题库蓝桥杯题库c++选拔赛(22年1月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;...

centos用户相关命令

添加用户命令&#xff1a; adduser tony.wang useradd tony.wang 这两个命令都行&#xff0c;如果已经添加了会提示已经存在。 设置密码&#xff1a; passwd tony.wang 如果需要加入sudo组&#xff1a; usermod -aG sudo tony.wang 这个命令我在CentOS7上是不行的&#x…...

智能优化算法应用:基于哈里斯鹰算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于哈里斯鹰算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于哈里斯鹰算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.哈里斯鹰算法4.实验参数设定5.算法结果6.参考…...

Stability AI 新发布SDXL Turbo:一款实时文本到图像生成模型

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

基于Java SSM框架+Vue实现病人跟踪治疗信息系统项目【项目源码+论文说明】

基于java的SSM框架Vue实现病人跟踪治疗信息系统演示 摘要 病人跟踪治疗信息管理系统采用B/S模式&#xff0c;促进了病人跟踪治疗信息管理系统的安全、快捷、高效的发展。传统的管理模式还处于手工处理阶段&#xff0c;管理效率极低&#xff0c;随着病人的不断增多&#xff0c;…...

js一行压缩库

js一行压缩库 压缩 JavaScript 代码通常是为了减小文件大小&#xff0c;提高加载速度。有一些常见的工具和软件可用于这个目的。以下是其中一些&#xff1a; UglifyJS&#xff1a; UglifyJS 是一个流行的 JavaScript 压缩工具&#xff0c;可以通过命令行或作为一个 npm 包来使…...

管理库存和出货的软件

随着时代的信息化越来越成熟&#xff0c;库存和出货的管理使用专门的软件变得越来越普遍。一款优秀的库存和出货管理软件应具备高效性、实时性、安全性和灵活性&#xff0c;以满足企业的日常运营需求。本文将详细介绍一款管理库存和出货的软件及其功能。 一、软件介绍 &#x…...

保护关键信息基础设施网络安全,SSL证书来助力

近年来&#xff0c;随着信息科技的飞速发展和互联网的普及应用&#xff0c;保护关键信息基础设施网络安全变得越来越迫切和重要。而随着《关键信息基础设施安全保护条例》的发布&#xff0c;保护关键信息基础设施也成为运营者必须履行的义务。SSL证书作为保护传输数据安全的重要…...

Python实现学生信息管理系统(详解版)

Python实现学生信息管理系统-详解版 个人简介实验名称&#xff1a;学生信息管理系统系统功能实验步骤详讲添加入住学生信息删除学生的住宿信息修改学生的住宿信息查询学生的住宿信息显示所有学生住宿信息显示所有请假学生的信息 运行截图展示1.主界面2.添加新的入住学生信息3.显…...

企业计算机服务器中了mallox勒索病毒如何解密,mallox勒索病毒文件恢复

随着网络技术的不断发展&#xff0c;网络安全威胁也在不断增加&#xff0c;勒索病毒攻击企业计算机服务器的事件时有发生&#xff0c;并且勒索病毒的加密形式也越来越复杂。近期&#xff0c;云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器遭到了mallox…...

Linux学习笔记 CenOS6.3 yum No package xxx available

环境CenOS [roothncuc ~]# cat /etc/issue CentOS release 6.2 (Final) Kernel \r on an \m安装gcc的时候提示没有包 [roothncuc ~]# sudo yum install gcc gcc-c libstdc-devel Loaded plugins: refresh-packagekit, security Setting up Install Process No package gcc a…...

【探索Linux】—— 强大的命令行工具 P.18(进程信号 —— 信号捕捉 | 信号处理 | sigaction() )

阅读导航 引言一、信号捕捉1. 内核实现信号捕捉过程2. sigaction() 函数&#xff08;1&#xff09;函数原型&#xff08;2&#xff09;参数说明&#xff08;3&#xff09;返回值&#xff08;4&#xff09;函数使用 二、可重入函数与不可重入函数1. 可重入函数条件2. 不可重入函…...

vue3+ts v-model 深度学习

<template><div><h1>我是App.vue组件</h1><div>isShpw:{{ isShow }}</div><div>text:{{ text }}</div><div><button click"isShow !isShow">开关</button></div><hr /><vModeVal…...

网络通信概述

文章目录 IP地址端口号协议三要素作用 五元组协议分层OSI七层模型TCP/IP 五层模型应用层传输层网络层数据链路层物理层 封装和分用发送方 - 封装中间转发接收方 - 分用 一般认为计算机网络就是利用通信线路和通信设备将地理上分散的、具有独立功能的多个计算机系统按不同的形式…...

<avue-crud/>,二级表头,children下字典项的dicUrl失效问题

目录 1.提出问题&#xff1a; 1.1 代码&#xff1a; 1.2 效果图&#xff1a;会发现处在children下的dicUrl失效了 2. 解决思路 3. 解决代码&#xff08;你要的都在这&#xff0c;看这里&#xff09; 1.提出问题&#xff1a; 在使用<avue-crud/>组件实现二级表头时&…...

FastApi接收不到Apifox发送的from-data字符串_解决方法

接收不到Apifox发送的from-data字符串_解决方法 问题描述解决方法弯路总结弯路描述纵观全局小结 问题描述 这里写了一个接口&#xff0c;功能是上传文件&#xff0c;接口参数是file文件和一个id字符串 gpt_router.post("/uploadfiles") async def create_upload_fi…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

DingDing机器人群消息推送

文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人&#xff0c;点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置&#xff0c;详见说明文档 成功后&#xff0c;记录Webhook 2 API文档说明 点击设置说明 查看自…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战

🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...

【2D与3D SLAM中的扫描匹配算法全面解析】

引言 扫描匹配(Scan Matching)是同步定位与地图构建(SLAM)系统中的核心组件&#xff0c;它通过对齐连续的传感器观测数据来估计机器人的运动。本文将深入探讨2D和3D SLAM中的各种扫描匹配算法&#xff0c;包括数学原理、实现细节以及实际应用中的性能对比&#xff0c;特别关注…...