当前位置: 首页 > news >正文

Redis与数据库的一致性

Redis与数据库的数据一致性

在使用Redis作为应用缓存来提高数据的读性能时,经常会遇到Redis与数据库的数据一致性问题。简单来说,就是同一份数据同时存在于Redis和数据库,如何在数据更新的时候,保证两边数据的一致性。首先,如果期望Redis与数据库保持强一致性,则必须额外引入分布式事务组件,通过一致性协议(如2PC、3PC等)来保证缓存和数据库的一致性。这里讨论的一致性是最终一致性,即Redis中的数据将最终和数据库中的数据保持一致。

Redis缓存模式

Redis缓存模式并没有统一的范式,这里主要是借鉴本地缓存的设计模式,尝试总结出Redis的缓存模式。本地缓存在进行设计时,主要有以下几种常见的模式:cache aside,read through,write through,write around,write back。
在cache aside模式中,对于读请求,客户端应用会优先访问缓存,如果缓存命中,则直接返回数据;如果缓存未命中,则会进一步请求数据库,然后将数据写入缓存。在read through中,缓存负责保持与数据库的一致。当数据未命中时,缓存会主动从数据库中读取该未命中数据,并回写缓存,然后将这部分数据返回给客户端应用。在write through模式中,数据首先写入缓存,然后写入数据库。与read through一样,写入总是通过缓存到达数据库。在write around模式中,数据直接由客户端应用写入数据库,然后让Cache中对应数据无效。在write back模式中,客户端应用将数据写入缓存后,缓存会立即确认,并在延迟一段时间后将数据写回数据库。更多缓存设计模式相关细节可以参考笔者软件系统缓存设计一文。
以上五种缓存设计模式,cache aside模式与read through模式主要针对读请求的场景,且在第一次请求数据时,总是会导致缓存未命中,并额外带来将数据加载到缓存的操作。相比cache aside模式是客户端应用从数据库读取缓存未命中数据并将其写入缓存,read through模式是由缓存从数据库读取未命中数据并将其写入到缓存。对于Redis缓存来说,由于Redis缓存和数据库是两个独立的组件,所以Redis缓存不可能使用read through模式,而只能使用cache aside模式。
而write through模式、write around模式与write back模式主要针对写请求的场景,三种模式均需要将数据写入数据库,只是写入的主体或写入的时机不同。对于Redis缓存来说,同样由于Redis缓存和数据库是两个独立的组件,所以Redis缓存不可能使用write through模式或write back模式,而只能使用write around模式,即数据直接由客户端应用写入数据库。至此,Redis缓存的常用设计模式如下:

请添加图片描述

从上图可知,当客户端应用发起读请求时,客户端应用首先尝试从Redis中读取数据,如果缓存中命中数据,则直接从缓存读取数据。如果缓存未命中,则先从数据库读取数据,并将数据写入缓存。当客户端应用发起写请求时,客户端应用直接将新数据写入数据库。同时为保证Redis与Database的最终一致性,在客户端应用将数据写入缓存时,设置一个TTL,避免脏数据一直保存在Redis中。上述过程的伪代码表示如下:

Object readData(String keyStr) {Object data = readRedis(keyStr);if (data != null) {return data;}data = readDatabase(keyStr);writeRedis(keyStr, data, ttl);return data;
}boolean writeData(String keyStr, Object data) {return writeDatabase(keyStr, data);
}

针对写请求场景(新数据写入、已有数据的更新、已有数据的删除),特别是已有数据的更新和已有数据的删除这种情况,因为对于上述模式来说,只是将数据写入数据库,会带来Redis和数据的不一致。因为向Redis写入数据时,设置了TTL,所以一段时间后,Redis中的数据将最终与数据库一致。

总结

