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

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

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

1、首先redis是什么

Redis(Remote Dictionary Server ),是一个高性能的基于Key-Value结构存储的NoSQL开源数据库。大部分公司采用Redis来实现分布式缓存,用来提高数据查询效率。

2、为什么会选Redis

在Web应用发展的初期,系统的访问和并发并不高,交互也比较少。但随着业务的扩大,访问量的提升,使得服务器负载和关系型数据库出现瓶颈,而导致瓶颈的源头,主要体现在磁盘IO上。随着互联网的进一步发展,对系统性能有了更高的要求,Redis的出现,解决了很多问题。至于我们为什么要选择Redis,我总结为以下六个原因:

1)、基于内存存储,可以降低对关系型数据库的访问频次,从而缓解数据库压力

2)、数据IO操作能支持更高级别的QPS,官方发布的指标是10W;

3)、提供了比较多的数据存储结构,比如string、list、hash、set、zset等等。

4)、采用单线程实现IO操作,避免了并发情况下的线程安全问题。

5)、可以支持数据持久化,避免因服务器故障导致数据丢失的问题

6)、Redis还提供了更多高级功能,比如分布式锁、分布式队列、排行榜、查找附近的人等功能,为更复杂的需求提供了成熟的解决方案。

3、 应用场景

缓存,作为Key-Value形态的内存数据库,Redis 最先会被想到的应用场景便是作为数据缓存

分布式锁,分布式环境下对资源加锁

分布式共享数据,在多个应用之间共享

排行榜,自带排序的数据结构(zset)

消息队列,pub/sub功能也可以用作发布者 / 订阅者模型的消息

4、redis用作缓存时

4.1、作为缓存使用流程
缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
4.2、数据性一致性问题
例如我们使用Redis来作为缓存时,让请求先访问到Redis,而不是直接访问数据库。而在这种业务场景下,可能会出现缓存和数据库数据不一致性的问题。

在更新的时候,操作缓存和数据库无疑就是以下四种可能之一:

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

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

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

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

4.2.1、先更新缓存,再更新数据库
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删

如果我成功更新了缓存,但是在执行更新数据库的那一步,服务器突然宕机了,那么此时,我的缓存中是最新的数据,而数据库中是旧的数据。

脏数据就因此诞生了,并且如果我缓存的信息(是单独某张表的),而且这张表也在其他表的关联查询中,那么其他表关联查询出来的数据也是脏数据,结果就是直接会产生一系列的问题。

4.2.2、先更新数据库,在更新缓存
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
只有等到缓存过期之后,才能访问到正确的信息。那么在缓存没过期的时间段内,所看到的都是脏数据。

以上两图中只要执行第二步时失败了,就必然会产生脏数据。

4.2.3、先删除缓存,在更新数据库
这种方式在没有高并发的情况下,是可能保持数据一致性的。

Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
如果只有第一步执行成功,而第二步失败,那么只有缓存中的数据被删除了,但是数据库没有更新,那么在下一次进行查询的时候,查不到缓存,只能重新查询数据库,构建缓存,这样其实也是相对做到了数据一致性。

但如果是处于读写并发的情况下,还是会出现数据不一致的情况:
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
执行完成后,明显可以看出,1号用户所构建的缓存,并不是最新的数据,还是存在问题的

4.2.4、先更新数据库,在删除缓存
如果更新数据库成功了,而删除缓存失败了,那么数据库中就会是新数据,而缓存中是旧数据,数据就出现了不一致情况。
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
和之前一样,如果两段代码都执行成功,在并发情况下会是什么样呢?
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
还是会造成数据的不一致性。

但是此处达成这个数据不一致性的条件明显会比起其他的方式更为困难 :

  • 时刻1:读请求的时候,缓存正好过期

  • 时刻2:读请求在写请求更新数据库之前查询数据库,

  • 时刻3:写请求,在更新数据库之后,要在读请求成功写入缓存前,先执行删除缓存操作。

这通常是很难做到的,因为在真正的并发开发中,更新数据库是需要加锁的,不然没一点安全性~

一定程度上来讲,这种方式还是解决了一定程度上的数据不一致性问题的。

4.3、总结

以上四种方式无论选择那种方式,如果实在多服务或时并发的情况下,其实都是有可能产生数据不一致性的。

为了解决这个存在的问题有以下方式:

4.3.1、延迟双删
先进行缓存清除,再执行update,最后(延迟N秒)再执行缓存清除。进行两次删除,且中间需要延迟一段时间
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
scss

