如何实现Redis和Mysql中数据双写一致性

news2024/12/27 19:21:14

 在我们的实际开发中,我们用到了redis缓存一些常用的数据(如热点数据)用来提高系统的吞吐量。 但是不可以避免的出现了数据的修改场景,这就导致了数据库中的数据和Redis中出现不一致性的情况。如何保证数据一致性就显得非常重要了,下面介绍一下保证数据的双写一致性的方案。

   

1、先删缓存再操作数据库方案

    在redis一般写的场景下对数据的更新操作是不推荐使用的,推荐使用删除缓存数据的操作,因为删除操作的效率更高。下图展示先删除缓存再操作数据库的过程图:

图片

在这种方式下会存在数据不一致的问题,如下图所示:

图片

(1)线程1要更新数据,它先删除redis中的缓存数据,然后由于网络堵塞导致暂短的停顿,没有继续执行操作数据库 

(2)线程2要查询数据,首先查询数据库,但是由于Redis中的数据已经被线程1删除了,那么它会去数据库中查询数据X并且要将数据X同步到Redis中

(3)线程1网络堵塞结束,执行了数据库操作将数据X更改为Y

    经过上述的过程就导致了Redis的数据和数据库中的数据不一致了,即就是Redis中存放的依据是老数据。为了解决上述的问题,我们采用缓存延迟双删的策略,如下图所示的缓存延迟双删的过程:

图片

    采用缓存延迟双删策略最多在X毫秒内读取的数据是老数据,在X毫秒之后读取的数据都是最新的数据。X的具体值如何确定那就需要根据自身的业务了来确定。

    延迟双删策略只能保证最终的一致性,不能保证强一致性。由于对Redis的操作和Mysql的操作不是原子性操作,所以如果想保证数据的强一致性就需要加锁控制,如下图所示:

图片

    加锁之后势必会带来系统的吞吐量的下降,所以需要衡量利弊来确定是否使用加锁。

2、先操作数据库再删除缓存方案

图片

    此方案就是先操作数据库,数据库写入成功之后再来删除Redis缓存中的数据。多个线程之间的数据读取和更新如下图所示:

图片

    这种方案下,在数据库更新成功后到删除Redis缓存数据之前的这段时间中,其他线程读取的数据都是旧数据,等Redis删除缓存后会重新从数据库中读取最新数据同步到Redis,这样可以在一定程度上保证数据的最终一致性。极端情况下会出现数据不一致的情况,如下图所示:

图片

(1)线程1先成功的更新数据到数据库中,然后执行删除Redis缓存中的数据的时候失败了

(2)线程2要读取数据,此时优先从Redis中查询数据,由于此时Redis中老数据没有删除,所以线程2可以拿到旧数据直接返回。直到Redis中缓存的数据过期之后才可以从数据库中获取最新的到Redis中

3、删除重试机制

    无论是先删除缓存再操作数据还是先操作数据库再删除缓存的机制,都有可能会出现删除缓存失败的情况,如下图所示:

图片

    为了应对删除缓存失败的情况发生,于是加入了删除重试机制,如下图所示:

图片

    通过canal监听binlog感知数据的变动后,canal客户端执行删除Redis缓存数据,如果缓存数据删除失败那么发送一条MQ消息让canal客户端继续执行删除操作,这样可以保证数据的最终一致性。但是这样也增加了系统的复杂性。

4、总结:

(1)实际开发中推荐使用先操作数据库再删除缓存的方案,因为此方案最大程度上保证了数据的一致性并且实现也最简单。

(2)无论是先操作数据库再删除缓存还是先删除缓存再操作数据库都有可能会出现删除缓存失败的情况,所以需要加入删除重试机制。

(3)如果想要Redis和Mysql的数据强一致性,可以考虑使用加锁的方式实现。

5、实际应用

