在我们的项目中,修改数据后,考虑缓存数据更新的及时性,我们可能会采用主动更新缓存的策略。主要有如下几种策略:
- 先更新缓存,再更新数据库
- 先更新数据库,再更新缓存
- 先删除缓存,再更新数据库,访问时按需加载数据到缓存中
- 先更新数据库,再删除缓存,访问时按需加载数据到缓存中
上面4中策略我们应该怎么选择呢?已下我们就逐一分析这4中策略:
“先更新缓存,再更新数据库” 策略不可行。数据库设计负责,压力集中,数据库因为超时等原因,操作失败的可能性会很大。此外还会涉及到事务,很有可能因为数据库更新失败,导致缓存和数据库的数据不一致。
“先更新数据库,在更新缓存” 策略不可行。以试,如果A和B两个线程先后完成数据库更新,但是更新缓存时是B和A的顺序,那么可能旧数据更新到缓存中引发缓存和数据库数据不一致;二是,我们不确定缓存中的数据是否会被再次访问,不一定要把所有数据都更新到缓存中去。
“先删除缓存,再更新数据库,访问时按需加载数据到缓存中” 策略也不可行。并发的情况下,很有可能删除缓存后还没有来得及更新数据库,就有另外一个线程读取了旧值到缓存中,如果并发量很大的话这个概率也会很大。
“先更新数据库,再删除缓存,访问时按需加载数据到缓存中” 策略是最好的。虽然在极端的情况下,这个策略也可能会出现数据不一致的问题,但概率非常低,基本上可以忽略。举一个“极端情况”的栗子,比如更新数据的时间点刚好是数据缓存失效的瞬间,这时A先读取到一个旧值,随后在B操作数据库完成更新并且删除了缓存之后,A再把旧值加入到缓存。
需要注意的是,更新数据库后删除缓存的操作可能失败,如果失败则考虑把任务加入到延迟队列进行延迟重试,确保数据可以删除,缓存可以及时更新。因为删除操作时幂等的,所有即使重复删除问题也不是太大,这又是删除比更新好的一个原因。
因此,针对缓存更新更推荐的方案是,缓存中的数据不由数据更新操作主动触发,统一在需要使用的时候按需加载,数据更新后及时删除缓存中的数据即可。