Redis【13】-修改数据库后,如何保证Redis与数据库的数据一致性

news2024/11/15 11:40:36

一、需求起因

在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库。
这个业务场景,主要是解决读数据从Redis缓存,一般都是按照下图的流程来进行业务操作。

在这里插入图片描述 


读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。

不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。举一个例子

1.如果删除了缓存Redis,还没有来得及写库MySQL,另一个线程就来读取,发现缓存为空,则去数据库中读取数据写入缓存,此时缓存中为脏数据。

2.如果先写了库,在删除缓存前,写库的线程宕机了,没有删除掉缓存,则也会出现数据不一致情况。

因为写和读是并发的,没法保证顺序,就会出现缓存和数据库的数据不一致的问题。

如来解决?这里给出两个解决方案,先易后难,结合业务和技术代价选择使用。

二、缓存和数据库一致性解决方案

1.第一种方案:采用延时双删策略

在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。

伪代码如下:

public void write(String key,Object data){
 redis.delKey(key);
 db.updateData(data);
 Thread.sleep(500);
 redis.delKey(key);


具体的步骤就是:

  1. 先删除缓存;
  2. 再写数据库;
  3. 休眠500毫秒;
  4. 再次删除缓存。

那么,这个500毫秒怎么确定的,具体该休眠多久呢?

需要评估自己的项目的读数据业务逻辑的耗时。这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。

当然这种策略还要考虑redis和数据库主从同步的耗时。最后的的写数据的休眠时间:则在读数据业务逻辑的耗时基础上,加几百ms即可。比如:休眠1秒。

设置缓存过期时间

从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。所有的写操作以数据库为准,只要到达缓存过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。

该方案的弊端

结合双删策略+缓存超时设置,这样最差的情况就是在超时时间内数据存在不一致,而且又增加了写请求的耗时。

2、第二种方案:异步更新缓存(基于订阅binlog的同步机制)

技术整体思路:

MySQL binlog增量订阅消费+消息队列+增量数据更新到redis

读Redis:热数据基本都在Redis
写MySQL:增删改都是操作MySQL
更新Redis数据:MySQ的数据操作binlog,来更新到Redis

Redis更新 

1)数据操作主要分为两大块:

一个是全量(将全部数据一次写入到redis)
一个是增量(实时更新)
这里说的是增量,指的是mysql的update、insert、delate变更数据。

2)读取binlog后分析 ,利用消息队列,推送更新各台的redis缓存数据。

这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis,Redis再根据binlog中的记录,对Redis进行更新。

其实这种机制,很类似MySQL的主从备份机制,因为MySQL的主备也是通过binlog来实现的数据一致性。

这里可以结合使用canal(阿里的一款开源框架),通过该框架可以对MySQL的binlog进行订阅,而canal正是模仿了mysql的slave数据库的备份请求,使得Redis的数据更新达到了相同的效果。

当然,这里的消息推送工具你也可以采用别的第三方:kafka、rabbitMQ等来实现推送更新Redis。


原文链接:https://blog.csdn.net/m0_67391683/article/details/126565681

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

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

相关文章

ARM 代码重定位实战

前言 任务 在 SRAM 中将代码从 0xd0020010 重定位到 0xd0024000。任务解释:本来代码是运行在0xd0020010的,但是因为一些原因我们又希望代码实际是在0xd0024000位置运行 的。这时候就需要重定位了。注解:本练习对代码本身运行无实际意义&…

你都工作两年半了,还不会RabbitMQ?

What is rabbitMQ ? RabbitMQ 是一个由 Erlang 语言开发的 AMQP(高级消息队列协议) 的开源实现。 RabbitMQ 是轻量级且易于部署的,能支持多种消息协议。 RabbitMQ 可以部署在分布式和联合配置中,以满足高规模、高可用性的需求。 具体特点包括…

ADI Blackfin DSP处理器-BF533的开发详解29:TOUCH_LINE(屏幕画线)(含源代码)

硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 硬件设计原理图 功能介绍 代码实现了读取触摸屏坐标,并将触摸屏坐标换算为液晶屏的显示坐标,将像素点显示到触摸坐标的位…

学习Python中turtle模块的基本用法(4:绘制科赫曲线和谢尔宾斯基三角形)

科赫曲线和谢尔宾斯基三角形是常见的分形图形(详细介绍见参考文献1),本文使用turtle库绘制这两类图形。 科赫曲线 科赫曲线的详细介绍见参考文献2,其中的绘图思路是“画正三角形,并把每一边三等分,取三等分后的一边中…

【LeetCode】Day194-超级丑数

题目 313. 超级丑数【中等】 题解 之前做过丑数,规定丑数是质因数只包含2,3,5的正整数,而这道题丑数升级为超级丑数,规定为包含的质因数是在primes数组中的正整数 丑数的题解用动态规划,那么超级丑数也可以利用相同的方法解答…

CSS -- CSS元素显示模式总结(块元素,行内元素,行内块元素)