在实际应用中,我们一般会采取云服务器使用并处理实时同步RDS与Redis构建缓存一致性,可参考我的上一篇文章:实时同步RDS与Redis构建缓存一致性-CSDN博客

        通过DTS数据订阅能力,用户可以实时订阅RDS日志数据变更,并将其写入Redis以实现缓存数据的更新。这样的配置可以实现MySQL与Redis之间的缓存同步一致性,采用了Cache-Aside Pattern模式。通过DTS的服务化能力,用户可以保证高效、稳定和实时的数据同步。从而用户能够实现商品信息的实时同步,确保在系统中的商品信息始终是最新的。同时,对于账单信息的查询也能够变得高效,用户可以从Redis中获取已缓存的数据,减少对MySQL的频繁访问,提升查询性能。这样的解决方案不仅能够提高系统的响应速度,还能够保证数据的一致性和准确性,为用户提供更好的使用体验。

        我使用的服务器组合是云服务器ECS省钱攻略,可以试用。

        通过RDS MySQL+DTS+Redis的架构,实现RDS MySQL与Redis缓存之间的数据同步和一致性。通过实时同步MySQL数据库数据到Redis缓存,提高数据查询速度,降低数据库压力,确保业务数据的实时性和准确性。

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

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

相关文章

H3C智能管理中心byod/index.xhtml接口存在远程命令执行漏洞

@[toc] H3C智能管理中心byod/index.xhtml接口存在远程命令执行漏洞 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学…

C++基础编程的学习3

nullptr关键字 在C11之前,空指针通常用NULL或0表示。然而,这些表示方法存在类型安全问题。C11引入了nullptr关键字,它提供了一个明确的、类型安全的空指针值。 Lambda表达式 Lambda表达式是C11引入的一种便捷的匿名函数定义方式。当Lambda…

海量数据处理商用短链接生成器平台 - 12

第三十五章 微信支付Native订单API测试实战和签名流程解读 第1集 微信支付-快速验证参数配置方法和统一下单接口开发 简介:微信支付-快速验证参数配置方法和统一下单接口开发 接口文档 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml 编码实…

03_Electron 主进程和渲染进程、点击(拖放)打开文件功能

Electron 主进程和渲染进程 一、Electron 主进程和渲染进程二、Electron 主进程和渲染进程中使用 Nodejs 以及 Nodejs 第三方模块2.1、主进程中使用 Nodejs 模块2.2、渲染进程中 使用 Nodejs 模块2.3、BrowserWindow 中通过 preload加载的js 文件可以直接使用nodejs 模块2.4、渲…

大小仅为Rust四分之一!MoonBit 现已支持Wasm组件模型

使用 MoonBit 开发 Wasm 组件模型 Wasm组件 WebAssembly(Wasm)是一种新的低级虚拟指令集标准(low-level virtual instruction set standard),用于沙箱模型。低级的,意味着它接近原生速度。虚拟的&#xff…

全网最最最全的LVS详解!!!

1 LVS-集群和分布式 1.1 集群 LVS(Linux Virtual Server)集群,即Linux虚拟服务器集群,是一个在Unix/Linux平台下实现负载均衡集群功能的系统。它由国人章文嵩博士在1998年开发,是中国国内最早出现的自由软件项目之一…

yolov8 剪枝 - DepGraph

2024年8月5 5000张图片,2个类别。 yolov8n 初始: 185 layers, 3151904 parameters, 31936 gradients, 8.7 GFLOPs 经过三次finetune后: 185 layers, 2327024 parameters, 31936 gradients, 6.6 GFLOPs 经过第四次fintune后: …

“write()” 与 “ tcp缓冲区 ” 之间的关系

