redis缓存和数据库都保存了数据信息,当我们更新了数据库的数据时,应该如何保证redis和数据库的数据同步呢?当前比较常用的是双写模式和失效模式。
1.双写模式
双写模式:每次修改数据库的数据后,然后在更新redis中的数据,使用了两次写操作,称为双写模式
双写模式存在的问题:高并发下有可能会有脏数据
原理如下图:
2.失效模式
失效模式:每次修改数据库的数据后,删除redis中缓存的数据,当有redis查询请求时,会先去数据库查询,然后更新到redis中,后续继续请求redis。更新时删除缓存数据,称为失效模式
失效模式存在的问题:同样会存在脏数据问题
原因如图:
3.缓存一致性问题解决方案
如上所示,无论是双写模式还是失效模式,都无法完美解决缓存一致性问题!
但是,为什么这两种还是常用呢?因为不同的业务场景对数据一致性的要求也不同,我们要根据实际业务场景来分析,具体解决方案如下所示:
注意:
1.加读写锁可能会导致系统变得沉重,系统变慢
2.设置缓存的过期时间、每隔一段时间自动刷新,可保持最终一致性
3.1使用Canal解决缓存一致性问题
Canal使我们的业务代码只关注于数据库的交互,不用管redis缓存的问题,因为Canal可以订阅mysql数据库的每一次更新,只要mysql数据库有更新,Canal就会把数据同步到redis
使用Canal注意点:
①:mysql要开启binlog日志,才能被Canal所监控
②:使用Canal在业务代码中执行修改缓存就可以
③:使用Canal需要额外增加Canal中间件,加重系统复杂度。
所以,根据具体的业务场景来解决数据一致性
Canal操作流程图