今天看到一个有意思的问题,如何保证缓存和数据库的一致性,思考后查资料总结如下。

要对数据库更新,如何处置缓存,更新or删除?

选择删除缓存

因为要更新的数据可能是简单的也可能是复杂的,复杂的数据更新缓存的话,成本较大,所以选择删除缓存。

如果选择更新缓存的话,频繁的写操作意味着数据库和缓存都频繁更新,但重点是,该数据的读频率多大。根据28法则,20%的数据占了80%的访问量,对于某些缓存的频繁更新有点得不偿失。

先淘汰缓存还是先更新数据库?

先淘汰缓存

如果先更新数据库,再淘汰缓存,数据库更新完了之后,若缓存淘汰失败,那么后面读到的都是脏数据了,直到缓存失效。

如果先淘汰缓存,再更新数据库,如果数据库更新失败,只会造成一次缓存miss。相较而言,后者对业务的影响较小。

高并发下数据不一致问题的分析与解决

如下场景:同时有一个请求A进行更新操作,另一个请求B进行查询操作
(1)请求A进行写操作,删除缓存
(2)请求B发现缓存不存在
(3)请求B去数据库查询得到旧值
(4)请求B将查到的旧值写入缓存
(5)请求A将新值写入数据库

这样就出现了数据不一致的错误,导致脏读。

只有在对数据进行并发读写时,才会出现这样的问题。

其实并发量很低,特别是读很低,每天就1w的访问量,那么很少会出现上面的状况。

但问题是,如果每天的是上亿的流量,每秒并发读是几万,每秒只要有数据更新的请求,就可能会出现上述的数据库+缓存不一致的情况。

高并发了以后,问题是很多的。

解决方法

串行化之后,会导致系统的吞吐量大幅度降低,用比正常情况下多几倍的机器去支撑线上的一个请求。

一般来说,如果系统不是严格要求缓存+数据库必须一致性的话,缓存可以稍微的跟数据库偶尔有不一致的情况,最好不要做这个方案。