缓存设计 - 互联网最佳实践Cache Aside Pattern

What

Cache Aside Pattern翻译过来是旁路缓存方案的经验实践,这个实践分为读实践、写实践。

How

读实践:
在这里插入图片描述

  1. 先读缓存,再读数据库
  2. 如果cache hit,则直接返回cache数据
  3. 如果cache miss,则访问db,并将数据set回缓存,然后返回。

写实践:
在这里插入图片描述
先操作数据库写,再淘汰缓存(这里淘汰缓存是删除,而不是更新)

Why

  1. 写实践中,Cache Aside Pattern为什么是淘汰缓存,而不是更新缓存?
    在这里插入图片描述
    答:如果是更新缓存,在并发写时,可能出现数据不一致。
    如上图所示,如果采用set缓存。

    在1和2两个并发写发生时,由于无法保证时序,此时不管先操作缓存还是先操作数据库,都可能出现:
    (1)请求1先操作数据库,请求2后操作数据库
    (2)请求2先set了缓存,请求1后set了缓存
    导致,数据库与缓存之间的数据不一致。相同的场景如果是delete则不会有此问题。
    所以,Cache Aside Pattern建议,delete缓存,而不是set缓存。

  2. 写实践中,Cache Aside Pattern为什么建议先操作数据库,再操作缓存?
    在这里插入图片描述
    答:如果先操作缓存,在读写并发时,可能出现数据不一致。
    如上图所示,如果先操作缓存。

    在1和2并发读写发生时,由于无法保证时序,可能出现:
    (1)写请求淘汰了缓存
    (2)写请求操作了数据库(主从同步没有完成)
    (3)读请求读了缓存(cache miss)
    (4)读请求读了从库(读了一个旧数据)
    (5)读请求set回缓存(set了一个旧数据)
    (6)数据库主从同步完成
    导致,数据库与缓存的数据不一致。

    所以,Cache Aside Pattern建议,先操作数据库,再操作缓存。

Drawback

然而,Cache Aside Pattern方案并不是完美无缺的,那么Cache Aside Pattern存在什么问题呢?

  1. 如果先操作数据库,再淘汰缓存,如果数据库操作成功,但是淘汰缓存失败。此时数据库和缓存数据不一致。
    个人见解:这里个人觉得可以使用重试的方法,在淘汰缓存的时候,如果失败,则重试一定的次数。如果失败一定次数还不行,那就是其他原因了。比如说redis故障、内网出了问题。

Refer

  1. https://www.jianshu.com/p/3613d55fb843

猜你喜欢

转载自blog.csdn.net/hudmhacker/article/details/108403232