一般来说Redis是用来实现应用和数据库之间的一个读操作的缓存层,它的主要目的是为了减少数据库的IO,还可以提升数据的IO性能。
当一份数据同时保存在Redis和MySQL中时,当数据发生变化的时候,需要同时去更新Redis和MySQL,由于更新操作是有先后顺序的,并且他并不像MySQL中的多表事务操作,可以满足ACID的特性,因此就会出现数据不一致的问题。
先更新数据库再更新缓存
先更新数据库再更新缓存,那么如果缓存更新失败这就会导致数据库和缓存的数据是不一致的
先删除缓存再更新数据库
先删除缓存再更新数据库,理想情况下是下次应用访问Redis时发现是空,那么就会从DB层面去加载,接着保存到Redis中去,也就是说理论上数据是保持一致的。但是在极端情况下,由于删除Redis和更新数据库这两个操作并不是原子操作,所以在这个过程中如果出现其他线程来访问,仍然会出现数据不一致 的问题。
在业务允许的情况下要求DB和缓存的一致性
我们经常采用的是最终一致性的一个方案。比如基于RocketMQ的一个可靠性方案来实现数据的最终一致性,还可以通过Canal组件监控MySQL中的binlog日志,把更新后的日志同步到Redis中去,因为这里是根据最终一致性去实现的,如果业务场景不能去接受数据的短期不一致,那么就不能使用这种方案。
技术是为了业务服务的,所有方案的选择和设计都是不同的,如果仍然要问数据还会不一致会怎么样,我们可以去好好分析业务的场景到底是什么样子的,一个技术方案不可能cover住所有的业务场景。