如何解决Redis缓存和MySQL数据一致性的问题?[通俗易懂]

如何解决Redis缓存和MySQL数据一致性的问题?

大家好,又见面了,我是全栈君。

在高并发的业务场景下,数据库的性能瓶颈往往都是用户并发访问过大。所以,一般都使用redis做一个缓冲操作,让请求先访问到redis,而不是直接去访问MySQL等数据库。从而减少网络请求的延迟响应

如何解决Redis缓存和MySQL数据一致性的问题?[通俗易懂]

数据为什么会不一致

这样的问题主要是在并发读写访问的时候,缓存和数据相互交叉执行。

一、单库情况下

同一时刻发生了并发读写请求,例如为A(写) B (读)2个请求

如何解决Redis缓存和MySQL数据一致性的问题?[通俗易懂]

  1. A请求发送一个写操作到服务端,第一步会淘汰cache,然后因为各种原因卡主了,不在执行后面业务(例:大量的业务操作、调用其他服务处理消耗了1s)。

  2. B请求发送一个读操作,读cache,因为cache淘汰,所以为空

  3. B请求继续读DB,读出一个脏数据,并写入cache

  4. A请求终于执行完全,在写入数据到DB

    总结:因最后才把写操作数据入DB,并没同步。cache里面一直保持脏数据

    脏数据是指源系统中的数据不在给定的范围内或对于实际业务毫无意义,或是数据格式非法,以及在源系统中存在不规范的编码和含糊的业务逻辑。

二、主从同步,读写分离的情况下,读从库而产生脏数据

如何解决Redis缓存和MySQL数据一致性的问题?[通俗易懂]

  1. A请求发送一个写操作到服务端,第一步会淘汰cache

  2. A请求写主数据库,写了最新的数据。

  3. B请求发送一个读操作,读cache,因为cache淘汰,所以为空

  4. B请求继续读DB,读的是从库,此时主从同步还没同步成功。读出脏数据,然后脏数据入cache

  5. 最后数据库主从同步完成

    总结:这种情况下请求A和请求B操作时序没问题,是主从同步的时延问题(假设1s),导致读请求读取从库读到脏数据导致的不一致

根本原因:

单库下,逻辑处理中消耗1s。可能读到旧数据入缓存

主从+读写分离,在1s的主从同步时延中。读到从库的旧数据入缓存

 

数据优化方案

如何解决Redis缓存和MySQL数据一致性的问题?[通俗易懂]

一、缓存双淘汰法

  1. 先淘汰缓存

  2. 再写数据库

  3. 往消息总线esb发送一个淘汰消息,发送立即返回。写请求的处理时间几乎没有增加,这个方法淘汰了缓存两次。因此被称为“缓存双淘汰法“,而在消息总线下游,有一个异步淘汰缓存的消费者,在拿到淘汰消息在1s后淘汰缓存,这样,即使在一秒内有脏数据入缓存,也能够被淘汰掉。

二、异步淘汰缓存

上述的步骤,都是在业务线里面执行,新增一个线下的读取binlog异步淘汰缓存模块,读取binlog总的数据,然后进行异步淘汰。

如何解决Redis缓存和MySQL数据一致性的问题?[通俗易懂]

1.思路:

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

1)读请求走Redis:热数据基本都在Redis

2)写请求走MySQL: 增删改都操作MySQL

3)更新Redis数据:MySQ的数据操作binlog,来更新到Redis

2.Redis更新

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

  • 一个是全量(将全部数据一次写入到redis)

  • 一个是增量(实时更新)

这里说的是增量,指的是mysql的update、insert、delate变更数据。

这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis,Redis再根据binlog中的记录,对Redis进行更新。就无需在从业务线去操作缓存内容

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111871.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • docker 入门_docker高级教程

    docker 入门_docker高级教程一、docker概述1.什么是dockerDocker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似iPhone的app),更重要的是容器性能开销极低。Docker从17.03版本之后分为CE(CommunityEdition:社区版)和E..

    2022年10月15日
    0
  • Win10安装wget_linux wget安装

    Win10安装wget_linux wget安装安装下载点击下载依次如下:1.2、将下载好的wget.exe放到C:/windows/system32文件夹下3.3、在cmd中输入wget–version如下则成功:测试下载图片wgethttp://q1.xiongmaoya.com/2021/08/09/26045/1.jpg

    2022年10月17日
    0
  • 孙鑫的java_孙鑫java视频教程「建议收藏」

    孙鑫的java_孙鑫java视频教程「建议收藏」近几年来,提到java相信很多人都不陌生了吧,Java技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于个人PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网。也正是由于互联网的快速发展,学习java的人也是越来越多了。需要注意的是,java和我们平时学习的其它计算机语言还是有区别的。Java不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节…

    2022年5月17日
    41
  • linux重命名文件名_linux 文件重命名

    linux重命名文件名_linux 文件重命名https://blog.csdn.net/weixin_33724570/article/details/91909917https://blog.csdn.net/csdnnews/article/details/87927567https://blog.csdn.net/weixin_34329187/article/details/93004715https://blog…

    2022年9月10日
    0
  • Json的FastJson与Jackson

    Json的FastJson与JacksonJson的FastJson与Jackson

    2022年4月22日
    69
  • idea设置springboot热部署

    idea设置springboot热部署一.由于使用springboot开发时,需要经常修改代码,但是每次的修改需要重启springboot的启动类才能生效,所以我们需要设置成热部署的方式,大大减少启动时间,提高开发效率.二.设置热启动包括两方面:(1)在pom.xml文件中添加热部署的依赖<dependency><groupId>org.springfra…

    2022年5月4日
    171

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号