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 的数据一致性?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2906752.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu20安装python3.10

1、添加 deadsnakes PPA 到源列表 add-apt-repository ppa:deadsnakes/ppa apt update 2、安装 apt install python3.10 3设置默认版本为 Python3.10 查看所有python版本 ls -l /usr/bin/python* update-alternatives --install /usr/bin/python3 python3 /usr/bin/pytho…

基于Axios封装请求---防止接口重复请求解决方案

一、引言 前端接口防止重复请求的实现方案主要基于以下几个原因: 用户体验:重复发送请求可能导致页面长时间无响应或加载缓慢,从而影响用户的体验。特别是在网络不稳定或请求处理时间较长的情况下,这个问题尤为突出。 服务器压力…

MySql实战--MySQL为什么有时候会选错索引

前面我们介绍过索引,你已经知道了在MySQL中一张表其实是可以支持多个索引的。但是,你写SQL语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由MySQL来确定的。 不知道你有没有碰到过这种情况,一条本来…

有手就会Anaconda下载与安装

​1.Anaconda 介绍 Anaconda(官网:https://www.anaconda.com/) 是一个开源 Python 发行版本,Anaconda 包括 Conda、Python 以及一大堆安装好的工具包,比如:numpy、pandas 等,是数据分析&#x…

代码随想录算法训练营第二十四天|77.组合、216.组合Ⅲ

文档链接:https://programmercarl.com/ LeetCode77.组合 题目链接:https://leetcode.cn/problems/combinations/ 思路: 回溯三部曲: 第一步:确定函数返回值和参数类型 第二步:确定终止条件 第三步&a…

保理业务产品方案

常见的信贷业务流程 产品架构 一般分为贷前、贷中、贷后三个部分: 贷前一般处理客户入驻、资质审批、授信项目准入; 贷中一般处理处理具体的融资申请、审批、中登登记、资产锁定、放款事务; 贷后一般处理客户还款冲销、账款跟踪、到期日调整…

windows 远程连接(mstsc)无法复制粘贴文件

目录 问题 1. 打开远程连接(mstsc) 方式一: 方式二: 2. 打开【显示选项】 3. 选择【本地资源】 > 【详细信息】 4. 选择需要操作的本机磁盘 5. 重新打开远程即可 问题 使用win自带的远程桌面连接,无法复制粘贴文件,解…

Go微服务实战——metrics指标监控(Prometheus框架与Grafana可视化)

安装Prometheus 参考官网 安装完后访问http://IP:9090如下所示: 这是Prometheus自带的UI。 该地址是数据监控地址http://localhost:9090/metrics所有输出的监控项。 可以正常浏览上述信息是表示安装完成。 Promethus简介 promethus中文网 Prometheus中文文档 …

整理git上的模板框架

vite-vue3.0-ts-pinia-uni-app 技术栈的app框架 功能:基于 uni-app,一端发布多端通用,目前已经适配 H5、微信小程序、QQ小程序、Ios App、Android App。 taro3vue3tsnutuipinia taro3 框架小程序跨端平台 vue3.0-element-vite-qiankun 后台…

雷军分享造车故事:储备1363亿元的现金,吊打特斯拉Model 3

小米召开新车发布会,正式发布小米 SU7。该车定位中大型纯电轿车,有 SU7、SU7 Pro、SU7 Max 三个版本,车身尺寸 4997/1963/1455mm,轴距 3000mm。售价 21.59-29.99 万。 在小米汽车SU7发布会后,小米集团的创始人、董事长…

马蹄集第九周

MT3011 代码 #include<bits/stdc.h> using namespace std; const int N 1e3 7;int n; struct NODE{vector<int> v;int ind 0; }g[N];int main( ) {cin >> n;int x;for(int i 1; i < n; i){for(int j 1; j< n-1; j){cin >> x;g[i].v.push_…

深入浅出MHA(MySQL Master High Availability)集群:原理、部署与实践

目录 引言 一、MHA集群介绍 &#xff08;一&#xff09;什么是MHA &#xff08;二&#xff09;MHA集群原理 &#xff08;三&#xff09;同步方式 &#xff08;四&#xff09;管理节点与数据节点 二、实现MHA &#xff08;一&#xff09;搭建主从复制环境 1.搭建时间同…

C语言例4-32:利用for语句实现循环次数未知的例子

从键盘输入若干个整数&#xff0c;求其中的最大者和最小者&#xff0c;直到输入“0”为止 算法分析&#xff1a; 读取第一个整数i&#xff0c;并假设它是当前最大整数max&#xff0c;也是当前最小整数min当,则重复执行以下操作&#xff0c;若i<min&#xff0c;则mini;从键…

Linux课程____Linux防火墙

一、包、过滤防火墙 包过滤内核&#xff1a;netfilter 规则管理工具&#xff1a;firewalld ,老版本linux: iptables工具 firewalld网络区域&#xff1a; 常用区域&#xff1a;trusted、home、public、external、block 二、格式 格式&#xff1a;firewall-cmd 【参数】 --per…

【软件安装】(十五)Ubuntu22.04+Anaconda安装labelimg

一个愿意伫立在巨人肩膀上的农民...... LabelImg是一款开源的图片标注工具&#xff0c;使用Python编写&#xff0c;基于PyQt5框架。它提供了一个直观的图形用户界面&#xff0c;方便用户对图片进行标注&#xff0c;并生成标注结果。LabelImg支持多种常见的标注格式&#xff0c;…

线程中的核心操作

线程中的核心操作 1:start()2:中断(终止)一个线程2.1:自己定义线程结束的代码2.1.1 存在的问题 2.2:使用Thread提供的interrupt()方法和isInterrupted()2.2.1 继续执行2.2.2 立即结束2.2.3 打印异常信息,再立即结束2.2.1 继续执行 22三级目录 1:start() start() 真正的创建线程…

数据资产的计量方式和后续计量如何确定?

对与数据资产的计量&#xff0c;可分为初始计量和后续计量两大环节来考虑。 一、在初始计量环节可采用按历史成本法计量和按公允价值计量两种方式 目前数据资产的计量属性主要包含历史成本、公允价值。企业数据资产可考虑从用途角度划分为内部开发型和外购型。 &#xff08;…

Android TargetSdkVersion 30 安装失败 resources.arsc 需要对齐且不压缩。

公司项目&#xff0c;之前targetSDKVersion一直是29&#xff0c;近期小米平台上架强制要求升到30&#xff0c;但是这个版本在android12上安装失败&#xff0c;我用adb命令安装&#xff0c;报错如下图 adb: failed to install c: Program Files (x86)(0A_knight\MorkSpace \Home…

Springboot构建测试类Test出现错误:Test class should have exactly one public constructor

&#xff08;1&#xff09;在SpringBoot中&#xff0c;分为Spring4和Spring5&#xff08;或Spring5以上版本&#xff09;&#xff0c;Spring4的Test测试类需要加上两个注解&#xff1a; SpringBootTest RunWith(SpringRunner.class) 导入的包是: import org.junit.Test; &am…

App地推统计神器,Xinstall让数据说话

App地推&#xff0c;作为移动应用推广的重要手段&#xff0c;一直以来都备受关注。然而&#xff0c;随着移动工具App进入存量时代&#xff0c;用户粘性降低&#xff0c;行业竞争日益激烈&#xff0c;地推的效果评估和提升成为了开发者们亟待解决的问题。在这个背景下&#xff0…