write()写入tcp缓冲区过程 write()将该文本写入到tcp缓冲区中本质是数据的拷贝,当write()调用完,数据不一定发给tcp发送缓冲区中 因为: 有没有拷贝成功,都不由write(&a…

史上最全Java初、中、高三级都适用的面试八股文(2024版含答案)

在Java编程的世界里,无论你是初出茅庐的新人,还是已经有一定经验的中级开发者,抑或是寻求突破的高级工程师,面试时总有一套通用的“八股文”知识点,就像是每位程序员的必备宝典。这套2024版的Java面试指南,…

mma.sync.aligned.m16n8k16.row.col.f16.f16.f16.f16测试

mma.sync.aligned.m16n8k16.row.col.f16.f16.f16.f16测试 1.参考文档2.numpy测试3.cuda kernel测试4.相关截图 本文演示了如何按PTX指令文档中的layout格式要求,加载数据,执行mma指令,并且跟numpy对比结果的一致性 1.参考文档 Matrix Fragments for mma.m16n8k16 with floatin…

MAVSDK添加自定义消息与函数实现云台(Gimbal)调整功能

1.找到action.proto文件并添加如下消息 2. 定义RPC方法AdjustGimbal方法如下: 3.运行generate_from_protos.sh重新根据.proto生成.cpp与.h文件 生成过程 生成完成 4. .proto生成的.h文件,成功包含同步与异步方法声明

零基础转行网络安全真的好就业吗?

网络安全作为近两年兴起的热门行业,成了很多就业无门但是想转行的人心中比较向往但是又心存疑惑的行业,毕竟网络安全的发展史比较短,而国内目前网安的环境和市场情况还不算为大众所知晓,所以到底零基础转行入门网络安全之后&#…

python自动化笔记:excel文件处理及日志收集

目录 一、openpyxl模块1.1、安装:pip install openpyxl1.2、openpyxl模块三大组件1.3、创建excel并写入数据1.4、读取excel 二、日志收集 一、openpyxl模块 1.1、安装:pip install openpyxl 注: openpyxl只支持xlsx格式,xls格式…

10+ Midjourney V6.1 提示:生成精美的角色海报

前言 近期图像生成界最大的更新是MidjourneyV6.1!我迫不及待地想要开始创作和分享,这次分享的重点是V6.1在角色创作方面的增强。 以下是半天测试的结果,包括提示,专注于角色摄影照片和角色插图。 网上关于这方面的教程虽然很多&…

【第22章】Spring Cloud之Gateway集成Knife4j(下)

文章目录 前言一、访问页面加权控制1. 加权控制2. 登录 二、生产环境如何屏蔽Knife4j、Swagger等Ui资源和接口1. 基于Spring Boot框架提供的Conditional条件控制相关Bean的生效2. 效果 三、聚合个性化配置1. 用户服务1.1 引入依赖1.2 Knife4j配置类1.3 控制器 2. 网关服务2.1 排…

JG08Z-GD系列 八轴智能测径仪系统介绍

1.测径仪: 主要用于轧制线,棒材,八个方向直径及椭圆度在线测量,轧制螺纹钢特钢尺寸在线测量。 2.功能介绍: (1)显示内容 主控室液晶显示器:管材截面的最大/最小直径、平均值、椭圆…

问题本记录(1):mac有网络但打不开网页

此学习类别,仅作为小许的问题本,方便后续再次遇到相关问题进行查看。 第一步: 第二步: 添加一个新的位置 第三步: 选择这个新建的位置,Wi-Fi显示已连接就 万事大吉啦啦啦

html+css+js+jquery实现一个 飘零的树叶

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>飘落的枫叶</title><style>.maple {position: absolute;top: 0;color: #ff0000;}</style><script src"https://www.jq22.com…

片上POR和BOR的区别

片上 POR 和 BOR 的区别 片上 POR&#xff08;Power On Reset&#xff09;和 BOR&#xff08;Brown-out Reset&#xff09;是微控制器中用于确保系统在电源异常情况下能够恢复正常运作的两种复位机制。 1. POR&#xff08;上电复位&#xff09; POR 是在微控制器上电时触发的…

多路RTSP转RTMP推送方案的两个选择

技术选型 RTSP转RTMP推送到流媒体服务器&#xff0c;说起来技术实现不难&#xff0c;简单来说&#xff0c;获取RTSP流后&#xff0c;拿到未经解码的H.264/H.265和audio数据&#xff0c;重新打包RTMP发送出去即可。需要注意的是&#xff0c;大多RTSP转RTMP模块&#xff0c;需要…