Redis缓存与数据库数据一致性
不管是先写数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况:
- 1.如果删除了缓存,还没有来得及写数据库,另一个线程就来读取,发现缓存为空,则去数据库中读取数据写入缓存,此时缓存中为脏数据。
- 2.如果先写了库,在删除缓存前,写库的线程宕机了,没有删除掉缓存,则也会出现数据不一致情况。
1. 第一种方案:延时双删策略+缓存超时设置
- 在写库前后都进行删除缓存操作(redis.del(key)),并且设定合理的缓存过期时间。具体的步骤就是:
- 先删除缓存;
- 再写数据库;
- 休眠一段时间;
- 再次删除缓存。
- 设置缓存过期时间
所有的写操作以数据库为准,只要到达缓存过期时间,则后面的读请求自然会从数据库中读取新值,然后再回填缓存。
2. 第二种方案:异步更新缓存(基于订阅binlog的同步机制)
订阅MySQL binlog增量消费+消息队列+增量数据更新到redis。一旦MySQL产生了更新操作(写入、更新、删除),就把binlog记录相关的消息通过消息队列推送至Redis,Redis则根据binlog中的记录,来对Redis缓存进行更新。