【七日打卡】CacheAsidePattern简单理解

前言

由于本人水平有限,如有错误,欢迎指正,谢谢!

本文中谈到的一些概念,作如下的约定:

  1. 缓存: redis中的数据
  2. 数据库:MySQL

本文不会介绍redis和MySQL相关的内容,只关注Cache Aside Pattern。

什么是 Cache Aside Pattern

Cache Aside Pattern是最经典的缓存 + 数据库读写的模式。

  1. 读的时候,先读缓存,缓存没有的话,那么就读数据库,然后取出数据后放入缓存,同时返回响应

  2. 更新的时候,先删除缓存,然后再更新数据库(缓存和数据库双写)

理解 Cache Aside Pattern

在Cache Aside Pattern中,读请求的思路是,先从缓存冲读取,如果缓存中无数据,则从数据库读取数据并写入缓存中,然后返回响应。这个很好理解。

对于更新缓存和数据的操作,深究一下,可能会产生如下的疑问:

  1. 为什么是先删除缓存,再更新数据库
  2. 为什么是删除缓存而不是更新缓存

我们依次来理解这两个问题。

为什么是先删除缓存,再更新数据库

如果我们先修改数据库,再删除缓存,如果删除缓存失败了,那么会导致数据库中是新数据,缓存中是旧数据,数据出现不一致。

为什么是删除缓存而不是更新缓存

理由1:高并发场景下,多个并发写,可能会导致数据不一致。

比如在1和2两个并发写发生时,由于无法保证顺序,此时不管先操作缓存还是先操作数据库,都可能出现:

  • 请求1先操作数据库,请求2后操作数据库
  • 请求2先set了缓存,请求1后set了缓存

如果我们仅仅删除缓存,不会发生数据不一致的问题。

理由2:lazy init懒加载的思想

因为有可能当前缓存数据会成为冷数据,访问频率不会太高,也没有必要及时去更新缓存。这条缓存数据可能1个小时只被访问了100次,就没有必要去更新缓存数据。当下一次对该数据的读请求发生时,才去更新缓存。这是一种懒加载思想。

理由3:更新缓存可能需要复杂计算

先删除缓存再更新数据库就一定天衣无缝了吗

这样在高并发场景下还是可能会出现问题。

  1. 假如数据发生了变更,先删除了缓存,然后要去修改数据库,此时还没修改。

  2. 然后一个请求过来,去读缓存,发现缓存空了,去查询数据库,查到了修改前的旧数据,放到了缓存中

  3. 接着数据变更的程序完成了数据库的修改。

爆炸了,此时数据库和缓存中的数据不一样了。这就是高并发场景下的缓存和数据库双写不一致问题

总结

本文先对Cache Aside Pattern做了基本的定义(读者可参考下图),然后去解答了两个疑惑,并引出了,先删除缓存再更新 在高并发场景下的 缓存和数据库 双写不一致的问题,这个问题我们会在接下来的文章中去讲解谢谢!

Cache Aside Pattern

参考

  1. Cache Aside Pattern(缓存模式)解析

  2. 中华石杉亿级流量电商详情页课程

    感谢我的老师,通过大量画图+大白话式的讲解,让我初步理解了Cache Aside Pattern