之前写了三篇关于秒杀的文章,里面提到了通过分布式缓存来缓解数据库压力。最近有朋友私信回复问,缓存和数据库是如何进行同步的,通过大家的问题,让我感到这个点确实可以聊一下,所以今天准备写一写,供大家做一个参考。
缓存同步的常用模式
缓存同步的模式,可以按照缓存的用途(主要用于读或者写)分为两类:读缓存的同步和写缓存的同步。
读缓存的同步:
缓存预加载模式
提前将数据从数据库加载到缓存,如果数据库有写更新,同步更新缓存。在秒杀情况下,我们对商品数据就按照这种模式进行处理。
缓存直读模式
应用先查看缓存中是否有该数据,有则直接使用,如果没有,从数据库加载,然后放入缓存,下次以后再访问就可以直接从缓存中获得。
写缓存的同步:
缓存直写模式
在数据更新时,同时写入缓存和数据库。这种模式是最稳妥的办法,但是性能会受到一定的影响。
缓存回写模式
在数据更新时只写入缓存。通常由一个后台队列检查缓存中数据的变化,再将据写到后端数据库。
如何避免缓存和数据库的数据不同步
上面介绍了缓存同步的模式,但光依靠模式,是不能完全阻止数据同步是没有问题的。比如说,有两个线程A和B,在并发情况下,他们如果能同时操作某条数据,由于同一个数据进行读写,在数据库层面并发的读写并不能保证完成顺序。就有可能导致数据库与缓存不同步。
所以在在缓存模式下,处理过程中,需要通过对该数据加锁,保证对数据的处理是严格按照串行处理的。
如何检查缓存和数据库的数据是同步的
1. 属性中增加一个版本号或者时间戳字段,每次更新缓存后,版本号+1或者取更新时间戳,下一次写操作前,先比较,然后再更新。
2. 建立一个定时任务,定义一个同步周期(5分钟或者15分钟),定时任务会对最近一个时间周期内数据库中更新过的数据进行比较,于缓存(例如redis)中的数据进行匹配和比较。
作者:ForestXie
链接:https://www.jianshu.com/p/e3365c9ed0a9