随着业务的发展,流量会变得越来越大,我们DB的压力也就越来越大,我们会采取很多手段去降低DB的压力。这里手段有很多,复杂均衡,CDN,缓存,读写分离,集群。这里缓存比较常见,也是性能比较高的一种手段。但是用到缓存,往往用于不经常变化的数据,但是我们也存在需要缓存和数据库一致的场景。比如,商品的属性发生修改,要及时显示到用户的界面上。为了防止脏读,导致读用户的误导,我们就需要做到缓存和数据一致性。
在ENODE群里面,汤雪华老师给出了两种方案。第一种,定时job+Cache记录。正常的我们都是先读取DB数据,然后把数据缓存起来。那么我们可以每次执行一次DB(增删改)操作,同时将缓存key存入到数据库。数据的操作和Key的插入操作是一个事物,这样就可以保证,如果DB操作成功,那么对应的key一定成功。这个时候,我们开一个定时任务根据DB中的Key去删除缓存,那么用户请求过来,就会从新读取DB,并且重新缓存起来。这是一种懒加载的机制,并且易于实现。如果你的修改比较频繁,那么你就可以考虑在Job的时候,直接更新缓存而不是删除了,这样就不会降低缓存的命中率,防止一下子压垮DB。JOB是否是删除还是更新缓存,取决于你的并发数量。
第二种方案使用消息队列实现,有点类似CAP的感觉。修改数据的时候,不是直接更新DB,而是发送一条消息。这条消息所要做的就是,更新DB的同时,去更新缓存。如果更新DB失败,那么认为这个消息失败。如果更新DB成功,更新缓存失败,那么这个消息就会进行重试,直到更新缓存也成功,做到最终一致性。那么你的这个消息消费的方法一定要做到幂等,来保证可以重试。