我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL和Redis的数据一致性问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL和Redis的数据一致性问题

前言:

在数据读多写少的情况下作为缓存来使用,恐怕是Redis使用最普遍的场景了。当使用Redis作为缓存的时候,一般流程是这样的。

  • 如果缓存在Redis中存在,即缓存命中,则直接返回数据

MySQL和Redis的数据一致性问题_数据

  • 如果Redis中没有对应缓存,则需要直接查询数据库,然后存入Redis,最后把数据返回

MySQL和Redis的数据一致性问题_数据_02

通常情况下,我们会为某个缓存设置一个key值,并针对key值设置一个过期时间,如果被查询的数据对应的key过期了,则直接查询数据库,并将查询得到的数据存入Redis,然后重置过期时间,最后将数据返回,伪代码如下:


public User getUserInfo(String userName) {
      User user = redisCache.getName("user:" + userName);
      if (user != null) {
          return user;
      }

      // 从数据库中直接搜索
      user = selectUserByUserName(userName);
      // 将数据写入Redis,并设置过期时间
      redisCache.set("user:" + userName, user, 30000);
      // 返回数据
      return user;
}

一、一致性问题

但是,在Redis的key值未过期的情况下,用户修改了个人信息,我们此时既要操作数据库数据,也要操作Redis数据。现在我们面临了两种选择:

  • 先操作Redis的数据,再操作数据库的数据
  • 先操作数据库的数据,再操作Redis的数据

如论选择哪种方法,最理想的情况下,两个操作要么同时成功,要么同时失败,否则就会出现Redis和数据库数据不一致的情况。

遗憾的是,目前没有什么框架能够保证Redis的数据和数据库的数据的完全一致性。我们只能根据场景和所需要付出的代码来采取一定的措施降低数据不一致出现的概率,在一致性和性能之间取得一个折中。

下面我们来讨论一下关于Redis和数据库质检数据一致性的一些方案。

二、方案选择

1、是删除缓存还是更新缓存?

当数据库数据发生变化的时候,Redis的数据也需要进行相应的操作,那么这个「操作」到底是用「更新」还是用「删除」呢?

「更新」的话调用Redis的set方法,新值替换旧值;「删除」直接删除原来的缓存,下次查询的时候重新读取数据库,然后再更新Redis。

结论:推荐直接使用「删除」操作

因为使用「更新」操作的话,你会面临两种选择

  • 先更新缓存,再更新数据库
  • 先更新数据库,再更新缓存

第1种不用考虑了,下面讨论一下「先更新数据库,再更新缓存」这种方案。

MySQL和Redis的数据一致性问题_redis_03

如果线程1和线程2同时进行更新操作,但是每个线程的执行顺序如上图所示,此时就会导致数据不一致,因此从这个角度上我们推荐直接使用删除缓存的方式。

此外,推荐使用「删除缓存」还有两点原因。

  • 如果写数据库的场景比读数据场景多,采用这种方案就会导致缓存就被频繁写入,浪费性能;
  • 如果缓存要经过一系列复杂的计算才能得到,那么每次写入数据库后,都再次计算写入的缓存无疑也是浪费性能的。

明确这个问题之后,摆在我们面前的就只有两个选择了:

  • 先更新数据库,再删除缓存
  • 先删除缓存,再更新数据库

2、先更新数据库,再删除缓存

这种方式可能存在以下两种异常情况

  • 更新数据库失败,这时可以通过程序捕获异常,直接返回结果,不再继续删除缓存,所以不会出现数据不一致的问题
  • 更新数据库成功,删除缓存失败。导致数据库是最新数据,缓存中的是旧数据,数据不一致

第2种情况应该怎么办呢?我们有两种方式:失败重试异步更新

3、失败重试

如果删除缓存失败,我们可以捕获这个异常,把需要删除的 key 发送到消息队列。自己创建一个消费者消费,尝试再次删除这个 key,直到删除成功为止。

MySQL和Redis的数据一致性问题_一致性问题_04

这种方式有个缺点,首先会对业务代码造成入侵,其次引入了消息队列,增加了系统的不确定性。

4、异步更新缓存

因为更新数据库时会往 binlog 中写入日志,所以我们可以启动一个监听 binlog变化的服务(比如使用阿里的 canal开源组件),然后在客户端完成删除 key 的操作。如果删除失败的话,再发送到消息队列。

总结

总之,对于删除缓存失败的情况,我们的做法是不断地重试删除操作,直到成功。无论是重试还是异步删除,都是最终一致性的思想。

5、、先删除缓存,再更新数据库