文章目录CSS 的元素显示模式1 什么是元素显示模式2 块元素3 行内元素4 行内块元素5 元素的显示模式总结CSS 的元素显示模式 1 什么是元素显示模式 作用:网页的标签非常多,在不同地方会用到不同类型的标签,了解他们的特点可以更好的布局我们…

[附源码]JAVA毕业设计-学生宿舍故障报修管理信息系统-(系统+LW)

[附源码]JAVA毕业设计-学生宿舍故障报修管理信息系统-(系统LW) 项目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff…

开源即巅峰,《Java程序性能优化实战》GitHub三小时标星已超34k

蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力、培训、出国、大公司的经历,还有很多很好的朋友。但再仔细一想,这十年中我至少浪费了五年时间,这五年可以足够让自己成长为一个优秀的程序员,…

项目设置分页条件查询接口

一、分页 1、HospPlusConfig中配置分页插件1 /** 2 * 分页插件 3 */ 4 Bean 5 public PaginationInterceptor paginationInterceptor() { 6 return new PaginationInterceptor(); 7 }2、分页Controller方法 HospitalSetController中添加分页方法1 ApiOperation(value "分…

Python学习基础笔记四十二——序列化模块

1、序列化的概念: 序列:就是字符串。 序列化:将原本的字典、列表等内容转换成一个字符串数据类型的过程就叫做序列化。 反序列化:从字符串到数据类型的过程。 2、序列化的目的: 1、以某种存储形式使自定义的数据持…

servlet+Mysql实现的校园论坛管理系统(功能包含登录,首页帖子查看、发帖、个人帖子删除编辑、帖子评论回复、用户管理等)

博客目录servletMysql实现的校园论坛管理系统实现功能截图系统功能使用技术代码完整源码servletMysql实现的校园论坛管理系统 本系统是一个简单的校园论坛系统,学生可以在线发帖并进行帖子评论回复,同同时管理员可以对用户进行管理。 (文末查看完整源码…

win11: cmake+glfw+imgui

下载源码:imgui github地址 将需要的文件拖拽入项目外部库的imgui文件夹 backends文件夹里选择与环境适配的文件,我这里用了glfw和opengl3 目录结构: CMakeLists.txt cmake_minimum_required(VERSION 3.24) project(proforlearn) set(CM…

基于java+springmvc+mybatis+jsp+mysql的实验室计算机故障报修系统

项目介绍 本系统采用java语言开发,后端采用ssm框架,前端采用jsp技术,数据库采用mysql进行数据存储。 前端页面: 功能:首页、设备信息、公告资讯、个人中心、后台管理、联系客服 管理员后台页面: 功能&…

电子学会2020年12月青少年软件编程(图形化)等级考试试卷(二级)答案解析

目录 一、单选题(共25题,每题2分,共50分) 二、判断题(共10题,每题2分,共20分) 三、编程题【该题由测评师线下评分】(共2题,共30分) 青少年软件…

业务流程监控:让多维度监控有了灵魂

需求 《可视化业务流程监控,是解决方案更是运维之道!》一文让我们知道可以借助Grafana 两个插件:Diagram、FlowCharting,满足我们对于图形数据业务流程的可视化监控,但是在使用前需要我们做好以下两点工作&#xff1a…

修复自定义标题word题注错误:错误,文档中没有指定样式的文字以及编号无法随章节变化问题

一、单个修复指定章节号 假设采用自定义样式“毕业”,如果出现类似提示,可以具体操作如下: 光标定位与错误题注的位置,按shift F9 {STYLEREF 1 \s} - 2 将内容修改为 图 {STYLEREF "毕业" \s} - 2 右击,更…

被人叫做砖家模拟器的ChatGPT,它真的靠谱吗?

大家好啊,我是测评君,欢迎来到web测评。 前言 最近很热门的聊天机器人ChatGPT,据说五天时间用户就破了百万,这几天在体验过程中发现了一些问题,今天我就以下列几个方面来跟大家简单的交流下ChatGPT。 ChatGPT怎么注册国…

【博客555】prometheus的step,durations,rate interval,scrape interval对数据查询结果的影响

prometheus的step,durations,rate interval,scrape interval对数据查询结果的影响 1、场景:在查询prometheus数据时出现很多诡异的现象 1、为什么同样的查询语句在不同的时间点查询,对过去某一时刻的数据展示却不一样…

网络拓扑配置案例练习(VRRP,浮动路由,DCHP,三层交换机配置)

网络拓扑配置案例网络拓扑配置案例练习网络拓扑需求描述具体操作命令交换机创建vlan,配置access、trunk口,划分vlanvrrp配置路由配置验证vrrp和浮动路由DHCP配置总结网络拓扑配置案例练习 在这篇文章中将记录网络的常见配置:VRRP&#xff0c…

vue-cli和vue有什么区别

目录 1、什么是 Vue? 2、什么是vue-cli? 3、区别和关联 👉 区别 👉 关联 🍀 扩展知识 “vue-cli”和vue的区别:vue是“vue.js”的简称,是一个成熟的用于构建用户界面的JavaScript渐进式框…