在读取数据下的数据一致性
1.线程去缓存查询数据
2.如果缓存获取数据失效,则查询数据库
3.从数据库获取数据后,更新缓存
4.最后是响应数据
在写数据下的数据一致性
先删除缓存,再更新数据库的做法(延迟双删)
先更新数据库,在删除缓存做法
先删除缓存,再更新数据库的做法下,导致写数据下数据不一致性的原因,在多并发下,线程一在更新数据库时,由于网络等原因未完成更新数据,此时线程二查询操作缓存未命中,则从数据库查询旧的数据(线程一还未更新数据库),然后更新缓存,等线程一能够正常执行时,更新数据库,而缓存因为线程二的原因,缓存的是旧数据,数据库则是新数据,这就导致了数据不一致性。
解决方法就是当网络延迟后,更新数据库之后在休眠多少毫秒(最多在这个时间内,线程读到的是脏数据),然后删除缓存,这时,当其他线程进行查询操作时就会未命中缓存,去查数据库,然后更新缓存,这就达到了线程一致性。实际在这个流程中,允许了数据在一段时间内不一致,这就是最终一致性。如果需要强一致性,则不使用缓存或者加锁处理。
则先操作数据库,再删除缓存,造成数据不一致的原因则是删除缓存失败,解决方案就是引入重试机制,在高并发情况下,最好使用的是异步方式,比如发送消息到MQ中间件,实现异步解耦。
总结
先更新数据库,再更新缓存
这种方法的优点是可以保证缓存中的数据始终与数据库中的数据一致。但是,如果在更新缓存的过程中出现问题,可能会导致数据库中的数据已经被更新,但是缓存中的数据没有被更新,从而出现不一致的情况。此外,这种方法在高并发的情况下可能会导致缓存被频繁更新,影响系统性能。
先删除缓存,再更新数据库
这种方法的优点是可以避免在更新缓存的过程中出现问题导致的不一致情况。但是,如果在删除缓存后,有多个线程同时读取数据,可能会导致这些线程从数据库中读取到旧的数据并将其放入缓存中,从而出现不一致的情况。为了解决这个问题,可以在更新数据库后,再延迟一段时间删除缓存,以确保所有的读请求都已经从数据库中读取到了新的数据。