这种方式可能存在以下两种异常情况:

  • 删除缓存失败,这时可以通过程序捕获异常,直接返回结果,不再继续更新数据库,所以不会出现数据不一致的问题
  • 删除缓存成功,更新数据库失败。在多线程下可能会出现数据不一致的问题

MySQL和Redis的数据一致性问题_缓存_05

这时,Redis中存储的旧数据,数据库的值是新数据,导致数据不一致。这时我们可以采用延时双删的策略,即更新数据库数据之后,再删除一次缓存。

MySQL和Redis的数据一致性问题_缓存_06

用伪代码表示就是:


public void update(String key, Object data) {
    // 首先删除缓存
    redisCache.delKey(key);
    // 更新数据库
    db.updateData(data);
    // 休眠一段时间,时间依据数据的读取耗费的时间而定
    Thread.sleep(500);
    // 再次删除缓存
    redisCache.delKey(key);
}

到此这篇关于MySQL和Redis的数据一致性问题的文章就介绍到这了,更多相关MySQL和Redis内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MySQL和Redis的数据一致性问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MySQL和Redis的数据一致性问题怎么解决

本篇内容主要讲解“MySQL和Redis的数据一致性问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL和Redis的数据一致性问题怎么解决”吧!前言:在数据读多写少的情况下作为
2023-06-29

redis数据库一致性问题解决

redis数据库通过以下机制解决数据一致性问题:主从复制:主服务器将写操作同步复制到从服务器。redis sentinel:监控redis服务器并执行故障转移和故障恢复,保持数据库可用性和数据一致性。redis cluster:使用一致性哈
redis数据库一致性问题解决
2024-04-19

Redis缓存和数据库的数据一致性的问题解决

目录前言一、谈谈一致性二、 情景分析2.1 针对读场景2.2 针对写场景三、同步策略3.1 先更新缓存,再更新数据库3.2 先更新数据库,再更新缓存3.3 先删除缓存,后更新数据库3.4 先更新数据库,后删除缓存四、解决办法4.1 双写一致
Redis缓存和数据库的数据一致性的问题解决
2024-09-20

掘地三尺搞定 Redis 与 MySQL 数据一致性问题

今天「码哥」跟大家一起深入探索缓存的工作机制和缓存一致性应对方案。

redis缓存和数据库一致性问题如何解决

在使用Redis缓存时,常常会遇到与数据库一致性的问题。当数据发生变更时,需要保证Redis缓存与数据库的数据保持一致。以下是几种常见的解决方案:1. 缓存穿透:在查询缓存时,如果缓存中不存在对应的数据,会直接查询数据库。但是当数据库中也不
2023-08-24

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

今天给大家剖析一下工作中常见的 MySQL 和 Redis 数据一致性问题。

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

在满足实时性的条件下,MySQL 和 Redis 不存在两者完全保存一致的方案,只有最终一致性方案。

redis和mysql数据一致性怎么保证

为了确保 redis 和 mysql 之间的数据一致性,可以采用以下策略:1. 主从复制:利用 mysql 的复制功能,将 mysql 作为主数据库,并将数据同步到 redis 作为从数据库。2. 事务队列:将更新请求发送到事务队列,由消费
redis和mysql数据一致性怎么保证
2024-04-08

MySQL和Redis如何保证数据一致性

MySQL与Redis都是常用的数据存储和缓存系统。为了提高应用程序的性能和可伸缩性,很多应用程序将MySQL和Redis一起使用,其中MySQL作为主要的持久存储,而Redis作为主要的缓存。在这种情况下,应用程序需要确保MySQL和Re
2023-08-22

Redis 和 MySQL 如何保证数据一致性?

启动一个订阅程序去订阅数据库的binlog,获得需要操作的数据。在应用程序中,另起一段程序,获得这个订阅程序传来的信息,进行删除缓存操作。

Redis和MySQL如何保持数据一致性?

Mysql和Redis是两种不同的数据库,如何保证不同数据库之间数据的一致性就非常关键了。

缓存和数据库一致性问题

1、想要提高应用的性能,可以引入「缓存」来解决2、引入缓存后,需要考虑缓存和数据库一致性问题,可选的方案有:「更新数据库 + 更新缓存」、「更新数据库 + 删除缓存」3、更新数据库 + 更新缓存方案,在「并发」场景下无法保证缓存和数据一致性,且存在「缓存资源浪
缓存和数据库一致性问题
2021-04-23

Redis数据一致性问题的三种解决方案

缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。

Redis经典问题:数据不一致

数据不一致是Redis使用中常见的问题之一,但通过合理的策略和措施,我们可以有效地解决这一问题。无论是通过重试策略、缩短缓存时间,还是采用缓存分层策略,我们都可以确保数据的最终一致性,进而提高应用程序的稳定性和性能。

编程热搜

目录