美文网首页测开
如何保持Redis和db的数据一致性

如何保持Redis和db的数据一致性

作者: _52Hertz | 来源:发表于2020-03-02 17:53 被阅读0次

    导致数据不一致性的场景:

    场景一(查询):

    高并发的时候,线程A redis未命中,去查询db,得到值1,还未回种redis,这时候db修改了,线程B redis未命中,查询db,得到值2,但线程B先存入redis,然后线程A存入redis,这时候redis的数据是值1,是条脏数据。

    解决方案:

    通过加锁解决,保证查询db和存入redis操作的原子性,或者用乐观锁,加个版本号或者时间戳,存入redis之前查下,但还是要保证查和存的原子性

    场景二(更新):

    先写入db,在删除缓存,可能出现db已经更新,但redis中未更新的情况,这时候redis命中后查到的数据就是旧数据,所以不行。

    场景三(更新):

    先删除缓存,再写入db。这其实也有并发问题:线程A是更新操作,先删除缓存,但还没写入db,这时候线程B来了,是个查询操作,发现缓存中没有数据,就去查db,但这时候线程A的写入操作还没完成,于是线程B查到了脏数据。

    解决方案:

    老外提出了一个缓存更新套路,名为Cache-Aside pattern。其中就指出

    失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
    命中:应用程序从cache中取数据,取到后返回。
    更新:先把数据存到数据库中,成功后,再让缓存失效。

    这样的策略其实还是会出现并发问题:
    假设这会有两个请求,一个请求A做查询操作,一个请求B做更新操作,那么会有如下情形产生

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

    此时,产生脏数据的原因:

    请求B的写操作(3)要比请求A(2)的读操作耗时更短,才会出现(4)先于(5)
    但是出现该情况的可能性是有多大呢,这边以读写分离为例,为啥会出现读写分离,读写分离的意义就是因为读操作比较快,耗资源少,不然要读写分离干啥?所以出现该场景的可能性太小了。

    总结

    redis和db的数据一致性理论上是不可能,如果真的对数据有强一致性的要求,就不应该放缓存里!!

    相关文章

      网友评论

        本文标题:如何保持Redis和db的数据一致性

        本文链接:https://www.haomeiwen.com/subject/ggzvkhtx.html