缓存与数据库的一致性

参考文章 http://www.javashuo.com/article/p-qadiunjd-dt.html数据库

缓存与数据库的一致性

缓存适用于读多写少的场景,而且能极大地提高性能和效率;可是让缓存的数据与数据库保持一致是一个难题缓存

保持一致的策略

  1. 当数据更新时,先更新缓存,若是缓存更新成功,再更新数据库
    • 适用场景有限,且实现起来较为复杂(若是数据库操做失败,要进行补偿措施,对缓存数据进行还原)
  2. 当数据更新时,先删除缓存,若是缓存删除成功,再更新数据库
    • 适用全部的场景,且实现起来简单,是最经常使用的

存在的问题

不考虑策略1,如下将深刻探究策略2并发

在高并发的状况下,假设请求1(更新操做)先删除缓存,再更新数据库,若是请求2(读操做)在缓存删除与数据库更新之间进行了读取数据,就会读入旧数据到缓存,待数据库更新后,此时旧数据缓存与数据库发生不一致的现象负载均衡

该问题的核心是,请求1的操做不能被其余请求打断,而且请求1与其余请求之间要保持有序(串行执行)。遇到这种状况,能够采用队列的方式去解决(为了保证串行执行,工做线程只能有1个),当出现更新请求时,直接将其丢进队列,等待异步执行;当出现读请求时,先读缓存,成功则返回,若是缓存不存在,再去判断队列头部是不是同一条记录的更新请求,若是是,为了避免打断其操做,将读请求也丢进队列,而后同步等待缓存更新完成;若是不是,说明该更新请求早已完成,直接读数据库并缓存便可,不要入队列。异步

优化

  1. 队列能够建立多个,运用Hash法将不一样记录的请求散列到不一样的队列,能够负载均衡,并行执行,也能够避免堵塞
  2. 在分布式场景下,队列最好共享
  3. 进入队列的读请求能够采用超时等待,一旦超时,直接读数据库并返回,避免长时间的不响应

最后强调:只有读多写少的场景才用缓存!!!读多写少、读多写少,其余状况不要用

相关文章
相关标签/搜索