You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

31 lines
2.2 KiB

一致性问题多发生在数据更新阶段目前有2种
**(1) 先删除缓存,再更新数据库**
**(2) 先更新数据库,再删除缓存**
# 一、为什么不能更新缓存而要删除
因为并发情况下的执行顺序与预期不一致,会出现旧值覆盖新值的情况,如图所示
![[Snipaste_2023-03-01_17-52-19.png]]
线程1 先发起的更新请求过了一段时间线程2也发起更新但是由于线程2比线程1先执行完当线程1执行完成后会覆盖线程2更新的缓存值就导致了库与缓存数据不一致问题。因此并发环境下不要更新缓存。
# 二、为什么不能先删除缓存,再更新数据库
![[Snipaste_2023-03-01_17-52-19 1.png]]
如图所示,读请求如果没有命中缓存,会先查库再更新缓存。假如先删除缓存,再更新库,如下图所示:
![[Snipaste_2023-03-01_17-52-19 2.png]]
当写、读两个线程同时执行由于读先执行完读线程将缓存的val更新为a1但是库中实际值是a2此时出现不一致情况。
# 三、Cache-Aside Pattern
Cache-Aside Pattern即旁路缓存模式它的提出是为了尽可能地解决缓存与数据库的数据不一致问题。
通俗的说就是先更新库,再删除缓存,理想情况下会出现极短的不一致问题。
![[Snipaste_2023-03-01_17-52-19 3.png]]
如图所示线程2 的查询在线程1之前完成将缓存val设为a1随后线程1删除缓存当下一次查询时缓存没有命中就会将缓存val设为a2实现了一致性。
## 3.1 不一致场景
![[Snipaste_2023-03-01_17-52-19 4.png]]
当读线程比写线程执行慢的时候又会产生不一致情况,直到缓存过期或下一次更新。因此引入了延迟双删策略。只需要保证,删除动作在写动作之后完成就能保证一致性。
## 3.2 延迟双删
![[Snipaste_2023-03-01_17-52-19 6.png]]
引入了第二次删除将要删除的Key交给定时任务或MQ只要线程2的写缓存操作在设定的延时范围内执行完成就能保证一致性。延迟时间需要更新业务来设置。
## 3.3 改进延迟双删
假如删除缓存的动作失败了,需要加入重试机制。