Java高并发之Redis批量提交数据库

article/2025/9/19 2:01:36

        随着系统并发请求激增,参考电商秒杀、当下集中核酸采取等业务场景,如果突然大量数据请求业务系统。此时如果没有做任何缓存措施,直接保存数据库,即使你的数据库做了集群和分库分表,也会由于扛不住并发压力崩溃的。基于最简单的存储模型,就是用Redis做缓存,数据业务插入到Redis缓存中,然后缓存依据系统的处理能力依次批量插入数据库,就有效避免数据库崩溃的情况发生了。

        基于最简单的存储模型,就是用Redis做缓存,数据业务插入到Redis缓存中,然后缓存依据系统的处理能力依次批量插入数据库,就有效避免数据库崩溃的情况发生了。

    然后有人说:Redis就不会崩了吗?

    当然,Redis也有它的并发上限,但是Redis是基于内存的,数据库是基于硬盘的,缓存要比数据库轻量得多!

简单模型大致如下:

在这里插入图片描述

        核心功能是:每条数据都直接通过StringRedisTemplate下的leftPushAll方法插入缓存,然后再通过定时任务,调用rightPop方法取出指定数量的集合数据,批量持久化到数据库中。注意:插入的时候从左边插入,取的时候就要从右边取出,这样的话就跟队列一样,先进先出、依次按序保存了。

Springboot大致实现的demo如下,仅供参考

1. 建项目,导入redis、mysql的依赖,yml中做配置等

略(我用的Springboot+mybatis+mybatisPlus+mysql的项目)

2. 数据库中新建一张表用于测试,对应实体、mapper、service、controller新建

在这里插入图片描述

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TempLog {@TableIdprivate Long logId;private String logParam;private String logMsg;private String createTime;
}

3. controller中引入StringRedisTemplate

@Slf4j
@RestController
@RequestMapping("/temp")
public class TempLogController {@Autowiredprivate TempLogService tempLogService;@Autowiredprivate StringRedisTemplate redisTemplate;private static final String CACHE_KEY = "TEMP_LIST";}

4. 写一个方法,模拟数据插入,使用redis的opsForList()插入数据到缓存中

	/*** 模拟:插入数据,单条存入到缓存集合中(从左边插入)*/@GetMapping("/saveCache")public R saveCache(){TempLog tempLog = TempLog.builder().logParam(StringUtils.getUuid()).logMsg(StringUtils.getRandomStr(10)).createTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())).build();log.info("数据插入...........");redisTemplate.opsForList().leftPushAll(CACHE_KEY, JSON.toJSONString(tempLog));return R.ok();}

