驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
缓存更新策略(一)
/  

缓存更新策略(一)

前言

缓存的引入能够帮助DB减轻检索压力,但是如果不能很好的处理数据一致性的问题,那么会导致读取脏数据的问题,解下来2篇文章就总结下几种缓存更新策略:

如果更新缓存

  • 先更新DB,再更新缓存
  • 先更新缓存,再更新DB

如果删除缓存

  • 先删除缓存,再更新DB
  • 先更新DB,再删除缓存

必要手段

为了保证数据的一致性,不论何种方式处理缓存,都应该给缓存设置过期时间,这个是缓存必须的要素,否则数据的最终一致性很难得到保证。

下述讨论的讨论方案中,是在没有设置缓存过期时间 的情况下的极端讨论,仅仅为了理清思路,实际开发过程中,都应该给缓存加上过期时间

更新缓存

先下结论:对于数据变化,不应该同步更新缓存。

因为:只有被查询的数据的数据建立缓存,才有意义。一个数据只会被更新,长期或者永远不会被查询,建立缓存就是浪费资源。

综上:建立缓存的操作应该是在数据被读取的时候。

先更新缓存,再更新DB

我们先来分析下,在更新缓存需要的时候,数据变更时如果:先更新缓存,再更新DB会有什么问题?

缓存的来源是DB,如果先更新缓存,在还未更新DB的这段时间内,如果有查询操作读取了这个缓存,读取的数据都是脏数据。

先更新DB,再更新缓存

如果先更新DB,再更新缓存又会遇到什么问题了?在如下场景中,问题就会出现:

  1. 第一步:2个线程A和B同时更新DB的一条数据,A线程先更新DB,B后更新DB。(此时B的数据为最新的)。
  2. 第二步:接下来A和B需要更新缓存,因为网络原因,B发送的缓存更新指令先于A到达。(完全有可能,因为A和B是异步的)
  3. 第三步:缓存中间件中,缓存先被B更新(最新的数据),才被A更新(老的数据)。因为B的数据才最最新的,但是缓存最后被A更新,此时的缓存的数据是脏数据。

同样是脏数据的问题。

结论

在不设置过期时间的情况下,不管是先更新DB还是更新缓存,都非常容易出现缓存脏数据的问题,且不容易进行处理。

再加上数据在不需要的时候被缓存就是浪费时间,所以不应该在数据发生变更的时候更新缓存。

既然不更新缓存,那么就删除缓存吧,但是先删除缓存还是先更新数据库了?

骐骥一跃,不能十步。驽马十驾,功在不舍。