如果数据同时存在redis和数据库,此时要更新数据。不管删除缓存和更新数据库的先后顺序如何,都可能出现数据不一致的情况。
如何解决数据不一致问题?(不能百分百保证一致性)
采用重试机制
可以把要删除的缓存值或者是要更新的数据库值暂存到消息队列中(例如使用 Kafka 消息队列)。当应用没有能够成功地删除缓存值或者是更新数据库值时,可以从消息队列中重新读取这些值,然后再次进行删除或更新。
如果能够成功地删除或更新,我们就要把这些值从消息队列中去除,以免重复操作,此时,我们也可以保证数据库和缓存的数据一致了。否则的话,我们还需要再次进行重试。如果重试超过的一定次数,还是没有成功,我们就需要向业务层发送报错信息了。
为什么要借助MQ?
现实情况往往没有想的这么简单,失败后立即重试的问题在于:立即重试很大概率「还会失败」
重试次数设置多少才合理?:重试会一直「占用」这个线程资源,无法服务其它客户端请求
如果你确实不想在应用中去写消息队列,是否有更简单的方案,同时又可以保证一致性呢?
方案还是有的,这就是近几年比较流行的解决方案:订阅数据库变更日志,再操作缓存。
想要保证数据库和缓存一致性,推荐采用「先更新数据库,再删除缓存」方案,并配合「消息队列」或「订阅变更日志」的方式来做。
缓存延迟双删策略
1,在线程 A 删除缓存、更新完数据库之后,先「休眠一会」,再「删除」一次缓存。
2,线程 A 可以生成一条「延时消息」,写到消息队列中,消费者延时「删除」缓存。
这个时间在分布式和高并发场景下,其实是很难评估的。不建议
其实不用追求强一致性,我们引入缓存的目的是什么?没错,性能。一旦我们决定使用缓存,那必然要面临一致性问题。性能和一致性就像天平的两端,无法做到都满足要求。
文章摘抄:缓存和数据库一致性问题,看这篇就够了