Redis和MySQL如何保持数据一致性?

一、背景

在高并发的场景下,大量的请求直接访问Mysql很容易造成性能问题。所以,我们都会用Redis来做数据的缓存,削减对数据库的请求。但是,Mysql和Redis是两种不同的数据库,如何保证不同数据库之间数据的一致性就非常关键了。


二、导致数据不一致的原因:

当数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。

读数据从Redis缓存流程图如下:




三、缓存先后删除的问题:

当涉及到数据更新时,不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。

1.先删除缓存

如果先删除Redis缓存数据,然而还没有来得及写入MySQL,另一个线程就来读取,这个时候发现缓存为空,则去Mysql数据库中读取旧数据写入缓存,此时缓存中为脏数据;然后数据库更新后发现Redis和Mysql出现了数据不一致的问题。

2.后删除缓存

如果先写了库,然后再删除缓存,不幸的写库的线程挂了,导致了缓存没有删除,这个时候就会直接读取旧缓存,最终也导致了数据不一致情况,因为写和读是并发的,没法保证顺序,就会出现缓存和数据库的数据不一致的问题。



四、解决方案:

方案一:延时双删策略+缓存超时设置:

1、先删除缓存

2、再写数据库

3、休眠500毫秒(休眠时间根据实际业务逻辑的耗时决定。)

4、再次删除缓存

方案缺点:

1、在缓存过期时间内发生数据存在不一致

2、同时又增加了写请求的耗时。


方案二:异步更新缓存(基于Mysql binlog的同步机制):

一旦mysql中产生了新的写入、更新和删除等操作,就可以把binlog相关的消息推送到redis,redis再根据binlog中的记录,对缓存数据进行更新,参考:mysql的主从数据库备份机制。

(Mysql的数据操作都记录到binlog,通过消息队列及时更新到Redis上)



五:总结:

解决高并发场景下数据一致性的方案,结合之前看错的书籍和文档,我暂时整理的方案是这两种,分别是延时双删策略和异步更新缓存两种方案,有错误请大家指出来,共同进步。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容