缓存与数据一致性方案设计

南风 2021年04月27日 67次浏览

一、什么保证访问缓存与数据库数据是一致,又可以避免大量的访问穿透?

1、(Cache-Aisde-Patterm)旁路缓存方案

  • 读流程
    • (1)、先读cache,命中直接return
    • (2)、cache未命中再读DB,DB命中写回缓存在返回
  • 写流程
    • (1)、淘汰cahce原始key
    • (2)、新数据更新写入DB

思考:为什么会淘汰cache,而不是直接更新cache?
原因是:当两个并发写的请求过来时,由于无法保证set cache的时序性,会导致DB和cache的数据不一致,导致查询脏读的产生。

旁路缓存方案弊端?

还是并发读写的问题,假设有一个并发写 A 先进来,刚删除完cache,另一个并发写 B 请求进来,发现cache已经没有这个缓存,直接写入DB,但是关键就这个时候一个并发读 C 进来, C 的action发生在 A delete完cache和B写入DB之间,这个时候C拿到的就是A写入的数据,而不是最新的B更新写入的数据,这个时候就会出现数据不一致,那么需要什么解决这种问题呢?
其实很好的思路就是延迟删除cache,前提是对于数据的更新读实时性要求不高的时候,在每次写请求进来之后,都会记录一个队列,在一段时间之后才会去删除cache。这样保证了并发写数据一致性。
如果对实时性要求比较高的时候,也是可以通过触发时间提前去预计触发时刻 - 延迟时间达到实时性的目标。

2、订阅binlog同步更新redis方案

这种方案适合于写频繁的场景,实时性也高、保证数据有序性。但是要单独实现一个程序去解析binlog日志,也会增加mysql的压力,成本较大。

3、利用高可靠消息中间件作为媒介,redis消费DB变更消息同步

此方案需要使用有序消息进行投递消息,这样才可以保证消息的有序性,保证数据的一致性;但是引入消息中间件增大维护成本。

简而言之,针对于大部分场景,第一种思路已经可以解决问题。