一、背景:在高并发的场景下,大量的请求直接访问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上)五:总结:解决高并发场景下数据一致性的方案,结合之前看错的书籍和文档,我暂时整理的方案是这两种,分别是延时双删策略和异步更新缓存两种方案,有错误请大家指出来,共同进步。