我们来聊聊业界最通用的缓存业务代理,即Cache aside,这种模式下,具体应该用什么姿势编写代码。

读的姿势比较简单:

缓存业务代理模式Cache aside的最佳实践插图

先读缓存,如果缓存有数据,直接返回;如果没数据,再查db,查出来的数据先更新缓存,再返回。

写的姿势有四种,我们应该选哪种呢?

1)先更新db,再更新缓存

这种姿势在多写并发的时候会造成数据不一致。例如对于同一条记录,即使db有写锁,但如果写请求1与缓存所在机房距离太远或是卡顿了,先发后至,写请求2先更新完了缓存,如果db无写锁问题就更大了,所以不推荐

这也告诉我们部署缓存应该和数据库挨的近一点。

缓存业务代理模式Cache aside的最佳实践插图1

优点是在更新数据库的同时更新了缓存,下次读取就会直接命中缓存了。

2)先更新缓存,再更新db

与第一种一样,存在更严重的写并发问题,枪毙

3)先删除缓存,再更新db

当读写请求并发时,读请求插在删除和更新操作中间,就会出现数据不一致的问题。由于更新数据库操作较慢,而读操作很快,这种case发生的概率还是不小的,枪毙

缓存业务代理模式Cache aside的最佳实践插图2

4)先更新db,再删除缓存(推荐)

缓存业务代理模式Cache aside的最佳实践插图3

与第三种情况类似,当读写并发时,仍然存在数据不一致的可能。但不一致发生的前提是写请求插在读请求中间,我们知道同一条数据数据库读通常是比写要快的,缓存操作也肯定要比数据库快,所以这种不一致发生的概率很小。

缓存业务代理模式Cache aside的最佳实践插图4

缺点是需要在下一次读取时才能从数据库中读出数据再写入缓存,会降低缓存的命中率。

当然, 为了避免上面这种小概率出现的不一致问题,我们还可以利用缓存设置分布式锁,同时对缓存设置过期时间。

例如在读取或更新一条数据前,先加上分布式锁。综上所述,我个人首推缓存业务代理模式(Cache aside)的姿势是先更新db,再删除缓存,同时加上缓存过期时间。朋友们至少要记得更新数据时先操作数据库,再操作缓存哦。



缓存业务代理模式Cache aside的最佳实践插图5

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://choupangxia.com/2022/07/01/cache-aside-4/