1 如何保障MySQL和Redis的数据一致性-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何保障MySQL和Redis的数据一致性

Linux爱好者 来源:Linux爱好者 2023-03-14 16:48 次阅读

我直接先抛一下结论:在满足实时性的条件下,不存在两者完全保存一致的方案,只有最终一致性方案。根据网上的众多解决方案,总结出 6 种,直接看目录:

a0f40be6-c23a-11ed-bfe3-dac502259ad0.png

不好的方案

1. 先写 MySQL,再写 Redis

a114271e-c23a-11ed-bfe3-dac502259ad0.png

图解说明:

这是一副时序图,描述请求的先后调用顺序;

橘黄色的线是请求 A,黑色的线是请求 B;

橘黄色的文字,是 MySQL 和 Redis 最终不一致的数据;

数据是从 10 更新为 11;

后面所有的图,都是这个含义,不再赘述。

请求 A、B 都是先写 MySQL,然后再写 Redis,在高并发情况下,如果请求 A 在写 Redis 时卡了一会,请求 B 已经依次完成数据的更新,就会出现图中的问题。

这个图已经画的很清晰了,我就不用再去啰嗦了吧,不过这里有个前提,就是对于读请求,先去读 Redis,如果没有,再去读 DB,但是读请求不会再回写 Redis。大白话说一下,就是读请求不会更新 Redis。

2. 先写 Redis,再写 MySQL

a12d47a8-c23a-11ed-bfe3-dac502259ad0.png

同“先写 MySQL,再写 Redis”,看图可秒懂。

3. 先删除 Redis,再写 MySQL

这幅图和上面有些不一样,前面的请求 A 和 B 都是更新请求,这里的请求 A 是更新请求,但是请求 B 是读请求,且请求 B 的读请求会回写 Redis。

a13a6500-c23a-11ed-bfe3-dac502259ad0.png

请求 A 先删除缓存,可能因为卡顿,数据一直没有更新到 MySQL,导致两者数据不一致。

这种情况出现的概率比较大,因为请求 A 更新 MySQL 可能耗时会比较长,而请求 B 的前两步都是查询,会非常快。

好的方案

4. 先删除 Redis,再写 MySQL,再删除 Redis

对于“先删除 Redis,再写 MySQL”,如果要解决最后的不一致问题,其实再对 Redis 重新删除即可,这个也是大家常说的“缓存双删”。

a1534084-c23a-11ed-bfe3-dac502259ad0.png

为了便于大家看图,对于蓝色的文字,“删除缓存 10”必须在“回写缓存10”后面,那如何才能保证一定是在后面呢?网上给出的第一个方案是,让请求 A 的最后一次删除,等待 500ms。

对于这种方案,看看就行,反正我是不会用,太 Low 了,风险也不可控。

那有没有更好的方案呢,我建议异步串行化删除,即删除请求入队列

a1737ae8-c23a-11ed-bfe3-dac502259ad0.png

异步删除对线上业务无影响,串行化处理保障并发情况下正确删除。

如果双删失败怎么办,网上有给 Redis 加一个缓存过期时间的方案,这个不敢苟同。个人建议整个重试机制,可以借助消息队列的重试机制,也可以自己整个表,记录重试次数,方法很多。

简单小结一下:

“缓存双删”不要用无脑的 sleep 500 ms;

通过消息队列的异步&串行,实现最后一次缓存删除;

缓存删除失败,增加重试机制。

5. 先写 MySQL,再删除 Redis

a17d1878-c23a-11ed-bfe3-dac502259ad0.png

对于上面这种情况,对于第一次查询,请求 B 查询的数据是 10,但是 MySQL 的数据是 11,只存在这一次不一致的情况,对于不是强一致性要求的业务,可以容忍。(那什么情况下不能容忍呢,比如秒杀业务、库存服务等。)

当请求 B 进行第二次查询时,因为没有命中 Redis,会重新查一次 DB,然后再回写到 Reids。

a1aec828-c23a-11ed-bfe3-dac502259ad0.png

这里需要满足 2 个条件:

缓存刚好自动失效;

请求 B 从数据库查出 10,回写缓存的耗时,比请求 A 写数据库,并且删除缓存的还长。

对于第二个条件,我们都知道更新 DB 肯定比查询耗时要长,所以出现这个情况的概率很小,同时满足上述条件的情况更小。

6. 先写 MySQL,通过 Binlog,异步更新 Redis

这种方案,主要是监听 MySQL 的 Binlog,然后通过异步的方式,将数据更新到 Redis,这种方案有个前提,查询的请求,不会回写 Redis。

a1d5bc94-c23a-11ed-bfe3-dac502259ad0.png

这个方案,会保证 MySQL 和 Redis 的最终一致性,但是如果中途请求 B 需要查询数据,如果缓存无数据,就直接查 DB;如果缓存有数据,查询的数据也会存在不一致的情况。

所以这个方案,是实现最终一致性的终极解决方案,但是不能保证实时性。

几种方案比较

我们对比上面讨论的 6 种方案:

先写 Redis,再写 MySQL

这种方案,我肯定不会用,万一 DB 挂了,你把数据写到缓存,DB 无数据,这个是灾难性的;

我之前也见同学这么用过,如果写 DB 失败,对 Redis 进行逆操作,那如果逆操作失败呢,是不是还要搞个重试?

先写 MySQL,再写 Redis

对于并发量、一致性要求不高的项目,很多就是这么用的,我之前也经常这么搞,但是不建议这么做;

当 Redis 瞬间不可用的情况,需要报警出来,然后线下处理。

先删除 Redis,再写 MySQL

这种方式,我还真没用过,直接忽略吧。

先删除 Redis,再写 MySQL,再删除 Redis

这种方式虽然可行,但是感觉好复杂,还要搞个消息队列去异步删除 Redis。

