• 如何保证redis和数据库的一致性


    在项目中难免会使用到redis作为缓存,去减轻数据库的访问压力,但是涉及到数据更新时,如果redis和数据库的操作设计出现问题,就会导致redis缓存中和数据库中的数据不一致的情况。那么我们如何去保证缓存与数据库中数据一直呢?

    四种同步策略

    想要保证缓存与数据库的双写一致,一共有四种方式,即四种同步策略
    1、先更新缓存,再更新数据库
    2、先更新数据库,再更新缓存
    3、先删除缓存,在更新数据库
    4、先更新数据库,再删除缓存
    更新缓存和删除缓存的选择
    更新缓存

    优点:
    如果每次数据变化都能被及时更新,那么查询数据时不容易出现不命中的情况,
    缺点:
    1、如果数据的计算复杂,频繁的更新会造成服务器性能的消耗比较大
    2、如果数据并不是被频繁使用,那么频繁更新也只是浪费服务器性能,对业务没有多大的帮助
    适用于数据使用较为频繁,且数据的计算不那么复杂的场景

    删除缓存

    优点:不需要顾忌数据的复杂性,直接删除即可
    缺点:查询数据时,增大未命中的几率,从而增大数据库的访问压力
    适用于数据使用频率不高的场景

    在上面四种同步策略中,都存在导致数据不一致的风险

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

    在这里插入图片描述

    操作步骤:
    a、线程A删除缓存中的数据,
    b、线程A更新数据库中的数据,但是更新失败
    c、此时线程B去获取缓存中的数据,但是未命中
    d、线程B,去数据库中获取数据,但此时的数据因为更新失败为旧数据
    e、线程B将数据库中查到的数据同步到缓存中去
    f、线程A此时更新数据到数据库成功
    最后数据库和redis缓存中的数据不一致

    如果在更新数据库时没有出现失败,也同样存在会造成数据不一致的情况
    在这里插入图片描述
    操作步骤:
    a、线程A删除缓存中的数据,
    b、此时线程B去获取缓存中的数据,但是未命中
    c、线程B,去数据库中获取数据,但此时的数据因为更新失败为旧数据
    d、线程B将数据库中查到的数据同步到缓存中去
    e、线程A此时更新数据到数据库成功
    最后数据库和redis缓存中的数据不一致,这里造成的数据不一致的原因是线程B在数据库还未更新时就已经获取到了旧的数据。

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

    在这里插入图片描述
    操作步骤:
    1、线程A更新数据库中的数据
    2、线程A删除缓存中的数据,删除失败
    3、线程B查询缓存中的数据,查询到旧数据
    4、线程A异步重试删除缓存
    这里,删除缓存中数据失败后就会造成线程B获取到缓存中的旧数据,从而导致数据不一致的情况

    如果缓存没有删除失败的情况也可能导致数据不一致
    在这里插入图片描述
    操作步骤:
    1、线程A更新数据库中的数据
    2、线程B查询缓存中的数据,查询到旧数据
    3、线程A删除缓存
    如果线程B在缓存删除前获取到了缓存中的数据,那么线程B获取到的还是旧数据,也会导致数据不一致的情况

    延时双删

    上面中先删除缓存,在更新数据库在不出现失败时也会出现数据不一致的情况,那么我们要有什么解决方案呢。我们就采用延时双删的策略来保证缓存中的数据时更新后的数据
    操作步骤
    1、先删除缓存
    2、更新数据库
    3、线程等待 N秒(等待时间根据具体业务来判断)
    4、再删除缓存
    这样就保证了缓存中的数据最终会和数据库中的数据保持一致

    数据库读写分离

    先删除缓存,在更新数据库,如果数据库采用读写分离架构会有什么影响呢?
    在这里插入图片描述

    操作步骤:
    1、线程A删除缓存
    2、线程A更新从数据库
    3、线程B查询缓存,未命中
    4、线程B去从数据库查询数据,还未同步,所以从数据库为旧数据
    5、线程B将数据更新到缓存中
    6、主数据库同步数据到从数据中
    这样还是会出现数据不一致的情况,那么我们要怎么解决呢?
    如果只是为了更新redis的数据的数据库查询,让线程同步数据时强行指定到主数据库执行

  • 相关阅读:
    Oracle数据库:使用 bash脚本 + 定时任务 自动备份数据
    案例 | 美创助力镇海区大数据发展管理中心构建“数改”安全防护力
    PostgreSQL 源码部署
    【开发教程4】开源蓝牙心率防水运动手环-外部 Flash 读写
    小程序订单中心path设置本次审核不通过,审核原因:小程序尚未发布,无法审核。
    ES报错1
    多协议充电桩平台系统小程序方案
    Java版 招投标系统简介 招投标系统源码 java招投标系统 招投标系统功能设计
    SpringDataRedis快速入门(一)
    玄幻小说阵法大全—— 网文助手
  • 原文地址:https://blog.csdn.net/weixin_44740485/article/details/124846964