public void write(String key,Object data){ // 延迟双删伪代码 
deleteRedisCache(key); // 删除redis缓存 
updateMysqlSql(obj); // 更新mysql 
Thread.sleep(100); // 延迟一段时间 
deleteRedisCache(key); // 再次删除该key的缓存 }

延迟双删的流程图:
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
解决这样的问题,其实最好的方式就是在执行完更新数据库的操作后,先休眠一会儿,再进行一次缓存的删除,以确保数据一致性

首先延迟删除的时间需要大于 1号用户执行流程的总时间

就是1号用户从数据库读取数据 写入缓存时间

4.3.2、通过发送MQ,在消费者线程去同步Redis
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
无论是更新缓存还是删除缓存,在同时操作缓存和数据库时,都无法保证两者都能一次性操作成功,所以我们最好的办法就是重试,这个重试并不是立即重试,因为缓存和数据库可能因为网络或者其它原因停止服务了,立即重试成功率极低,而且重试会占用线程资源,显然不合理,所以我们需要采用异步重试机制。

异步重试我们可以使用消息队列来完成,因为消息队列可以保证消息的可靠性,消息不会丢失,也可以保证正确消费,当且仅当消息消费成功后才会将消息从消息队列中删除。

  • 优点1:可以大幅减少接口的延迟返回的问题
  • 优点2:MQ本身有重试机制,无需人工去写重试代码
  • 优点3:解耦,把查询Mysql和同步Redis完全分离,互不干扰

4.3.3、Canal 订阅日志实现
当我们业务修改数据时,我们只需要更新数据库,无需修改缓存,那什么时候修改缓存呢?

以mysql为例,在数据库一条记录发生变更时就会生成一条binlog日志,我们可以订阅这种消息,拿到具体的数据,然后根据日志消息更新缓存,订阅日志目前比较流行的就是阿里开源的canal,那么我们的架构就变为如下形式。
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
订阅数据库变更日志,当数据库发生变更时,我们可以拿到具体操作的数据,然后再去根据具体的数据,去删除对应的缓存。

当然Canal 也是要配合消息队列一起来使用的,因为其Canal本身是没有数据处理能力的。
Redis数据一致性问题的三种解决方案,# redis,redis,缓存,一致性,延迟双删
这个方式算的上彻底解耦了,应用程序代码无需再管消息队列方面发送失败问题,全交由 Canal来发送。文章来源地址https://www.toymoban.com/news/detail-630754.html

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

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

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

相关文章

  • Redis生产实战-热key、大key解决方案、数据库与缓存最终一致性解决方案

    Redis生产实战-热key、大key解决方案、数据库与缓存最终一致性解决方案

    热 key 问题就是某一瞬间可能某条内容特别火爆,大量的请求去访问这个数据,那么这样的 key 就是热 key,往往这样的 key 也是存储在了一个 redis 节点中,对该节点压力很大 那么对于热 key 的处理就是通过热 key 探测系统对热 key 进行计数,一旦发现了热 key,就将热 key 在 jv

    2024年02月05日
    浏览(13)
  • Redis如何保障缓存与数据库的数据一致性问题?

    Redis如何保障缓存与数据库的数据一致性问题?

    目录 一.最经典的数据库加缓存的双写双删模式 二. 高并发场景下的缓存+数据库双写不一致问题分析与解决方案设计 三、上面高并发的场景下,该解决方案要注意的问题 1.1 Cache Aside Pattern概念以及读写逻辑 (1)读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取

    2023年04月21日
    浏览(13)
  • 如何保证Redis缓存和数据库的一致性问题

    熟练掌握Redis缓存技术? 那么请问Redis缓存中有几种读写策略,又是如何保证与数据库的一致性问题 今天来聊一聊常用的三种缓存读写策略 首先我们来思考一个问题 写 先更新缓存 再更新数据库 首先如果缓存更新成功但数据库更新失败,会导致数据不一致的问题 其次当请求

    2024年02月14日
    浏览(12)
  • Redis持久化与一致性解决方案

    Redis持久化与一致性解决方案

    怎样去验证我们的Redis缓存是否一定生效了呢? 很简单:如果缓存生效,那么我们每次查询数据是不是先从Redis里面查,那么好,我们先去查第一次,接着去改MySQL里面的数据值,此时再去查第二次,此时如果发现第二次查询到的数据值与与我们改过的MySQL里面的数据值不一致

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

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

    2024年03月20日
    浏览(18)
  • redis和mysql中的数据以哪个为准,并且会不会存在一致性的问题

    为了解决数据一致性的问题,可以采取以下策略: 读写双写:在更新MySQL数据时,同时更新Redis中的数据,确保数据的一致性。 数据过期策略:设置Redis中缓存数据的过期时间,确保缓存数据不会过期太久,从而减少数据不一致的可能性。 异步更新:在更新MySQL数据后,异步

    2024年02月13日
    浏览(11)
  • 游戏配置二级缓存一致性问题解决方案

    游戏配置二级缓存一致性问题解决方案

    游戏服务器进程在启动的时候,一般会把所有策划配置数据加载到内存里,将主键以及对应的记录存放在一个HashMap容器里,这称为一级缓存。部分功能可能还需要缓存其他数据,这些称为二级缓存。举个例子,对于如下的玩家升级表记录 程序缓存level与ConfigPlayerLevel的对应关

    2024年02月22日
    浏览(9)
  • 缓存一致性问题解决方案(超全超易懂)

    缓存一致性问题解决方案(超全超易懂)

    标准的操作方式就是查询数据库之前先查询缓存,如果缓存数据存在,则直接从缓存中返回,如果缓存数据不存在,再查询数据库,然后将数据存入redis。 缓存作用模型 在项目中我们经常这样用缓存来缓解数据库的压力: 缓存更新是redis为了节约内存而设计出来的一个东西,

    2023年04月12日
    浏览(12)
  • Redis缓存(双写一致性问题)

    Redis缓存(双写一致性问题)

    前言 : 什么是缓存? 缓存就像自行车,越野车的避震器 举个例子:越野车,山地自行车,都拥有\\\"避震器\\\", 防止 车体加速后因惯性,在酷似\\\"U\\\"字母的地形上飞跃,硬着陆导致的 损害 ,像个弹簧一样; 同样,实际开发中,系统也需要\\\"避震器\\\",防止过高的数据访问猛冲系统,导致其操作线程无法

    2024年02月02日
    浏览(12)
  • Redis缓存问题(穿透, 击穿, 雪崩, 污染, 一致性)

    Redis缓存问题(穿透, 击穿, 雪崩, 污染, 一致性)

    目录 1.什么是Redis缓存问题? 2.缓存穿透 3.缓存击穿 4.缓存雪崩 5.缓存污染(或满了)    5.1 最大缓存设置多大    5.2 缓存淘汰策略 6.数据库和缓存一致性    6.1 4种相关模式    6.2 方案:队列+重试机制    6.3 方案:异步更新缓存(基于订阅binlog的同步机制) 在高并发的业

    2024年02月12日
    浏览(11)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包