redis缓存与数据库双写不一致问题

1. 先更新数据库,再更新缓存

问题:(1)线程A写操作先更新数据库

           (2) 线程B写操作也更新数据库

            (3)当线程B比线程A先更新缓存(线程A停滞卡顿)

            (4)线程A最后更新缓存

 a,导致redis缓存与数据库不一致,出现脏数据

b,频繁更新,浪费性能

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

1,A,B两个线程同时要更新数据,并且A,B已经都做完了删除缓存这一步,A先更新数据库,C线程读取数据,由于缓存没有,则查数据库,并把A更新的数据,写入了缓存,最后B更新数据库。那么缓存和数据库的值不一致

2,   (1)请求A进行写操作,删除缓存
        (2)请求B查询发现缓存不存在
        (3)请求B去数据库查询得到旧值
        (4)请求B将旧值写入缓存
        (5)请求A将新值写入数据库

    延时双删+设置超时时间

(1)先淘汰缓存
(2)再写数据库
(3)休眠1秒,再次淘汰缓存

 伪代码:

public void write(String key,Object data){
        redis.delKey(key);

        db.updateData(data);

        Thread.sleep(1000);

        redis.delKey(key);

    }

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

旁路缓存策略(Cache Aside Pattern)

流程:

  1. 首先从缓存中查询数据,如果缓存命中则直接返回。

  2. 缓存未命中,则去数据库中读取。

  3. 将从数据库中读取的结果的副本放入到缓存中,并返回。

  4. 写操作

    流程:

    1. 首先更新数据库。
    2. 然后删除缓存中的数据

问题:(1)缓存刚好失效
           (2)请求A查询数据库,得一个旧值
           (3)请求B将新值写入数据库
           (4)请求B删除缓存
           (5)请求A将查到的旧值写入缓存

 但 读操作比写操作耗时更少,上述情况出现概率极低

使用Cache-Aside Pattern时,一定要合理地设置过期策略。如果过期时间太短,可能导致大量请求涌入数据库。相反,如果过期时间太长,有可能导致缓存中数据的大量失效。使用缓存的一个原则,就是尽量缓存那些相对静态的、频繁被读取的数据。

推荐使用Cache Aside Pattern;

但需根据自身业务场景合理变通。

通过给缓存设置合理过期时间,是保证最终一致性的解决方案。

思考:若删除缓存失败导致数据不一致:

保障的重试机制:消息队列

参考:redis缓存数据与数据库如何保持一致性_君莫笑_0808的博客-CSDN博客_如何保持redis和数据库一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值