如何保证 Redis 缓存和数据库的一致性?

news/2025/3/1 15:01:57/文章来源:https://www.cnblogs.com/Abner-rudolf/p/18744870

如何保证 Redis 缓存和数据库的一致性?

1. 问题出现场景

  1. 先修改数据库,再删除缓存

    删除数据库数据成功了,但是删除缓存却失败了,缓存中仍保留的是旧数据

  2. 先删除缓存,再删除数据库

    如果 Redis 缓存删除成功后,假如数据库数据还没来得及更新,用户又请求数据,这时就会从数据库中读取旧的值,存入到 Redis 中,用户查到的数据依旧是旧的数据。


2. 解决方案

2.1 双写事务

原理:利用 Redis 的事务特性,或是数据库的事务特性,把 Redis 操作和数据库操作放到同一个事务中去执行,同时提交或回滚,最大程度上保证 Redis 缓存和数据库的一致。

  1. 优点:实现简单、不复杂,能够保证一定的一致性

  2. 缺点:

    Redis 和数据库本质不是同一种数据库,所以无法通过事务来保证它们之间完全的一致性

适合小型系统的简单读写,不适合高并发系统。

2.2 延迟双删

原理:当完成数据库的更新时,立即删除 Redis 缓存,为了确保数据更新的稳妥,延迟一定时间后(例如 1s、2s),再次对缓存进行删除。

目的:避免并发操作导致缓存脏数据的问题出现

  1. 优点:实现简单,能够解决大部分场景下短时间数据不一致的情况
  2. 缺点:延迟时间非常难以精确控制,如果操作量比较大,可能还会出现覆盖的风险

2.3 订阅更新机制

原理:当数据库更新,会向消息队列发送一条消息,Redis 通过订阅这个消息队列,来更新缓存数据,这样会让更新和缓存的清除变得非常及时。

  1. 优点:同步效果非常好
  2. 缺点:系统的复杂度会增加,消息队列本身需要一些可靠性,也是需要一些维护成本

2.4 读写分离架构

高并发场景应用非常广泛

原理:把写操作全部直接操作数据库,然后通过一个异步线程、后台服务、定时任务,去更新 Redis 缓存,从而实现数据的一致性。

  1. 优点:缓存压力降低很多,特别适合大数据流量的系统
  2. 缺点:项目开发比较复杂,因为要做好这种异步的逻辑的处理

2.5 Canal 订阅 Binlog 同步 Redis

原理:修改数据库的同时,数据库的操作会同时写入到 Binlog 中,这时可以通过 Canal 中间键,来订阅 Binlog 的一些变化,如果监听到数据库变化之后,把更新的数据同步通知给 Redis,来更新 Redis 的缓存


3. 总结

3.1 哪儿种方案更好?

具体选择哪儿种解决方案,要根据具体业务场景、项目的需求,以及整体的架构等多种因素去综合考虑,比如是否是高并发、是否要考虑低延迟等等因素。

脱离业务谈技术,就是耍流氓。

3.2 归纳

虽然这几种解决方案,可以在一定程度上解决 Redis 和数据库不一致的情况,但是在实际情况种,还要结合业务,来判断项目中是否真的需要,或是项目中可以使用 Redis。如果业务需要强一致性,例如银行、股票等业务,其实不使用 Redis 其实也是一种很好的方案。


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

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

相关文章

PowerShell开发小工具 四张照片拼成一张

小工具的设计与实现------选四张照片拼成一张照片。 很经典的应用情景,市面上有很多类似的小软件,特别是手机应用。为了方便学习巩固PowerShell,今天笔者使用它来实现。【设计思路】选择四张符合要求的照片或图片[.jpg] [.png] 准备画布,计算其子区域(画布四分之一)宽高比…

Python123画一个五星红旗

点击查看代码 import turtle import math# 初始化画布(推荐设置600x400显示区域) screen = turtle.Screen() screen.colormode(1.0) t = turtle.Turtle() t.speed(10) t.hideturtle()# 国旗标准参数 FLAG_WIDTH = 600 # 旗面宽度 FLAG_HEIGHT = 400 # 严格3:2比例…

擦除0地址codeflash营造空片现象_重新上电即可进入BootLoader程序

芯片在空片时,首次插入USB供电会直接在ISP工具中搜索到USB设备,可以进行首次烧录;原因是在0地址没有用户程序,所以会在停留在boot区域; 利用该特性,可以在固件中加入一些处理,比如USB OUT端点透传数据给芯片,解析成功后,使用FLASH_ROM_ERASE接口擦除0地址数据,此后给…

探秘Transformer之(8)--- 位置编码

从零开始解析Transformer,目标是:(1) 解析Transformer如何运作,以及为何如此运作,让新同学可以入门;(2) 力争融入一些比较新的或者有特色的论文或者理念,让老鸟也可以有所收获。探秘Transformer之(8)--- 位置编码 目录探秘Transformer之(8)--- 位置编码0x00 概述0x01…

day11 用户的管理篇

day11用户的管理篇不同的用户,在不同的目录下,操作不同的文件权限是不一样的用户的路的机器该文件和用户的关系是什么在单位里运维作为服务器的管理员,root权限是有的 而开发,测试,他们是不可能有root权限的 即使需要使用root权限,运维会给他配置(临时使用管理员身份运行…

idea无法跳转到jar包里面的代码

需要添加到library 右键点击jar包,然后添加到library

【vulhub】tomcat CVE-2017-12615(任意写入文件)

CVE-2017-12615 tomcat 任意写入文件 漏洞复现渗透环境 攻击机: 192.168.66.130(Kali) 漏洞收录于:vulhub/tomcat/CVE-2017-12615 涉及知识点:tomcat任意文件写入 漏洞详情 当 Tomcat 运行在 Windows 系统且启用了 HTTP PUT 方法(通过将 readonly 参数设置为 false)时…

太阳花2

from turtle import * color(red,yellow) begin_fill() while True:forward(200)left(170)if abs(pos()) < 1:breakend_fill()done()

reDuh工具:实现端口复用(附下载链接)

本文来自无问社区成员,村口一枝花投稿。 一、端口复用的知识点 有关端口复用的知识点,深入学习一下。存在的安全隐患所指的是在同一个端口上建立了与多个服务之间的连接,在实际场景下多用于绕过防火墙的端口限制。 二、场景设立实验环境 靶机 B 在内网当中,而防火墙只开放了…

【Java免杀】异或加密 (XOR Cipher)实现WebShell免杀

异或加密是一种对每个字符执行位操作的加密方法。通过与一个密钥进行异或运算,明文会被加密,且加密后的文本可以通过相同的密钥再次进行异或解密。 一、加密与解密示例: <%! public static String xorEncryptDecrypt(String text, char key) {StringBuilder result = new…

大厂开源项目,真的太爽啦,字节跳动出品!这个设计系统开源神器,让你的产品颜值与效率齐飞

Semi Design是由抖音前端团队开源的企业级设计系统,**同时支持React/Vue双框架**,提供超过60+高质量组件。不同于普通UI库,它从**设计工程化**角度出发,打通Figma设计资源与前端代码的桥梁,真正实现设计稿到代码的"零误差还原"。目前已在字节跳动200+项目中验证…

微信小程序安装VantWeapp组件

1、网址 https://vant-ui.github.io/vant-weapp/#/popup 2、安装教程:点击快速上手 这里我们通过 npm i @vant/weapp -S --production 来安装 1、右键点开 app.js 点 在内建终端中打开 2、把 npm i @vant/weapp -S --production 放到这里来 按回车安装完成后显示这个 3…