Redis的作用
一般情况下Redis是用来实现应用和数据库之间的一个读操作的缓存层,主要目的是减少数据库的io,还可以提升数据库io性能
整体架构
- 命中缓存从缓存加载数据,直接返回
- 没有命中缓存,从数据库加载加载数据
- 加载到的数据写入缓存
原理
一份数据同时保存在数据库和Redis里面,当数据发生变化的时候,需要同时更新Redis和Mysql,由于更新操作是有先后顺序的,并且它并不像Mysql中的多表事务操作可以满足ACID的特性,所以就会出现数据一致性的问题,
如何保证数据一致性
- 先更新数据库,再更新缓存
- 先删除缓存,再更新数据库
第一种情况的缺点
如果先更新数据库,再更新缓存,如果缓存更新失败,就会导致数据库和Redis的数据是不一致的,
第二种情况的缺点
如果先删除缓存,再更新数据库,理想情况下,是应用下次访问Redis的时候,发现Redis的数据是空的那么就会从数据库加载保存到Redis里面理论上数据是一致的,但是在极端情况下,由于删除Redis和更新数据库这两个操作并不是原子操作,如果出现其它线程来访问,还是会存在数据不一致的问题
如何保证数据一致性
如果需要在极端情况下仍然去保证Redis和Mysql的数据一致性就只能采用最终一致性的一个方案
基于RocketMq的可靠性通信
- 更新数据库的数据
- 更新redis的数据
- 失败的请求写入mq事务消息
- 异步重试,确保成功
基于canal组件
- 更新数据库的数据
- 更新redis的数据
- 从binlog加载数据
- 同步到Redis里面
如果业务不能接受短期的不一致性,那么就不能这样的一个方案来实现