数据库与缓存双写一致性如何保证

一致性

  • 强一致性:完全一致性,写进去是什么,读出来就是什么。用户体验好,实现起来对系统的性能影响大。
  • 弱一致性 :写入成功后,不会立马达到一致,也无法保证多久之后能一致,尽快的保证在一个时间后达到一致。
  • 最终一致性:最终一致性是弱一致性的一个特例,区别在于他保证在一定时间内达到一致。比较常用。

缓存模式

  • Cache-Aside Pattern,即旁路缓存模式,它的提出是为了尽可能地解决缓存与数据库的数据不一致问题。
    读请求过程

    image.png

    写请求过程:
    image.png

  • Read-Through/Write-Through(读写穿透)
    Read/Write-Through模式中,服务端把缓存作为主要数据存储。应用程序跟数据库缓存交互,都是通过抽象缓存层完成的。

  • 读请求

    image.png

Read-Through实际只是在Cache-Aside之上进行了一层封装,它会让程序代码变得更简洁,同时也减少数据源上的负载。

  • 写请求:Write-Through模式下,当发生写请求时,也是由缓存抽象层完成数据源和缓存数据的更新,流程如下:

    image.png

  • Write-behind (异步缓存写入):

Write-behind 跟Read-Through/Write-Through有相似的地方,都是由Cache Provider来负责缓存和数据库的读写。它们又有个很大的不同:Read/Write-Through是同步更新缓存和数据的,Write-Behind则是只更新缓存,不直接更新数据库,通过批量异步的方式来更新数据库。


image.png

这种方式下,缓存和数据库的一致性不强,对一致性要求高的系统要谨慎使用。但是它适合频繁写的场景,MySQL的InnoDB Buffer Pool机制就使用到这种模式。

优化方案

备注: 首先数据库与缓存数据是无法做到强一致性的。

其实,这是由CAP理论决定的。缓存系统适用的场景就是非强一致性的场景,它属于CAP中的AP。个人觉得,追求绝对一致性的业务场景,不适合引入缓存。

  • 延时双删


    image.png

1 先删除缓存
2 再更新数据库
3 休眠一会(读业务逻辑数据的耗时 + 几百毫秒。为了确保读请求结束,写请求可以删除读请求可能带来的缓存脏数据),再次删除缓存。

  • 删除缓存重试机制


    image.png

1 写请求更新数据库
2 缓存因为某些原因,删除失败
3 把删除失败的key放到消息队列
4 消费消息队列的消息,获取要删除的key
5 重试删除缓存操作

你可能感兴趣的:(数据库与缓存双写一致性如何保证)