精华内容
下载资源
问答
  • redis数据一致性
    千次阅读
    2022-03-23 10:53:28

    在使用redis时,需要保持redis和数据库数据的一致性,最流行的解决方案之一就是延时双删策略,今天我们就来详细刨析一下

    注意:要知道经常修改的数据表不适合使用redis,因为双删策略执行的结果是把redis中保存的那条数据删除了,以后的查询就都会去查询数据库。所以redis使用的是读远远大于改的数据缓存。

    1,首先要理解在并发环境下redis数据一致性的问题所在

    在多线程并发情况下,假设有两个数据库修改请求,为保证数据库与redis的数据一致性,
    修改请求的实现中需要修改数据库后,级联修改redis中的数据。
    请求一:1.1修改数据库数据		1.2 修改redis数据
    请求二:2.1修改数据库数据		2.2 修改redis数据
    并发情况下就会存在1.1 ---> 2.1 ---> 2.2 ---> 1.2的情况 
    (一定要理解线程并发执行多组原子操作执行顺序是可能存在交叉现象的)
    
    此时存在的问题就是:
    	1.1修改数据库的数据最终保存到了redis中,2.1在1.1之后也修改了数据库数据。
    	此时出现了redis中数据和数据库数据不一致的情况,在后面的查询过程中就会长时间去先查redis,
    	从而出现查询到的数据并不是数据库中的真实数据的严重问题。
    问题解决:
    	修改数据库级联修改redis数据改为  修改数据库数据后级联删除redis数据
    	至于是先执行1.2的redis删除,还是限制性2.2的redis删除,无关紧要。
    	结果都是redis中数据已被删除。之后的查询就会由于redis中没有数据而去查数据库,
    	此时即不会存在查询到的数据和数据库的数据不一致的情况。
    

    2,上面详解了redis数据一致性的问题所在,并提供了单删策略来解决问题
    但此时依然存在比较严重的问题。

    上面的单删策略情况如下:
    修改请求的实现中需要修改数据库后,级联删除redis中的数据。
    请求一:1.1修改数据库数据		1.2 删除redis数据
    请求二:2.1修改数据库数据		2.2 删除redis数据
    
    假设现在并发存在一个查询请求
    请求三:3.1查询redis中数据   3.2查询数据库数据    3.3 新查到的数据写入redis
    (一定要理解带redis的查询请求实现逻辑,先查redis,数据不存在查数据库,
    			查到的数据写入redis以便以后的查询不去直接查数据库)
    			
    此时并发情况下就会存在1.1 ---> 1.2 ---> 3.1 ---> 3.2 ---> 2.1 ---> 2.2 ---> 3.3的情况 
    
    此时存在的问题就是:
    	此时数据库中的数据保存的是2.1修改后的数据,而redis中保存的数据是3.2中在1.1修改数据后的结果,
    	此时出现了redis中数据和数据库数据不一致的情况,在后面的查询过程中就会长时间去先查redis,
    	从而出现查询到的数据并不是数据库中的真实数据的严重问题。
    

    3,上面刨析到了单删策略来解决redis数据一致性存在的问题,下面我们来说双删策略

    上面的单删策略存在问题的情况如下:
    请求一:1.1修改数据库数据		1.2 删除redis数据
    请求二:2.1修改数据库数据		2.2 删除redis数据
    请求三:3.1查询redis中数据   3.2查询数据库数据    3.3 新查到的数据写入redis
    
    添加延时双删策略后的情况
    请求一:1.1修改数据库数据		1.2 删除redis数据    1.3 延时3--5s再去删除redis中数据
    请求二:2.1修改数据库数据		2.2 删除redis数据    2.3 延时3--5s再去删除redis中数据
    请求三:3.1查询redis中数据     3.2 查询数据库数据    3.3 新查到的数据写入redis
    
    双删策略为什么能解决问题:
    因为存在了延时时间,故1.3或2.3 一定是最后执行的一步操作(并发中的延时一定要理解)
    延时的根本目的就是为了让程序先把3.3执行完,再去删除redis
    

    4,如何实现延时3–5s的操作

    比较好的:   项目整合quartz等定时任务框架,去实现延时3--5s再去执行最后一步任务
    比较一般的:  创建线程池,线程池中拿一个线程,线程体中延时3-5s再去执行最后一步任务(不能忘了启动线程)
    比较差的:   单独创建一个线程去实现延时执行
    
    更多相关内容
  • redis数据一致性

    万次阅读 2019-01-15 17:19:13
    前言:所谓的redis数据一致性即当进行修改或者保存、删除之后,redis中的数据也应该进行相应变化,不然用户再次查询的时候很可能查询出已经删除过的脏数据。 一、缓存一致的必要性 还是接上篇来说,我们已经解决了...

    前言:所谓的redis数据一致性即当进行修改或者保存、删除之后,redis中的数据也应该进行相应变化,不然用户再次查询的时候很可能查询出已经删除过的脏数据。

    一、缓存一致的必要性

    还是接上篇来说,我们已经解决了redis缓存穿透的问题(简单解决方案,可以再次优化),但是使用redis的时候缓存一致性的问题我们也需要着重考虑,例如:保存了一个新用户之后,就应该同时在redis缓存中也插入该条数据,更新了某条数据在缓存中也应该同步更新,而redis默认的做法是:当你不去设置的时候redis中存放的一值是你之前存放的数据,只有在重启服务器的时候数据才会同步,显然这是非常不可取的,如果是这样的话岂不是每时每刻都要重启服务器,那将是多么大的灾难!

    二、业务场景

    这里我只说一个场景吧,其他场景都是一样的处理办法,场景为:假设我们将用户数据放入到redis中,此时有新用户注册,在数据库中会插入一条新数据,与此同时要在redis中也插入该条数据,以便于下次查询的时候显示最新数据。

    我们先来看一下默认不使用任何处理的情况下redis是否会为我们做一致性操作,现在我的测试数据库中有18条用户数据,此时我们启动系统后注册插入第19条数据后看下redis中是否有19条。

    经过注册之后我现在给数据库中插入了第19条数据

    接着我们还是使用上篇提到过的查询缓存的方法来获取下所有信息,我们直接来看第最后一条,可以看到最后是润青而不是十九,所以redis默认是没有替我们做缓存一致操作的。

    三、缓存一致性实现(方案1)

    其实,要想实现一致性很简单,当我们在进行插入操作之后,我们把该条数据取出来同时保存到redis缓存中去,这样再次查询缓存的时候我们也可以看到新的数据,代码如下:

    需要注意的是:我这里直接是调用JPA的findAll(),其实更好的做法是根据id去更新刚插入的那一条,这样效率才高,这里只是演示如何实现,接着再来注册一条新数据,看看是否可以在缓存中同时看到:新插入的数据id为29,我们来看下缓存是否存在该条新数据

    四、redis缓存一致性实现(方案2)

    定期清除redis中的数据,例如设置一个定时任务,每当一个小时的时候就会清除redis中的数据,也就是让redis中的数据失效,然后再次保存、删除的时候之前的 redis中的数据已经不存在,所以相当于是将数据重新设置到redis中去,所以可以保证数据的一致性。

    展开全文
  • 实现MySQL和Redis数据一致性的方案

    千次阅读 2022-02-22 15:51:06
    实现MySQL和Redis缓存一致的方案延时双删策略操作步骤示例代码异步更新缓存(基于订阅binlog的同步机制)操作步骤示例代码 延时双删策略 操作步骤 示例代码 异步更新缓存(基于订阅binlog的同步机制) 操作步骤 示例代码...

    什么是一致性

    一致性就是数据保持一致,在分布式系统中一致性代表多个节点的数据保持一致

    • 强一致性:这种一致性级别是最符合用户直觉的,它要求系统写入什么,读出来的也会是什么,用户体验性好,但实现起来往往对系统的性能影响大;
    • 弱一致性:这种一致性级别约束了系统在写入成功后,不承诺立即可以读到写入的值,也不承诺多久之后数据能够达到一致,但会尽可能地保证到某个时间级别(比如秒级别)后,数据能够达到一致状态;
    • 最终一致性:最终一致性是弱一致性的一个特例,系统会保证在一定时间内,能够达到一个数据一致的状态。这里之所以将最终一致性单独提出来,是因为它是弱一致性中非常推崇的一种一致性模型,也是业界在大型分布式系统的数据一致性上比较推崇的模型;

    三种缓存使用模式

    • chche-aside
      Cache-Aside Pattern, 即旁路缓存模式。它的提出是为了尽可能地解决缓存与数据库的数据不一致问题。
      cache-aside读流程
      在这里插入图片描述
      读的时候先读缓存,缓存命中的话直接返回数据;缓存没有命中,就去读数据库,然后更新缓存,再返回数据
      cache-aside写请求流程
      在这里插入图片描述
      更新得到时候,先更新数据库,然后再删除缓存。
      当这个数据在下一次需要的时候,使用Cache-Aside模式将会在获取数据的时候,同时从数据仓库中获取数据,并且写到Cache之中
    • Read Through/Write Through
      Read Through流程
      在这里插入图片描述

    Read-Through 实际上只是在Cache-Aside之上进行了一层封装,它会让程序代码变得更加简洁,同时也减少数据源上的负载。
    Wirte Through流
    在这里插入图片描述

    • write-behind
      Write-behind跟Read-Through/Write-Through有很多相似的地方,都是由Cache Provider来负责缓存和数据库的读写。它们又有个很大的不同:Read/Write-Through是同步更新缓存和数据的,Write-Behind则是只更新缓存,不直接更新数据库,通过批量异步的方式来更新数据库
      write behind流程:
      在这里插入图片描述
      这种方式下,缓存和数据库的一致性不强,对一致性要求高的系统要谨慎使用。
      但是它适合频繁写的场景,MySQL的Innodb Buffer Pool机制就是用到这种模式。
    • 操作缓存的时候到底是更新缓存还是删除缓存
      日常开发中我们一般用的是cache-aside模式。但我们注意到cache-aside模式为什么是删除缓存而不是更新缓存
      例子:
      在这里插入图片描述
      线程A先发起一个写操作,第一步先更新数据库;线程B先发起一个写操作,第二步后更新数据库;但是由于网络等原因,线程B先更新了缓存;线程A更新缓存;
      此外,更新缓存相对于删除缓存,还有亮点劣势:
      如果你写入的缓存值,是经过复杂计算才得到的话,更新缓存频率高的话,就浪费性能了;
      在写数据库场景多、读数据场景少的情况下,数据很多时候还没被读取到,又被更新了,这也浪费了性能呢。
    • 双写的情况下,先更新数据库还是先更新缓存
      例子:
      在这里插入图片描述
      线程A发起一个写操作,第一步del cache;此时线程B发起一个读操作,cache miss;线程B继续读DB,读出来一个老数据,此时线程B把老数据设置入cache;线程A写入DB更新数据;
      这里就存在这样的一个问题了:缓存和数据库的数据不一致了。缓存保存的是老数据,数据库保存的是新数据。 因此,Cache-Aside缓存模式,选择了先操作数据库而不是先操作缓存
    • 数据库和缓存数据保持强一致,可以嘛?
      实际上是没有办法做到数据库与缓存达到强一致性
      加锁可以嘛?并发写期间加锁,任何读操作不写入缓存?缓存以及数据库封装CAS乐观锁,更新缓存时通过lua脚本?分布式事务,3PC?TCC?
      其实,这是由CAP理论 决定的。缓存系统适用的场景就是非强一致性的场景,它属于CAP中的AP 。个人觉得,追求绝对一致性的业务场景,不适合引入缓存。

    延时双删策略

    操作步骤

    在这里插入图片描述
    先删除缓存,在更新数据库,再休眠(例如1s),然后删除缓存
    这个休眠的时长,等于读业务逻辑数据的耗时 + 几百毫秒

    删除缓存重试机制

    操作步骤

    在这里插入图片描述
    写请求更新数据库;缓存因为某些原因,删除失败;把删除失败的key放到消息队列;消费消息队列的消息,获取要删除的key;重试删除缓存操作;

    异步更新缓存(基于订阅binlog的同步机制)

    操作步骤

    在这里插入图片描述

    展开全文
  • 如果数据库数据发生了变化,如何将变化的数据同步给redis? 1.直接删除redis缓存,见代码 2.基于MQ形式实现同步(略) 3.基于canal订阅binlog二进制文件,通过mq实现异步同步 基于canal订阅binlog同步 原理: 1....

    问题;如果数据库数据发生了变化,如何将变化的数据同步给redis?

    1.直接删除redis缓存,见代码

    2.基于MQ形式实现同步(略)

    3.基于canal订阅binlog二进制文件,通过mq实现异步同步

    基于canal订阅binlog同步

    在这里插入图片描述

    原理:

    1.canal服务器伪装成mysql的从节点,订阅mysql 的binlog二进制文件

    2.当mysql主节点binlog发生改变时,会通知给canal服务器端

    3.canal服务器将改变的数据转换成json数据发送canal客户端

    4.在canal客户端中,将数据异步的写入到redis中

    环境搭建

    1.配置mysql,开启binlog主从同步

    #1.查询mysql安装目录
    select @@datadir;
    
    #2.然后在my.cnf文件添加以下配置,并重启服务器
    log-bin=mysql-bin #添加这一行就ok
    binlog-format=ROW #选择row模式 
    server_id=1
    
    #3.查询是否开启binlog
    show variables like 'log_bin';
    
    #4.添加用户并赋予权限(略)
    

    2.配置canal服务端(此处为了方便使用docker安装)

    docker pull canal/canal-server:latest
    docker run -p 11111:11111 --name canal -id canal/canal-server
    docker exec -it canal /bin/bash
    # 修改canal.id=2  不能与之前的mysql配置id相同
    vi /home/admin/canal-server/conf/canal.properties
    

    在这里插入图片描述

    #修改mysql主节点地址
    vi /home/admin/canal-server/conf/example/instance.properties
    

    在这里插入图片描述

    3.测试代码
    github地址

    展开全文
  • redis 数据一致性

    2019-05-30 15:34:43
    数据库和redis分别处理不同的数据类型 数据库处理要求强一致实时数据,例如金融数据、交易数据 Redis处理不要求强一致实时数据,例如网站最热贴排行榜 redis和MySQL数据的同步,代码级别大致可以这样做: ...
  • Redis 保证数据一致性方案解析

    千次阅读 2022-03-22 23:03:31
    谈谈一致性 一致性就是数据保持一致,在分布式系统中,可以理解为多个节点中数据的值是一致的。...最终一致性:最终一致性是弱一致性的一个特例,系统会保证在一定时间内,能够达到一个数据一致的状态。这里之所以将
  • Redis缓存数据一致性及问题

    千次阅读 2021-12-01 22:11:37
    2、Redis缓存数据一致性及问题 2.1、如何保证缓存和数据库数据一致性 3、缓存问题 3.1、缓存穿透-查不到 3.2、缓存击穿-量太大,缓存过期 3.3、缓存雪崩 1、高客户端连接服务端处理 当客户端比较多,高并发...
  • redis如何保证数据一致性

    千次阅读 2022-02-21 15:59:41
    一:给缓存设置过期时间,是保证最终一致性的终极解决方案。 这种方案下,我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新...
  • Redis 与 Mysql 的数据一致性

    千次阅读 2022-07-17 15:26:10
    比如几百毫秒),再删除缓存,有可能第二次删除失败,还是会导致数据不一致缺点:存在延时操作,所以会造成服务器的阻塞, 所以不适合高并发的场景如果需要再极端情况下人仍然保证Redis和MySQL的数据一致性,...
  • Redis与数据库的数据一致性

    千次阅读 2022-02-14 22:14:25
    当数据库内容变化的时候,到底应该先操作数据库还是先操作缓存呢?本文带你了解如何解决Redis和数据库的数据一致性问题
  • Mysql和Redis如何保证数据一致性

    千次阅读 2022-03-31 09:50:11
    如果先更新数据库成功,接着更新redis失败,那么会造成数据一致,所以这种方法舍弃 二、先更新redis,在更新数据库 这种方案和第一种相似,也具有相同的问题 如果更新reids成功,更新数据库失败,那么同样会造
  • MySQL与Redis数据一致性解决方案总结,MySQL学习总结
  • Redis缓存如何保证数据一致性 一. Redis概述 redis是一个内存数据库, 因此数据基本上都存在于内存当中 但是Redis会定时以追加或者快照的方式刷新到硬盘中. 由于redis是一个内存数据库, 所以读取写入的速度是非常快...
  • (2)、如果写数据库的值与更新缓存的值不一致,写入缓存中的数据需要经过几个表的关联计算后得到的结果插入缓存中,那就没有必要马上更新缓存,只有删除缓存即可,等到查询的时候在去把计算后得到的结果插入到缓存...
  • redis基础篇——数据一致性

    千次阅读 2020-12-01 11:41:51
    数据一致性 缓存使用场景 针对读多写少的高并发场景,我们可以使用缓存来提升查询速度。 当我们使用Redis作为缓存的时候,一般流程是这样的: 如果数据在Redis存在,应用就可以直接从Redis拿到数据,不用访问...
  • 面试官:谈谈Redis缓存和MySQL数据一致性问题

    千次阅读 多人点赞 2020-11-10 12:24:11
    重在穿透吧,也就是访问透过redis直接经过mysql,通常是一个不存在的key,在数据库查询为null。每次请求落在数据库、并且高并发。数据库扛不住会挂掉。 解决方案 可以将查到的null设成该key的缓存对象。 当然,也...
  • Redis和MySQL保持数据一致性

    千次阅读 2022-04-23 11:25:10
    但是,Mysql和Redis是两种不同的数据库,如何保证不同数据库之间数据一致性就非常关键了。 导致数据不一致的原因: 1、在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。 2、所以,就需要...
  • 这个方案,会保证 MySQL 和 Redis 的最终一致性,但是如果中途请求 B 需要查询数据,如果缓存无数据,就直接查 DB;如果缓存有数据,查询的数据也会存在不一致的情况。 所以这个方案,是实现最终一致性的终极解决...
  • 导语|本文的主要思路是首先带大家认识了解MySQL和Redis数据一致性情况,然后进行反推不一致的情况,从而进行探究单线程中的不一致的情况。同时探究多线程中的不一致的情况,拟定数据一...
  • Redis和MySQL如何保持数据一致性

    千次阅读 多人点赞 2022-03-14 19:48:09
    Redis和MySQL如何保持数据一致性? 在高并发的场景下,大量的请求直接访问Mysql很容易造成性能问题。所以,我们都会用Redis来做数据的缓存,削减对数据库的请求。但是,Mysql和Redis是两种不同的数据库,如何保证不同...
  • 如何保证Redis与数据库的数据一致性

    千次阅读 2021-06-01 09:16:41
    读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。 不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有...
  • 1.先更新 mysql 数据, 再手动清除 Redis 缓存 , 最后重新查询最新的数据同步到Redis中,保证最终一致性。 2.更新 mysql 数据, 在采用 mq 异步的形式 同步数据Redis 中 。 缺点: 延迟概率就比较大 优点: ...
  • Redis和MySQL如何保持数据一致性?

    千次阅读 2022-03-02 15:09:50
    但是,Mysql和Redis是两种不同的数据库,如何保证不同数据库之间数据一致性就非常关键了。 数据不一致的原因 导致数据不一致的原因 1、在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。 2、...
  • redis主从库如何保证数据一致性

    千次阅读 2022-05-15 12:23:44
    Redis 提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。 ##为什么要采用读写分离的方式呢? 如果不管是主库还是从库,都能接收客户端的写操作,要保持这个数据在三个实例上一致,就要...
  • 既然要解决这个问题,那么首先要大概了解为啥会出现数据一致呢?根本原因是我们无法将数据库更新操作与缓存更新操作放在同一个事务内同步成功,同步失败! 下面列举几个常见的操作以及各自的问题 1、先更新...
  • 首先,我们先来看看有哪几种一致性的情况呢?如果你的项目对缓存的要求是强一致性的...最终一致性是弱一致性的一个特例,系统会保证在一定时间内,能够达到一个数据一致的状态。这里之所以将最终一致性单独提出来,是因

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 156,057
精华内容 62,422
关键字:

redis数据一致性

友情链接: CPP.rar