Redis---缓存双写一致性

这篇具有很好参考价值的文章主要介绍了Redis---缓存双写一致性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、什么是缓存双写一致性呢?

 1.1 双检加锁机制

 二、数据库和缓存一致性的更新策略

2.1、先更新数据库,后更新缓存

 2.2 、先更新缓存,后更新数据库

 2.3、先删除缓存,在更新数据库

延时双删的策略:

 2.4.先更新数据库,在删除缓存(常用)

2.5、实际中是不可能做到强一致性的,那么怎么做到最终一致性呢?

三、canal中间件

3.1   canal工作原理

3.2 MySQL的主从复制 


一、什么是缓存双写一致性呢?

  • 如果redis中有数据

    • 需要和数据库中的值相同
  • 如果redis中无数据

    • 数据库中的值是最新值,且准备回写redis

缓存按照操作分

  • 只读缓存    (就没有同步这一说法了)
  • 读写缓存
    • 同步直写策略   (比如比较紧急的事情,冲了vip得立即生效
      • 写数据库后也同步写 redis 缓存,缓存中的数据和数据库中的一致
      • 对于读写缓存来说,要想保证缓存和数据库中的数据一致
  • 异步缓写策略   (一般都是用这种)
    • 正常业务运行中,mysql数据变动了,但是可以在业务上容许出现一定时间后才作用于redis,比如仓库、物流系统
    • 异常情况出现了,不得不将失败的动作重新修补,有可能需要借助kafka或者RabbitMQ等消息中间件,实现重写重试

Redis---缓存双写一致性,缓存,redis,分布式

 1.1 双检加锁机制

加锁前从redis中查一次,加锁后再查一次。

Redis---缓存双写一致性,缓存,redis,分布式

多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个 互斥锁来锁住它

其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。

后面的线程进来发现已经有缓存了,就直接走缓存。 

Redis---缓存双写一致性,缓存,redis,分布式

 二、数据库和缓存一致性的更新策略

一般都是以MySQL为准。

给缓存设置过期时间,定期清理缓存并回写,是保证最终一致性的解决方案。

我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存,达到一致性,切记,要以mysql的数据库写入库为准

2.1、先更新数据库,后更新缓存

异常一:        回写失败会出现脏数据

Redis---缓存双写一致性,缓存,redis,分布式

 异常二:       高并发下会出现数据覆盖

Redis---缓存双写一致性,缓存,redis,分布式

 2.2 、先更新缓存,后更新数据库

我们一般是不用这种的,因为我们一般都把MySQL作为根基

异常:       高并发下会出现数据覆盖

Redis---缓存双写一致性,缓存,redis,分布式

 2.3、先删除缓存,在更新数据库

当有两个线程:一个线程负责删Redis,修改MySQL,  另一个来查找redis

 如果数据库更新失败或者不及时就会发生异常

(1)请求A进行写操作,删除redis缓存后,工作正在进行中,更新mysql......A还没有彻底更新完mysql,还没commit

(2)请求B开工查询,查询redis发现缓存不存在(被A从redis中删除了)

(3)请求B继续,去数据库查询得到了mysql中的旧值(A还没有更新完)

(4)请求B将旧值回写redis缓存

(5)请求A将新值写入mysql数据库 

上述情况就会导致不一致的情形出现。 

时间
线程A
线程B
出现的问题
t1
请求A进行写操作,删除缓存成功后,工作正在mysql进行中......
t2
1 缓存中读取不到,立刻读mysql,由于A还没有对mysql更新完,读到的是旧值
2 还把从mysql读取的旧值,写回了redis
1 A还没有更新完mysql,导致B读到了旧值
2 线程B遵守回写机制,把旧值写回redis,导致其它请求读取的还是旧值,A白干了。
t3
A更新完mysql数据库的值,over
redis是被B写回的旧值,
mysql是被A更新的新值。
出现了,数据不一致问题。

总结一下:

先删除缓存,再更新数据库
如果数据库更新失败或超时或返回不及时,导致B线程请求访问缓存时发现redis里面没数据,缓存缺失,B再去读取mysql时, 从数据库中读取到旧值,还写回redis,导致A白干了,o(╥﹏╥)o

改怎么解决呢?

延时双删的策略:

Redis---缓存双写一致性,缓存,redis,分布式

 这个删除该休眠多久呢?

Redis---缓存双写一致性,缓存,redis,分布式

 因为这种同步淘汰机制加上了sleep,导致MySQL吞吐量降低怎么办?

 Redis---缓存双写一致性,缓存,redis,分布式

 2.4.先更新数据库,在删除缓存(常用)

 这一种方法的弊端相对比较少

时间
线程A
线程B
出现的问题
t1
更新数据库中的值......
t2
 缓存中立刻命中,此时B读取的是缓存旧值。
A还没有来得及删除缓存的值,导致B缓存命中读到旧值。
t3
更新缓存的数据,over
先更新数据库,再删除缓存
假如缓存删除失败或者来不及,导致请求再次访问redis时缓存命中, 读取到的是缓存旧值。

2.5、实际中是不可能做到强一致性的,那么怎么做到最终一致性呢?

需要用到消息队列:kafka或者RabbitMQ

但是还是都需要是先更新数据库,再删除缓存,这样最多也就是数据暂时不一致,不会导致雪崩、击穿啥的出现。

Redis---缓存双写一致性,缓存,redis,分布式

1 可以把要删除的缓存值或者是要更新的数据库值暂存到消息队列中(例如使用Kafka/RabbitMQ等)。
2 当程序没有能够成功地删除缓存值或者是更新数据库值时,可以从消息队列中重新读取这些值,然后再次进行删除或更新。
3 如果能够成功地删除或更新,我们就要把这些值从消息队列中去除,以免重复操作,此时,我们也可以保证数据库和缓存的数据一致了,否则还需要再次进行重试
4 如果重试超过的一定次数后还是没有成功,我们就需要向业务层发送报错信息了,通知运维人员。

三、canal中间件

能够立刻感知到MySQL改变的有一个MySQL的binlog文件

我们需要一种技术来充当两者之前的吹哨人

这里有阿里研发的一种中间件canal

3.1   canal工作原理

Redis---缓存双写一致性,缓存,redis,分布式

1. canal 模仿MySQL的dump协议,假装自己是MySQL的slave,向MySQL发送dump协议

2. MySQLmaster收到dump请求之后,便会给canal推送自身bin  log 变化给canal

3. cannal收到bin  log 消息并解析。

3.2 MySQL的主从复制 

Redis---缓存双写一致性,缓存,redis,分布式

MySQL的主从复制将经过如下步骤:

1、当 master 主服务器上的数据发生改变时,则将其改变写入二进制事件日志文件中;

2、salve 从服务器会在一定时间间隔内对 master 主服务器上的二进制日志进行探测,探测其是否发生过改变,

如果探测到 master 主服务器的二进制事件日志发生了改变,则开始一个 I/O Thread 请求 master 二进制事件日志;

3、同时 master 主服务器为每个 I/O Thread 启动一个dump  Thread,用于向其发送二进制事件日志;

4、slave 从服务器将接收到的二进制事件日志保存至自己本地的中继日志文件中;

5、salve 从服务器将启动 SQL Thread 从中继日志中读取二进制日志,在本地重放,使得其数据和主服务器保持一致;

6、最后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒;文章来源地址https://www.toymoban.com/news/detail-553181.html

到了这里,关于Redis---缓存双写一致性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Redis缓存双写一致性之更新策略

    你只要用缓存,就可能会涉及到redis缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题? 双写一致性,你先动缓存redis还是数据库mysql哪一个?why? 延时双删你做过吗?会有哪些问题? 有这么一种情况,微服务查询redis无m

    2024年02月05日
    浏览(41)
  • Redis缓存问题:穿透,击穿,雪崩,双写一致性等

    在高并发场景下,数据库往往是最薄弱的环节,我们通常选择使用 redis 来进行缓存,以起到缓冲作用,来降低数据库的压力,但是一旦缓存出现问题,也会导致数据库瞬间压力过大甚至崩溃,从而导致整个系统崩溃.今天就聊聊常见的 redis 缓存问题. 缓存击穿 缓存击穿一般指redis中的一

    2024年04月27日
    浏览(36)
  • redis高级篇 缓存双写一致性之更新策略

    缓存通用查询3部曲 redis 中数据,返回redis 中的数据 redis 中没有,查询数据库并返回 完成第二部的同时,将数据库查询结果写到redis,redis和数据库数据一致. 谈谈双写一致性的理解 1.如果redis 中有数据:需要和数据库中的相同 2.如果redis 中无数据: 数据库中的值如果是最新的

    2024年02月06日
    浏览(42)
  • 【redis】缓存双写一致性之工程落地实现(下)

    提示:以下是本篇文章正文内容,下面案例可供参考 如何监听MySQL的变动? MySQL有一个binlog日志 伪装成从机,从主机获取二进制文件 配置不在详述 配置不再详述 a、业务类: 当MySQL进行增删改操作时,后台的canal会立刻监听捕捉到MySQL的二进制binlog日志文件改动,并通过Jav

    2023年04月19日
    浏览(22)
  • Redis双写一致性?

    双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致。 Redis作为缓存,mysql的数据如何与redis进行同步呢?(双写一致性) 1.我们当时做排行榜业务时,把历史榜单数据存储到了缓存中。这个虽然也是热点数据,但是实时要求性不高。

    2024年02月16日
    浏览(34)
  • 缓存面试解析:穿透、击穿、雪崩,一致性、分布式锁、Redis过期,海量数据查找

    在程序内部使用缓存,比如使用map等数据结构作为内部缓存,可以快速获取对象。通过将经常使用的数据存储在缓存中,可以减少对数据库的频繁访问,从而提高系统的响应速度和性能。缓存可以将数据保存在内存中,读取速度更快,能够大大缩短数据访问的时间,提升用户

    2024年02月14日
    浏览(39)
  • 深入理解高并发下的MySQL与Redis缓存一致性问题(增删改查数据缓存的一致性、Canal、分布式系统CAP定理、BASE理论、强、弱一致性、顺序、线性、因果、最终一致性)

    一些小型项目,或极少有并发的项目,这些策略在无并发情况下,不会有什么问题。 读数据策略:有缓存则读缓存,然后接口返回。没有缓存,查询出数据,载入缓存,然后接口返回。 写数据策略:数据发生了变动,先删除缓存,再更新数据,等下次读取的时候载入缓存,

    2024年03月20日
    浏览(38)
  • Redis(十四)双写一致性工程案例

    https://github.com/alibaba/canal 数据库镜像 数据库实时备份 索引构建和实时维护(拆分异构索引、倒排索引等) 业务 cache 刷新 带业务逻辑的增量数据处理 传统mysql主从复制原理 MySQL的主从复制将经过如下步骤: 当 master 主服务器上的数据发生改变时,则将其改变写入二进制事件日志

    2024年02月21日
    浏览(29)
  • 分布式系统中数据库和缓存双写一致性的实现技术

    标题:分布式系统中数据库和缓存双写一致性的实现技术 在分布式系统中,为了确保数据库和缓存之间的数据一致性,双写一致性成为了一个关键的挑战。本文将深入探讨如何利用一些常见的技术手段来保证数据库和缓存的双写一致性,以及通过举例说明这些技术是如何在实

    2024年01月16日
    浏览(41)
  • Redis与MySQL双写一致性如何保证

    前言 在分布式系统中,数据一致性是一个重要的问题。当我们使用Redis和MySQL这两种不同的数据库时,如何保证它们之间的双写一致性是一个需要解决的难题。本文将探讨Redis与MySQL双写一致性的保证方法。 什么是双写一致性? 指的是当我们更新了数据库的数据之后redis中的数

    2024年02月09日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包