5. 开启一个定时任务,模拟定时把缓存中的集合数据插入到数据库中

	/*** 定时任务,把缓存中的集合数据插入到数据库中* 模拟:每3s执行一次,每次从缓存中取50条数据(从右边取出)*/@Scheduled(cron = "*/3 * * * * ?")public void saveDB(){//注意:redis6.2.0以上才支持rightPop(key, count)方法,redis6.2.0版本以下调用rightPop(key, count)方法会报错,//低版本只能使用rightPop(key)单条取//rightPop(key, count) 返回值是List//rightPop(key) 返回值是Stringlog.info("定时任务...........");List<String> list = redisTemplate.opsForList().rightPop(CACHE_KEY, 50);if (list != null && list.size() > 0) {List<TempLog> collect = list.stream().map(i -> {TempLog tempLog = JSON.parseObject(i, TempLog.class);return tempLog;}).collect(Collectors.toList());//批量插入数据库tempLogService.saveBatch(collect);}}

注意:redis6.2.0以上才支持rightPop(key, count)方法,redis6.2.0版本以下调用rightPop(key, count)方法会报错

6. 测试看下效果

使用Jmeter开启100个线程,循环20次,默认发起2000次请求

在这里插入图片描述

可以看到1秒钟,就把所有的数据都提交到缓存中了,并发量达到 2000/s 了!

在这里插入图片描述

然后缓存中的数据依次批量提交到数据库了!

完结!


http://chatgpt.dhexx.cn/article/QMo6GLS4.shtml

相关文章

Java高并发累加器Striped64

原子类 在多线程环境下&#xff0c;常用累加操作方式是使用原子类进行累加&#xff0c;例如AtomicInteger、AtomicLong。但是使用原子类在多线程高竞争的情况下&#xff0c;CAS会经常失败&#xff0c;并发效率会大大降低。 因为CAS操作失败后要自旋再次进行替换&#xff0c;这…

Java高并发编程实战8,同步容器与并发容器

目录 一、为什么这种方式不能实现线程安全性?二、组合三、同步容器类四、隐藏迭代器五、并发容器六、ConcurrentHashMap一、为什么这种方式不能实现线程安全性? 分析一段代码: package com.guor.util;import java.util.

Java高并发项目案例,Java开发指南

一、前言 最近刚读完一本书&#xff1a;《Netty、Zookeeper、Redis 并发实战》&#xff0c;个人觉得 Netty 部分是写得很不错的&#xff0c;读完之后又对 Netty 进行了一波很好的复习&#xff08;之前用 spring boot netty zookeeper 模仿 dubbo 做 rpc 框架&#xff0c;那时…

Java高并发三部曲

疯狂创客圈为小伙伴奉上以下珍贵的学习资源&#xff1a; 疯狂创客圈 经典极品 &#xff1a; 极致经典《 Java 高并发 三部曲 》 面试必备 大厂必备 涨薪必备 疯狂创客圈 经典图书 &#xff1a; 《Netty Zookeeper Redis 高并发实战》 面试必备 大厂必备 涨薪必备 免费领 …

java队列处理高并发_Java高并发--消息队列

Java高并发--消息队列 举个例子&#xff1a;在购物商城下单后&#xff0c;希望购买者能收到短信或者邮件通知。有一种做法时在下单逻辑执行后调用短信发送的API&#xff0c;如果此时服务器响应较慢、短信客户端出现问题等诸多原因购买者不能正常收到短信&#xff0c;那么此时是…

Java如何解决高并发的问题? 可以试试这些方法

大家好&#xff0c;我是小武&#xff0c;一个工作10年的程序员&#xff0c;就职于鹅厂&#xff0c;平时喜欢搞搞副业。 在工作中&#xff0c;我们经常会遇到高并发的问题&#xff0c;这个是很常见的&#xff0c;只要用户访问量一多的情况下&#xff0c;那么我们的网站就会变慢&…

单例模式的五种写法

设计模式&#xff08;Design pattern&#xff09;&#xff0c;提供了在软件开发过程中面临的一些问题的最佳解决方案&#xff0c;是Java开发者必修的一门课程。主要分创建型模式、结构型模式和行为型模式。其中接下来我们要写的是单例模式&#xff0c;属于创建型模式。 单例模式…

JAVA单例模式代码实现

JAVA常见的设计模式之单例模式 懒汉模式 懒汉式是典型的时间换空间&#xff0c;也就是每次获取实例都会进行判断&#xff0c;看是否需要创建实例&#xff0c;浪费判断的时间。当然&#xff0c;如果一直没有人使用的话&#xff0c;那就不会创建实例&#xff0c;则节约内存空间(…

单例模式编写

单例">什么是单例 单例是保证一个内存/进程里只有一个类的实例&#xff0c;并提供一个访问它的全局访问点。 内存/进程中只有一个实例线程安全性能优化防止序列化产生新对象 写一个单例模式 1、饿汉模式 public class Singleton {//饿汉模式private static Single…

设计模式——单例模式八种方式实现与分析(附代码示例)

一. 概念 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法&#xff08;静态方法&#xff09;。 单例模式保证了系统内存中该类只存在一个对象&#xf…

C++ 单例模式 代码详解

单例模式 单例模式&#xff08;Singleton Pattern&#xff09;是 最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被…

[设计模式] -- 单例模式

Emai : hahayacodergmail.com 背景 最近在公司的项目中&#xff0c;经常会用到单例模式&#xff0c;由于之前没有想过怎么正确使用单例模式&#xff0c;导致写成的程序中有BUG。在学习Cocos2d-x时&#xff0c;导演类CCDirector等都是单例类。所以从头开始学习单例模式。 介绍 …

单例模式介绍

目录 1 前言 2 单例模式类型 2.1 饿汉式&#xff1a; 2.2 懒汉式&#xff1a; 2.2.1 双重检查锁 2.2.2 volatile防止指令重排 2.3 静态内部类 3 破坏单例 1 前言 单例模式是指在内存中有且只会创建一次对象的设计模式&#xff0c;在程序中多次使用同一个对象且作用相同…

单例模式详解(附常见的7种单例模式源码)

单例模式&#xff08;Singleton Pattern&#xff09;:保证一个类仅有一个对象&#xff0c;并提供一个访问它的全局访问点。(Ensure a class only has one instance,and provide a globe point of access to it.) 常见应用场景&#xff1a; Windows的Task Manager&#xff08;…

设计模式(一)—单例模式(附Java代码)

单例模式&#xff08;Singleton Pattern&#xff09;:采取一定的方法保证在整个的软件系统中&#xff0c;对于某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其实例对象的方法。 比如Hibernate的SessionFactory&#xff0c;它充当数据存储源的代理&#xff0c;…

线程的运行状态

不管是多线程还是多进程&#xff0c;实际上都不太可能一直占用CPU资源&#xff0c;所有多线程的几种状态一定要掌握。 多线程的状态如下图&#xff1a; 所有的系统费资源是有限的&#xff0c;不管是多线程还是多进程都必须在执行一段时间后让出资源&#xff0c;交由其他的线程…

一条SQL语句统计总数及各状态数

需求&#xff1a;共有协议X份&#xff0c;已签XX份&#xff0c;待签X份 sql: select count(1) 总记录数,sum(case when XY_STATUS1 then 1 else 0 end)待签,sum(case when XY_STATUS2 then 1 else 0 end)已签 from YG.T_ZHGL 结果&#xff1a; count(1):所有数据&#xff…

线程的执行状态

1,创建&#xff1a; 当创建好线程对象的时候&#xff0c;也就是new Thread类或者是new Thread子类的时候。此时称为创建状态 2&#xff0c;就绪&#xff1a; 当线程对象调用了start&#xff08;&#xff09;方法&#xff0c;开启线程了的时候&#xff0c;此时的线程已经开启了&…

Java线程线程的状态

1、线程的状态 线程有六种状态&#xff1a;分别如下 ① NEW(新建) 线程刚被创建&#xff0c;但是并未启动。还没调用start方法 ② Runnable(可运行) 线程可以在java虚拟机中运行的状态&#xff0c;可能正在运行自己代码&#xff0c;也可能没有&#xff0c;这取决于操作系统…

Java多线程批量执行sql

当遇到大sql批量导入时几十万上百万数据&#xff0c;使用plsql执行等都是非常的慢。因此开发一套自定义线程池处理sql&#xff1a; 1&#xff0c;线程代码 import java.util.ArrayList;/*** ClassName: com.ai.order.esb.yulang.tools.handle* Description: TODO* version: v1…