浅析数据库与缓存的双写一致性问题
缓存由于其高并发和高性能的特性,在项目中被广泛使用。读缓存流程如下图: 双写一致性有以下三个要求: 缓存不能读到脏数据 缓存可能会读到过期数据,但要在可容忍时间内实现最终一致 这个可容忍时间尽可能的小 要想同时满足上面三条,可以采用读请求和写请求串行化,串到一个内存队列里去,这样就可以保证一定不会出现不一致的情况。但是,串行化之后,就会导致系统的吞吐量会大幅度的降低,要用比正常情况下多几倍的机器去支撑线上请求。 所以,在这里,我们讨论三种常见方法: 先更新数据库,再更新缓存 先删除缓存,再更新数据库 先更新数据库,再删除缓存 1. 先更新数据库,再更新缓存 这种方法是大家普遍反对的,原因集中在下面两点: 原因1:线程安全角度。 同时有请求A和请求B进行更新操作,那么会出现: 线程A更新了数据库 线程B更新了数据库 线程B更新了缓存 线程A更新了缓存 这就出现请求A更新缓存应该比请求B更新缓存早才对,但是因为网络等原因,B却比A更早更新了缓存。这就导致了脏数据,因此不考虑。 > "先更新缓存,再更新数据库"这种方案同理,也是造成脏数据,所以不被考虑 原因2:业务场景角度。 有如下两点: 如果你是一个写数据库场景比较多,而读数据场景比较少的业务需求,采用这种方案就会导致数据压根还没读到,缓存就被频繁的更新,浪费性能。 如果你写入数据库的值,并不是直接写入缓存的