一般情况下,Redis是用来实现应用和数据库之间读操作得缓存层,主要目的是减少数据库IO,还可以提升数据的IO性能。
当应用程序需要去读取某个数据时,会首先尝试去Redis里面加载,如果命中就直接返回,如果没有命中,就去从数据库中查询,查询到数据之后再把这个数据缓存到Redis里。
如果一份数据,同时保存在数据库和Redis里面,当数据发生变化时,需要同时去更新Redis和Mysql,由于更新是有先后顺序的,并且他不像Mysql中多表事务操作,可以满足ACID特性,和会出现数据一致性的问题
这种情况下,只有两种方法:
1.先更新数据库,在更新缓存
2.先删除缓存,在更新数据库
如果先更新数据库,在更新缓存,如果缓存更新失败,会导致数据不一致
如果是先删除缓存,在更新数据库,理想是应用下次访问Redis时,发现Redis里面是空的,就从数据库中加载保存到Redis,那么数据是一致的。但是会有极端情况,由于删除Redis和更新数据库这两个操作不是原子的,所以这个过程如果有其他线程来访问,还是会存在数据不一致的情况。
所以在极端情况下,如果依旧想保持数据一致性,就需要采用最终一致性方案。
比如,基于RocketMQ的可靠性消息通信,来实现最终一致性。
还可以直接通过Canal组件,监控Mysql中binlog日志,把更新后的数据同步到Redis里面。
因为这里是基于最终一致性来实现的,如果业务场景不能接受数据的短期不一致性,那就不能使用这个 方案来做。
以上就是我对这个问题的理解。谢谢大家