基本流程
在我们访问redis时,redis中的数据,即此时数据库的更新操作已经完成,但是还没有同步到redis中。
延时双删
解决方案,延时双删
延时双删方案执行步骤
1.删除redis
2.更新数据库
3.延时500毫秒
4.删除redis
问题一:为何要延时500毫秒?
这是为了我们在第二次删除redis之前能完成数据库的更新操作。
假象一下,如果没有第三步操作时,有很大概率,在两次删除redis操作执行完毕之后,数据库的数据还没有更新,此时若有请求访问数据,便会出现我们一开始提到的那个问题。
问题二: 为何要两次删除redis?
如果我们没有第二次删除操作,此时有请求访问数据,有可能是访问的之前未做修改的redis数据,删除操作执行后,redis为空,有请求进来时,便会去访问数据库,此时数据库中的数据已是更新后的数据,保证了数据的一致性。
异步更新缓存(基于订阅binlog的同步机制)
MySQL binlog增量订阅消费+消息队列+增量数据更新到redis读Redis
热数据基本都在Redis写MySQL:增删改都是操作MySQL更新Redis数据:MySQ的数据操作binlog,来更新到Redis:
1)数据操作主要分为两大块:一个是全量(将全部数据一次写入到redis)一个是增量(实时更新)。
这里说的是增量,指的是mysql的update、insert、delate变更数据。
2)读取binlog后分析 ,利用消息队列,推送更新各台的redis缓存数据。
这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis,Redis再根据binlog中的记录,对Redis进行更新。
其实这种机制,很类似MySQL的主从备份机制,因为MySQL的主备也是通过binlog来实现的数据一致性。
这里可以结合使用canal(阿里的一款开源框架),通过该框架可以对MySQL的binlog进行订阅,而canal正是模仿了mysql的slave数据库的备份请求,使得Redis的数据更新达到了相同的效果。
当然,这里的消息推送工具你也可以采用别的第三方:kafka、rabbitMQ等来实现推送更新Redis。