缓存一致性设计方案
作者:互联网
文章目录
前言
公司项目中发生了缓存一致性
的问题,具体场景如下:
- 系统的业务配置更新为生效状态后,业务服务实际使用的配置数据还是旧版本的数据
- 偶现业务服务使用的配置数据不完整,造成业务流程异常
项目中引入了缓存,排查问题时发现 redis 中缓存的数据就是旧版本数据,而且有时会发生缓存中配置数据不完整的现象。分析代码,发现导致缓存数据与数据库数据不一致的原因有两个,本文主要分析解决 缓存淘汰设计不合理
的问题
MySQL读写分离
项目中使用了公司的读写分离框架,查询数据时默认读从库。因为主从延迟 的存在,主库数据更新后需要一定时间才能在从库读到更新后的数据,如果在这期间缓存已经失效并且恰好有查询进来,只能查询到从库旧数据,最后将其缓存到了 redis。这个点比较好解决,只要指定查询主库就可以缓存淘汰设计不合理
项目代码中将淘汰缓存的操作包裹在@Transcational
注解的方法的末尾,这样做实际是在事务提交前就淘汰了缓存,当并发较高时,如果查询在更新事务执行时进行,并且持续到更新事务结束,这样未加入同一个事务的多表查询就可能存在有些表数据能查到,有些表数据在更新事务结束后查不到的情况,也就造成了缓存中配置数据的不完整
1. 缓存一致性
应用系统通常会引入缓存来缓解数据库压力,这样可以提高系统吞吐,提升用户体验,但也带来了数据污染的风险,也就是缓存一致性
问题。所谓缓存一致性
指的是缓存数据和数据库数据之间的一致,如果没有合理的缓存设计,很容易导致缓存与数据库之间的不一致问题
2. 缓存一致性设计分析
缓存穿透等概念 中笔者大致介绍了缓存相关概念,缓存一致性问题总是由数据库源数据更新引发,所以在数据更新时首先要确定缓存的处理方式,通常的处理是淘汰缓存而不是更新缓存
,原因如下:
- 更新数据库时如果同步更新缓存数据,由于二者属于不同的中间件,很难保证原子操作,则必然存在并发更新缓存造成的数据不一致
- 更新缓存数据通常需要序列化,如果将其和数据库更新的操作绑定在一起,会额外提高数据更新操作的性能成本
基于以上共识,现在要考虑的就是在更新数据时如何淘汰缓存,直观的处理方式有两种,但是二者都有一定的问题,下文将详细说明
- 先淘汰缓存,再更新数据
- 先更新数据,再淘汰缓存
2.1 先淘汰缓存,再更新数据
这个方案可能导致问题的处理流程如下图所示,示意图中有两个线程在操作缓存,具体步骤如下:
线程1
进行数据库更新操作,在数据库更新之前首先淘汰掉缓存线程1
开启更新事务,执行数据库更新- 在
线程1
执行更新事务时,线程2
执行数据查询,首先去查询缓存- 由于
线程1
已经淘汰掉缓存,此时线程2
未查询到缓存,只能去查询数据库线程1
的更新事务执行耗时比较长,线程2
查询数据库只能查到旧的数据,并在查到旧数据后将其缓存起来线程1
更新事务执行完毕,更新后的最新数据对外可见,但是缓存中已经被线程2
保存了旧数据- 由于以上原因,数据库数据与缓存数据出现不一致
2.2 先淘汰缓存,再更新数据
这个方案的出现异常的处理流程如下:
线程1
进行数据库更新操作,开启更新事务线程2
执行数据查询,此时缓存中数据不存在或者已经过期淘汰,只能去查数据库线程2
查询数据库,此时只能查到旧数据,但是由于网络波动、GC 等原因,一直没有拿到数据库返回的数据- 在
线程2
等待数据库返回数据期间,线程1
更新事务执行提交,数据库最新数据对外可见线程1
更新事务执行完毕,淘汰掉旧的缓存数据线程2
在线程1
淘汰缓存之后终于拿到了数据库返回的旧数据,并使用旧数据去更新缓存- 由于以上原因,数据库数据与缓存数据出现不一致
3. 实用方案-延时二次淘汰
针对上一节提到的问题,一个能较大限度降低缓存一致性风险的方案是进行缓存二次淘汰,其处理流程如下:
线程1
进行数据库更新操作,在数据库更新之前首先淘汰掉缓存线程1
开启更新事务,执行数据库更新- 在
线程1
执行更新事务时,线程2
执行数据查询,首先去查询缓存- 由于
线程1
已经淘汰掉缓存,此时线程2
未查询到缓存,只能去查询数据库,此时查到旧数据,但是由于网络波动、GC 等原因,一直没有拿到数据库返回的数据线程1
的更新事务终于提交,数据库最新数据对外可见线程1
更新事务执行完毕,生成延时任务用于淘汰缓存线程2
此时终于拿到了数据库返回的旧数据,并使用旧数据去更新缓存- 由于以上原因,数据库数据与缓存数据出现短时不一致
线程1
提交的延时任务执行,淘汰掉线程2
更新的缓存数据,缓存中没有数据,下次查询必然要走数据库,则消除了缓存不一致的问题
需注意,延时任务的延时时间需要大于读取缓存的平均耗时(也即是线程2读取缓存,更新缓存这个过程的耗时)
标签:缓存,数据库,更新,线程,一致性,设计方案,淘汰,数据 来源: https://blog.csdn.net/weixin_45505313/article/details/120795425