缓存和数据库的数据一致性问题是一个老生常谈的问题了。在这里我记录几种方案及其可能出现的问题。
先更新缓存,再更新数据库:此时线程A去先去更新缓存,然后更新数据库,但数据库更新时出现回滚,更新失败,数据库和缓存数据不一致。
先更新数据库,在更新缓存:线程A去更新数据库->线程B也去更新数据库->A更新数据库完毕->A去更新缓存->B更新数据库完毕->B更新缓存完毕->A更新缓存完毕,此时导致数据不一致
先删除缓存,在更新数据库:线程A删除缓存->线程B查询会去更新缓存->线程A更新数据库,数据不一致。(延迟双删,即在更新数据库后,延迟在去删除缓存,保证在此期间,其他线程读,导致数据不一致。注意:延迟双删不能绝对解决一致性问题,在更新完毕,延时删除之间,来了读线程,但因为网络等原因,更新缓存操作被延迟到了,延迟删除之后,也会导致数据不一致)
先更新数据库,在删除缓存:线程A更新数据库->线程A删除缓存->线程B查询->线程C更新数据库->线程C删除缓存->线程B更新缓存。数据不一致。
请求串行化:将访问操作串行化,先删缓存,将更新数据库的操作放进有序队列中从缓存查不到的查询操作,都进入有序队列。需要解决的问题:读请求积压,大量超时,导致数据库的压力:限流、熔断。如何避免大量请求积压:将队列水平拆分,提高并行度。保证相同请求路由正确。