如果期望实现Redis缓存中数据与数据库中数据的强一致性,那么需要额外引入分布式事务组件,通过一致性协议(2PC、3PC)来实现实现Redis缓存中数据与数据库中数据的强一致性。但是,分布式事务组件的引入无疑会降低Redis缓存加速查询的初衷。所以很少看到需要Redis缓存中数据与数据库中数据保持强一致性的情况。
既然不强制要求Redis缓存中数据与数据库中数据的强一致性,那么是否可以加快Redis中数据与数据库中数据一致性的收敛速度呢?网络上针对如何加快Redis中数据与数据库中数据一致性的收敛速度,提出了多种解决方案,如:先更新数据库,再更新Redis;先更新数据库,再删除Redis中数据(直接删除Redis、延迟删除Redis);先删除Redis中数据,再更新数据库;先尝试删除Redis中数据,再更新数据库,再尝试删除Redis中数据(双删策略);先写数据库,然后通过binlog或队列,异步更新Redis中数据。笔者认为,以上方案虽然自成一体,但是不免纸上谈兵、画蛇添足,存在过度设计的问题。以上方案的一个公共特征是为了加快Redis中数据与数据库中数据一致性的收敛速度,需要执行多余的Redis写入步骤或引入额外的功能或组件(如数据库的binlog日志、队列等)。且在提升设计复杂度的同时,并没有真正起到加速一致性收敛的效果或收效甚微。且额外的Redis写入操作会加大Redis主从结点间同步负担,带来更多问题。
笔者认为,使用Redis作为缓存,就是已经接受了Redis缓存中数据可能存在脏数据的情况,且用户对数据不一致性的时间可容忍。与其考虑如何加快一致性收敛的速度,倒不如从业务出发,考虑Redis缓存的使用姿势是否合理,如将一些频繁更新且用户敏感的数据保存到Redis缓存就是一种不合理的使用;将数据长期的存储在Redis缓存中,且设置过长的TTL就是将Redis当做数据库使用,而不是缓存。此外,还应考虑将缓存前置,尝试使用客户端应用的本地缓存来提升性能。

参考

https://mp.weixin.qq.com/s/az1D1lKcoU9hiOIJjmjlJQ 4 种策略让 MySQL 和 Redis 数据保持一致
https://mp.weixin.qq.com/s/RL4Bt_UkNcnsBGL_9w37Zg 如何保障 MySQL 和 Redis 的数据一致性?

相关文章:

Redis与数据库的一致性

Redis与数据库的数据一致性 在使用Redis作为应用缓存来提高数据的读性能时,经常会遇到Redis与数据库的数据一致性问题。简单来说,就是同一份数据同时存在于Redis和数据库,如何在数据更新的时候,保证两边数据的一致性。首先&#…...

使用maxwell实时同步mysql数据到kafka

一、软件环境: 操作系统:CentOS release 6.5 (Final) java版本: jdk1.8 zookeeper版本: zookeeper-3.4.11 kafka 版本: kafka_2.11-1.1.0.tgz maxwell版本:maxwell-1.16.0.tar.gz 注意 : 关闭所有机器的防火墙,同时注意…...

知识图谱与大数据:区别、联系与应用

目录 前言1 知识图谱1.1 定义1.2 特点1.3 应用 2 大数据2.1 定义2.2 应用 3. 区别与联系3.1 区别3.2 联系 结语 前言 在当今信息爆炸的时代,数据成为了我们生活和工作中不可或缺的资源。知识图谱和大数据是两个关键概念,它们在人工智能、数据科学和信息…...

Nagios工具

一 nagios 相关概念 Nagios 是一款开源的免费网络监视工具,能有效监控 Windows、Linux 和 Unix 的主机状态,交换机路由器等网络设置,打印机等。在系统或服务状态异常时发出邮件或短信报警第 一时间通知网站运维人员,在状态恢复后…...

微信小程序全局数据共享

文章目录 安装MobX相关的包根目录创建store文件夹,添加store.js文件绑定到页面中绑定到组件 mobx-miniprogram和mobx-miniprogram-bindings实现全局数据共享 mobx-miniprogram用来创建Store实例对象 mobx-miniprogram-bindings用来把Store中的共享数据或方法&…...

算法训练营第24天|回溯算法理论基础 LeetCode 77.组合

终于把二叉树做完了!开始新的篇章,回溯! 回溯算法理论基础 回溯算法题目分类: 1.组合 2.分割 3.子集 4.排列 5.棋盘问题 什么是回溯? 回溯叫做回溯搜索法,是一种搜索方式。回溯是递归的副产品&…...

pip永久修改镜像地址

修改命令: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple/ 效果: 会在C:\Users\PC(用户名)\AppData\Roaming\pip目录下新增或修改文件pip.ini 文件内容: [global] index-url https://pypi.tuna.tsinghua.e…...

RK3588平台开发系列讲解(硬件篇-功能外设2)