先写 MySQL,再删除 Redis

比较推荐这种方式,删除 Redis 如果失败,可以再多重试几次,否则报警出来;

这个方案,是实时性中最好的方案,在一些高并发场景中,推荐这种。

先写 MySQL,通过 Binlog,异步更新 Redis

对于异地容灾、数据汇总等,建议会用这种方式,比如 binlog + kafka,数据的一致性也可以达到秒级;

纯粹的高并发场景,不建议用这种方案,比如抢购、秒杀等。

个人结论:

实时一致性方案:采用“先写 MySQL,再删除 Redis”的策略,这种情况虽然也会存在两者不一致,但是需要满足的条件有点苛刻,所以是满足实时性条件下,能尽量满足一致性的最优解。

最终一致性方案:采用“先写 MySQL,通过 Binlog,异步更新 Redis”,可以通过 Binlog,结合消息队列异步更新 Redis,是最终一致性的最优解。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    7002

    浏览量

    88937
  • 缓存
    +关注

    关注

    1

    文章

    239

    浏览量

    26669
  • MySQL
    +关注

    关注

    1

    文章

    804

    浏览量

    26526
  • Redis
    +关注

    关注

    0

    文章

    374

    浏览量

    10871

原文标题:几种方案比较

文章出处:【微信号:LinuxHub,微信公众号:Linux爱好者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    串行数据一致性测试和验证测量基础知识

    小弟这次给大家带来了串行数据一致性测试和验证测量基础知识其中提到了些高速串行信号的测试测量方法和简单的原理性介绍,适合初学者使用。PS。这其中提到的些测量设备现在已经升级为最新的仪器设备,但是测试的原理和技术还是可以让大家闲
    发表于 04-16 16:17

    Redis缓存和MySQL数据一致原因和解决方案

    高并发架构系列:Redis缓存和MySQL数据一致性方案详解
    发表于 03-27 15:55

    一致性非锁定读分析

    MySQL探秘(六)InnoDB一致性非锁定读
    发表于 09-17 08:39

    如何解决stm32 H7 DMA串口发送数据一致性问题?

    如何解决stm32 H7 DMA串口发送数据一致性问题?
    发表于 12-06 06:05

    VxWorks中主备数据一致性功能组件的设计与实现

    数据一致性是主备用系统必须解决的问题。目前主备系统的一致性都采用手工编程来实现。导致代码结构繁杂,且效率不高。利用VxWorks的异常处理机制,结合RISC CPU的特性.设
    发表于 12-16 14:21 5次下载

    VxWorks中主备数据一致性功能组件的设计与实现

    数据一致性是主备用系统必须解决的问题。目前主备系统的一致性都采用手工编程来实现,导致代码结构繁杂,且效率不高。利用VxWorks 的异常处理机制,结合RISC CPU 的特性,设计实
    发表于 09-22 11:32 8次下载

    VxWorks中主备数据一致性功能组件的设计与实现

    数据一致性是主备用系统必须解决的问题。目前主备系统的一致性都采用手工编程来实现。导致代码结构繁杂,且效率不高。利用VxWorks的异常处理机制,结合RISC CPU的特性.设计
    发表于 11-28 16:47 11次下载

    P2P平台上的数据一致性研究

    P2P网络是个自组织的动态网络,对等点可以随意的加入或者离开网络,因此如何控制数据一致性成了P2P网络平台应用扩展应用的关键点,本文引入数据一致性算法到P2P网络平台中来,
    发表于 02-25 16:06 15次下载

    串行数据一致性及验证基础指南

    本基础指南旨在帮助您了解串行数据传输的般方面,并介绍适用于这些新兴串行技术的模拟和数字测量要求。 串行数据一致性测试和验证测量基础知识本手册将帮助您理解串行
    发表于 08-05 15:14 32次下载

    电能质量监测数据一致性定义及检测方法_邱丽羚

    电能质量监测数据一致性定义及检测方法_邱丽羚
    发表于 01-08 11:07 0次下载

    分布式系统的CAP和数据一致性模型

    CAP理论的核心思想是任何基于网络的数据共享系统最多只能满足数据一致性(Consistency)、可用(Availability)和网络分区容忍(Partition Tolerance)三个特性中的两个。
    的头像 发表于 05-05 23:20 2265次阅读

    redismysql如何保持数据一致性

    RedisMySQL是两个常用的数据库系统,它们都有自己的特点和用途。在某些场景下,我们可能需要将RedisMySQL进行结合使用,并保
    的头像 发表于 11-16 11:27 927次阅读

    Redis缓存与Mysql如何保证一致性

    基本流程就是客户端A请求,先去删除缓存,然后将数据写入数据库,此时客户端B查询先去查询缓存,缓存没有返回,去查数据库,此时还没有完成主从同步,拿到是从库的旧数据,然后将旧
    的头像 发表于 12-02 14:23 920次阅读
    <b class='flag-5'>Redis</b>缓存与<b class='flag-5'>Mysql</b>如何保证<b class='flag-5'>一致性</b>?

    redis集群中的hash一致性算法的理解

    Redis集群是种为了增强Redis的可扩展性和高可用而设计的集群方案。在Redis集群中,一致性
    的头像 发表于 12-04 10:45 746次阅读

    深入理解数据备份的关键原则:应用一致性与崩溃一致性的区别

    深入理解数据备份的关键原则:应用一致性与崩溃一致性的区别 在数字化时代,数据备份成为了企业信息安全的核心环节。但在备份过程中,两个关键概念——应用
    的头像 发表于 03-11 11:29 898次阅读
    深入理解<b class='flag-5'>数据</b>备份的关键原则:应用<b class='flag-5'>一致性</b>与崩溃<b class='flag-5'>一致性</b>的区别