这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
接着写:
Read-Through/Write-Through(读写穿透)
抽象缓存层完成和数据库的交互
读方案
- 从缓存读取数据,读到直接返回
- 如果读取不到的话,从数据库加载,写入缓存后,再返回响应。
写方案
- 先查缓存,缓存中不存在,直接更新数据库。
- 缓存中存在,则先更新缓存,然后缓存服务自己更新数据库(同时更新数据库和缓存)。
和旁路缓存的区别: 由一个 Cache-Provider 操作缓存,应用读写都从 Cache-Provider 走
Write behind (异步缓存写入)
Cache-Provider 只更新缓存,不直接更新数据库,通过批量异步的方式来更新数据库。
只涉及写入部分
- 数据持久化操作是异步的。
写入的写性能非常高 开发过程中也非常少见,但是不代表它的应用场景少 一致性可能存在问题:比如
cache数据可能还没异步更新DB,cache服务可能就挂了。
从缓存本身下手
延时双删策略
- 先删除缓存
- 再更新数据库
- 休眠一会(比如1秒),再次删除缓存。1
休眠保证数据库更新完毕 双删保证获取新数据
删除缓存重试机制
解决延迟双删不成功的问题
- 写请求更新数据库
- 缓存因为某些原因,删除失败
- 把删除失败的key放到消息队列
- 消费消息队列的消息,获取要删除的key
- 重试删除缓存操作
存在业务代码入侵问题
读取 biglog 异步删除缓存
通过阿里巴巴开源的 Canal 中间件
- canal 将 binlog 日志采集发送到 MQ 队列里面
- 然后编写一个简单的缓存删除消息者订阅 binlog 日志
- 根据更新 log 删除缓存
- 并且通过 ACK 机制确认处理这条更新 log,保证数据缓存一致性