USB2.0/USB3.0 电路 RK3588 芯片内置两个USB3.0 OTG控制器(内嵌2个USB2.0 OTG,下图绿色处),1个USB3.0 HOST 控制器,2个USB2.0 HOST控制器。 这些控制器与PHY的内部复用图如下: USB3.0 OTG0 控制器支持SS/H…...

SpringBoot学习记录

SpringBoot是用于加速Spring开发的。 我们先来看看如何使用SpringBoot来创建一个基于Web的程序,可以发现相较于SpringMVC其有巨大改变。 3.开发控制器类 GetMapping("/{id}")public String getById(PathVariable Integer id){System.out.println("…...

财富池指标--通达信顾比均线实战指标免费源码

顾比均线是由两组均线构成,短期组为3、5、8、10、12、15。长期组为:30、35、40、45、50、60。顾比均线由澳大利亚的投资家戴若-顾比先生发明,因此叫顾比线。 顾比均线可以广泛运用于股票、期货和外汇交易中,只要是能运用K线图的投…...

AJAX(一):初识AJAX、http协议、配置环境、发送AJAX请求、请求时的问题

一、什么是AJAX 1.AJAX 就是异步的JS和XML。通过AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。 2.XML 可扩展标记语言。XML被设计用来传输和…...

idea常用的快捷键总结:

idea常用的快捷键总结: Ctrl相关的: Ctrl F 在当前文件进行文本查找 (必备) Ctrl R 在当前文件进行文本替换 (必备) Ctrl Z 撤销 (必备) Ctrl Y 删除光标所在行 或 删除选中的…...

LeetCode 热题 100 题解(一):哈希部分

《LeetCode热题 100》 经过了两个多月,终于刷完了代码随想录的题目,现在准备开始挑战热题一百了,接下来我会将自己的题解以博客的形式同步发到力扣和 c 站,希望在接下来的征程中与大家共勉! 题组一:哈希 题…...

C语言 | qsort()函数使用

目录: 1.qsort介绍 2.使⽤qsort函数 排序 整型数据 3.使⽤qsort函数 排序 结构体数据 4. qsort函数的模拟实现冒泡排序 qsort()函数 是一个 C语言编译器函数库自带的排序函数, 它可以对指定数组(包括字符串,二维数组&#x…...

继承的特点 | java

/*Java中继承的特点:A:Java只支持单继承,不支持多继承。 B:Java支持多层继承(继承体系),间接继承 */class Father(){} class Mother(){}class son extends Father(){} // 正确 class son2 extends Father , Mother {} // 不正确 1. Java只支持单继承…...

6、jenkins项目构建类型-项目类型介绍

文章目录 一、自由风格项目1、拉取代码2、演示改动代码后的持续集成二、Maven项目构建三、Pipeline流水线项目构建(☆☆☆)1、Pipeline简介(1)概念(2)使用Pipeline有以下好处(3)如何创建Jenkins Pipeline呢?2、安装Pipeline插件3、Pipeline语法快速入门(1)Declarati…...

指针函数的应用——找出哪些学生有不及格的科目

下面的代码实现了以下功能: 定义了一个函数 getFailStudent,它接收一个指向整数数组的指针,并遍历该数组,查找是否存在不及格的成绩。如果找到了不及格的成绩,就返回指向不及格学生所在行的指针;否则返回 N…...

【微服务】Gateway

文章目录 1.基本介绍官方文档:https://springdoc.cn/spring-cloud-gateway/#gateway-starter1.引出网关2.使用网关服务架构图3.Gateway网络拓扑图(背下来)4.Gateway特性5.Gateway核心组件1.基本介绍2.断言3.过滤 6.Gateway工作机制 2.搭建Gat…...

王道C语言督学营OJ课后习题(课时14)

#include <stdio.h> #include <stdlib.h>typedef char BiElemType; typedef struct BiTNode{BiElemType c;//c 就是书籍上的 datastruct BiTNode *lchild;struct BiTNode *rchild; }BiTNode,*BiTree;//tag 结构体是辅助队列使用的 typedef struct tag{BiTree p;//树…...

Filter、Listener、AJAX

Filter 概念&#xff1a;Filter 表示过滤器&#xff0c;是JavaWeb三大组件(Servlet、Filter、 Listener)之一。 过滤器可以把对资源的请求拦截下来&#xff0c;从而实现一些特殊的功能。 过滤器一般完成一些通用的操作&#xff0c;比如&#xff1a;权限控制、统一编码处理、敏感…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...