当前位置: 首页 > 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…...

告别杂乱!用FileMenu Tools 8.4.2一键清理Windows 11右键菜单(附隐藏技巧)

Windows 11右键菜单精简指南&#xff1a;用FileMenu Tools打造高效工作流每次在文件上点击右键时&#xff0c;那个缓慢弹出的冗长菜单是否让你感到烦躁&#xff1f;随着安装的软件越来越多&#xff0c;Windows的右键菜单往往会变得臃肿不堪&#xff0c;严重影响工作效率。今天&…...

零基础怎么学Agent?这个工程师考试内容拆给你看

站在 AI Agent&#xff08;智能体&#xff09;爆发的十字路口&#xff0c;很多既没有深厚算法背景、也没有丰富写代码经验的“小白”常常感到迷茫&#xff1a;动辄谈及的大模型交互、复杂的业务编排&#xff0c;零基础真的能学会吗&#xff1f; 事实上&#xff0c;智能体开发早…...

Taotoken用量看板功能详解,助你洞察团队AI资源消耗模式

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Taotoken用量看板功能详解&#xff0c;助你洞察团队AI资源消耗模式 对于技术管理者或项目负责人而言&#xff0c;清晰了解团队的AI…...

终极指南:Windows 10完美安装PL2303驱动,解决老旧USB转串口芯片兼容性问题

终极指南&#xff1a;Windows 10完美安装PL2303驱动&#xff0c;解决老旧USB转串口芯片兼容性问题 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 你是否还在为Windows…...

中小企无需重型数据中台:轻量化数据体系搭建完整方案

过去几年&#xff0c;“数据中台”一度成为企业数字化的标配热词。大量中小企业盲目跟风搭建重型数据中台&#xff0c;投入高额成本、耗费数月甚至数年周期&#xff0c;最终落地效果极差&#xff1a;功能冗余、运维复杂、使用率低、投入产出比失衡。大量项目最终沦为“摆设式中…...

如何高效实现Windows自动化鼠标点击:AutoClicker完整实战指南

如何高效实现Windows自动化鼠标点击&#xff1a;AutoClicker完整实战指南 【免费下载链接】AutoClicker AutoClicker is a useful simple tool for automating mouse clicks. 项目地址: https://gitcode.com/gh_mirrors/au/AutoClicker AutoClicker是一款专业的Windows桌…...

Windows Cleaner如何5步解决C盘爆红问题?完全指南助你释放宝贵空间

Windows Cleaner如何5步解决C盘爆红问题&#xff1f;完全指南助你释放宝贵空间 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服&#xff01; 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你是否曾经面对C盘爆红的警告束手无…...

基于窗口比较器与晶体管逻辑的可编程非线性电压指示器设计

1. 项目概述&#xff1a;打造一个可编程的“移动光点”电压指示器在电子制作和仪器仪表领域&#xff0c;我们经常需要一个直观的电压指示器。经典的LM3914点/条图显示驱动芯片大家都很熟悉&#xff0c;它能把一个模拟电压信号转换成10个LED的点亮状态&#xff0c;形成移动的光点…...

别光看手册!手把手教你读懂气体放电管(GDT)的6个关键参数,选型不踩坑

气体放电管实战选型指南&#xff1a;从参数表到电路设计的6个关键决策点 每次打开气体放电管&#xff08;GDT&#xff09;的英文数据手册&#xff0c;面对密密麻麻的参数表格和波形图&#xff0c;不少工程师都会陷入选择困难——这些数值到底如何影响实际电路保护效果&#xf…...

Rocky Linux 9.2 安装避坑指南:解决UEFI引导、分区加密、安装黑屏等常见问题

Rocky Linux 9.2 实战安装排雷手册&#xff1a;从UEFI配置到疑难解析当CentOS转向Stream分支后&#xff0c;Rocky Linux凭借其与RHEL的二进制兼容性和稳定的发布周期&#xff0c;迅速成为企业级环境的首选替代方案。但在实际安装过程中&#xff0c;即便是经验丰富的系统管理员也…...