问题何在
先说下缓存的意义,简单来说,就是为了减少数据库压力,如果缓存是基于内存的,那么系统性能也会大大提升.
但是问题也伴随而来,如果我们的系统或者相关业务并不大,可以把数据全部加到缓存,比如一个秒杀,抢红包,可以直接操作缓存,等抢购结束,再写回数据库.但是如果数据多了,肯定就不能这样,我们就要制定策略来同时更新数据库和缓存,并保证二者的一致性
先删缓存,再修改数据库
也就是有一个写请求,我们把相关的缓存先删除,然后去修改数据库,如果后面有请求访问该数据,会直接到数据库,然后再把值写回缓存.
当然,这是理想的情况,现实是在我们的写请求删除缓存和写数据库之间可能有另一条请求访问该数据,然后在缓存中没有找到,就在数据库读到了旧数据,再写回了缓存,然后写请求再更新数据库,这个时候就有了数据库缓存不一致的情况.
解决办法
- 分布式锁 :
使用分布式锁的意义很简单,就是保证写请求操作的时候,没有其他请求影响,就是一个排他锁.具体的加锁情况是这样.
在写请求删除缓存前请求分布式锁,更新完数据库后释放锁.
在读请求发现缓存为空的时候,请求分布式锁.
很容易理解,同时这个办法也保证了强一致性,也就是任何时刻,缓存和数据库都是一致的,问题是只适合写请求少的情况,如果写请求过多,频繁的加锁会导致性能下降 - 延迟双删
如果我们不要求强一致性,用这个办法是可以的,其实很简单,就是在上面先删缓存,再修改数据库的基础上,等我们修改数据库完后,再次删除缓存,同时我们可以把第二次删除缓存以异步的形式进行,这个其实更容易理解,但是会有短暂的不一致,但是可以保证最终一致性.