Redis的一致性

一、产生的原因

使用缓存,在进行写操作的时候就会出现不一致的问题。

一致性分为三类:强一致性,弱一致性,最终一致性

二、方案

2.1 延时双删

在更新数据库的操作前后分别进行一次删除缓存的操作,并在更新数据库之后线程休眠一段时间。

  1. 先删除缓存
  2. 再更新数据库
  3. 休眠一会(比如1秒),再次删除缓存。

这个休眠一会,一般多久呢?都是1秒?

休眠时间 = 读业务逻辑数据的耗时 + 几百毫秒。为了确保读请求结束,写请求可以删除读请求可能带来的缓存脏数据。

该方法优缺点思考:

这种方案还算可以,只有休眠那一会(比如就那1秒),可能有脏数据,一般业务也会接受的。但是如果第二次删除缓存失败呢?

缓存和数据库的数据还是可能不一致,对吧?

给Key设置一个自然的expire过期时间,让它自动过期怎样?

那业务要接受过期时间内,数据的不一致咯?还是有其他更佳方案呢?

2.2 删除缓存重试机制

当第二次删除缓存失败怎么办?那就再删一次呗,还不行就再删一次!

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

2.3 读取biglog异步删除缓存

删除缓存重试机制虽然能够解决一致性的问题,但是对代码的侵入性较大,可以进行如下优化:通过数据库的binlog来异步淘汰key。

以mysql为例,

可以使用阿里的canal将binlog日志采集发送到MQ队列里面

然后通过ACK机制确认处理这条更新消息,删除缓存,保证数据缓存一致性

三、可能出现的疑问

3.1 为什么先操作数据库,再操作缓存?

假设先操作缓存再操作数据库,可能会出现如下情况:

线程A先删除缓存,在A更新数据库的操作结束前,线程B去读数据,发现缓存没数据了,那么B就会去数据库中查询,结果读到的就是脏数据并存在缓存中,然后A更新完数据库,导致数据库和缓存中的值不一致。

如果先操作数据库再操作缓存,能保证一致性。

相关推荐
静听山水6 小时前
Redis核心数据结构
数据结构·数据库·redis
yuanmenghao6 小时前
Linux 性能实战 | 第 10 篇 CPU 缓存与内存访问延迟
linux·服务器·缓存·性能优化·自动驾驶·unix
流㶡6 小时前
MySQL 常用操作指南(Shell 环境)
数据库
静听山水6 小时前
Redis核心数据结构-Hash
数据结构·redis·哈希算法
数据知道6 小时前
PostgreSQL 性能优化:连接数过多的原因分析与连接池方案
数据库·postgresql·性能优化
怣506 小时前
MySQL子查询实战指南:数据操作(增删改查)与通用表达式
数据库·chrome·mysql
消失的旧时光-19436 小时前
第十六课实战:分布式锁与限流设计 —— 从原理到可跑 Demo
redis·分布式·缓存
范纹杉想快点毕业6 小时前
从单片机基础到程序框架:构建嵌入式系统的完整路径
数据库·mongodb
数据知道6 小时前
PostgreSQL性能优化:如何定期清理无用索引以释放磁盘空间(索引膨胀监控)
数据库·postgresql·性能优化
喵叔哟6 小时前
67.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--分摊功能总体设计与业务流程
数据库·微服务·架构