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

Redis教程(二十一):Redis怎么保证缓存一致性

 传送门:Redis教程汇总篇,让你从入门到精通

Redis 的缓存一致性

Redis 的缓存一致性是指在使用 Redis 作为缓存层时,保证缓存中的数据与数据库中的数据保持一致的状态。在分布式系统中,数据一致性是一个重要的问题,因为可能存在多个客户端同时读写同一数据,或者数据在不同节点间需要同步更新。

 

在涉及缓存的场景中,保持缓存一致性面临以下挑战:

 
  1. 数据更新:当数据库中的数据被修改后,相关联的缓存数据需要被相应地更新或失效,以避免返回陈旧的数据。

  2. 数据失效:当缓存的数据被认定为过时(可以是时间过期,或者因为底层数据有变更)时,必须从缓存中移除,以确保下次读取会从后端数据库加载最新数据。

  3. 数据同步:在分布式缓存环境中,相同的数据可能会存储在多个缓存节点上。这就要求所有的节点在数据变化时保持同步,从而确保数据的一致性。

 

为了处理这些挑战,你可以采取以下几种常见的方法保证缓存一致性:

 

强一致性

 

确保缓存和数据库的写入操作是原子的,即任何时刻,所有客户端看到的数据总是最新的。在实践中,这通常需要使用分布式锁或事务来实现,但可能会带来性能上的开销。

 

弱一致性

 

接受在短时间内缓存数据可能不同步的情况,但确保在一定时间后能够达到一致性。例如,可以通过设置缓存的过期时间来自动让旧数据失效。

 

缓存更新策略

 

比如采用“写入时更新”(Write-through)、“写入后更新”(Write-behind)等策略,这些策略定义了不同的数据同步时机和方式。

 

维护缓存和数据库的一致性可能会很复杂,需要在数据的实时性(一致性)和系统的性能之间做权衡。正确的缓存策略和实现细节取决于具体的应用场景和对数据一致性的需求。

缓存一致性

首先,我们首先明确什么是缓存一致性:

  • 缓存中有数据,那么,缓存的数据值需要和数据库中的值相同;
  • 缓存中本身没有数据,那么,数据库中的值必须是最新值。

缓存同步策略

  • 先更新缓存,再更新数据库;
  • 先更新数据库,再更新缓存;
  • 先删除缓存,再更新数据库;
  • 先更新数据库,再删除缓存;
  • 先删除缓存,再更新数据库,延迟一会后,再删除缓存(延迟双删);

代码实现

用一个HashMap模拟数据库存储

package com.single.conherence;import java.util.HashMap;
import java.util.Map;/*** @program: RedisDemo* @description:* @author: fudingwei* @create: 2024-05-28 11:39**/
public class DataBaseConstant {public static final Map<String,String> DATA_MAP = new HashMap<String,String>();
}

1、先更新缓存,再更新数据库

package com.single.conherence;import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.StringCodec;
import org.redisson.config.Config;import java.util.Date;
import java.util.concurrent.TimeUnit;import static com.single.conherence.DataBaseConstant.DATA_MAP;/*** @program: RedisDemo* @description: 先更新缓存,再更新数据库,A,B两个线程* @author: fudingwei* @create: 2024-05-28 11:12**/
public class RedisTest1 {public static void main(String[] args) throws InterruptedException {//1、A更新缓存为 apple,然后出现网络延迟,A暂停//2、B过来更新缓存 peer,更新数据库 peer//3、A继续更新数据库 apple,就会导致数据不一致问题Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");StringCodec stringCodec = new StringCodec();config.setCodec(stringCodec);RedissonClient redisson = Redisson.create(config

相关文章:

Redis教程(二十一):Redis怎么保证缓存一致性

传送门:Redis教程汇总篇,让你从入门到精通 Redis 的缓存一致性 Redis 的缓存一致性是指在使用 Redis 作为缓存层时,保证缓存中的数据与数据库中的数据保持一致的状态。在分布式系统中,数据一致性是一个重要的问题,因为可能存在多个客户端同时读写同一数据,或者数据在不同…...

android apk签名

android apk签名 命令&#xff1a; java -jar signapk.jar platform.x509.pem platform.pk8 **.apk ***.apk note&#xff1a; apk密钥为&#xff1a; platform.pk8和platform.x509.pem 路径&#xff1a; build\target\product\security apk签名工具&#xff1a;sign…...

flutter 解析json另类封装方式 List<bean>,哈哈哈

flutter 解析json另类封装方式&#xff0c;哈哈哈 日常学习&#xff0c;仅供参考&#xff0c;不喜 勿喷 http请求数据泛型解析封装&#xff0c;需要判断泛型数据类型再根据类型解析&#xff0c;本文只抽取了list演示 核心代码 import dart:convert;import package:webwsyn/h…...

哈希表(Hash table)

哈希表(Hash table),也称为散列表,是一种根据关键码值(Key value)直接进行访问的数据结构。它通过散列函数(Hash function)将关键码值映射到表中的一个位置,以此来访问记录,从而加快查找的速度。以下是关于哈希表的详细解释: 基本概念 散列函数:将关键码值映射到表…...

【c语言】自定义类型-结构体

结构体 结构体的声明与使用结构体的声明与初始化结构体的自引用 结构体的内存对齐对齐规则为什么存在内存对齐修改默认对齐数 结构体的传参结构体实现位段什么是位段位段的内存分配位段的跨平台问题位段使用的注意事项 结构体&#xff1a;是一个自定义的类型&#xff0c;成员可…...

2-链表-71-环形链表 II-LeetCode142

2-链表-71-环形链表 II-LeetCode142 参考&#xff1a;代码随想录 LeetCode: 题目序号142 更多内容欢迎关注我&#xff08;持续更新中&#xff0c;欢迎Star✨&#xff09; Github&#xff1a;CodeZeng1998/Java-Developer-Work-Note 技术公众号&#xff1a;CodeZeng1998&#…...

【UnityShader入门精要学习笔记】第十七章 表面着色器

本系列为作者学习UnityShader入门精要而作的笔记&#xff0c;内容将包括&#xff1a; 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更&#xff0c;有始无终 我的GitHub仓库 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 表面着色器…...

Python社会经济 | 怀特的异方差一致估计量

&#x1f3af;要点 &#x1f3af;算法​和模型底层数学及代码&#xff1a;&#x1f58a;线性代数应用&#xff08;主成分分析&#xff09;&#xff1a;降维、投影&#xff08;用于求解线性系统&#xff09;和二次形式&#xff08;用于优化&#xff09;| &#x1f58a;奇值分解…...

《被讨厌的勇气》笔记

自由就是被别人讨厌。对人而言&#xff0c;最大的不幸就是不喜欢自己。活在“如果怎样怎样”之类的假设之中&#xff0c;就根本无法改变。活在害怕关系破裂的恐惧之中&#xff0c;那是为他人而活的一种不自由的生活方式。人生是连续刹那&#xff0c;我们只能活在“此时此刻”。…...

Python爬虫协程批量下载图片

import aiofiles import aiohttp import asyncio import requests from lxml import etree from aiohttp import TCPConnectorclass Spider:def __init__(self, value):# 起始urlself.start_url value# 下载单个图片staticmethodasync def download_one(url):name url[0].spl…...

Flask Web开发基础:数据库与ORM实战

Flask Web开发基础&#xff1a;数据库与ORM实战 该文介绍了如何使用 Flask、SQLAlchemy 和 SQLite 实现数据库操作。首先&#xff0c;通过创建虚拟环境和安装 flask-sqlalchemy&#xff08;版本2.5.1&#xff09;及 sqlalchemy&#xff08;版本1.4.47&#xff09;来设置环境。接…...

pidstat -d 1分析磁盘吞吐量

iostat -dx 1 查看磁盘IO吞吐量 pidstat -d 1看是哪个进程写的...

期望20K,2年golang深圳某互联网小公司一面

后续约了二面&#xff08;CTO面&#xff09;&#xff0c;需要到现场&#xff0c;基本没问啥具体的技术知识&#xff0c;都是聊规划和个人职业目标 一面 1、假设访问百度网站&#xff0c;从在浏览器输入网址&#xff0c;到最终页面展示出来&#xff0c;中间会发生哪些事情&…...

#02 安装指南:如何配置Stable Diffusion环境

文章目录 前言前置条件第1步&#xff1a;安装Python和PIP第2步&#xff1a;创建虚拟环境第3步&#xff1a;安装PyTorch和CUDA第4步&#xff1a;安装Stable Diffusion相关库第5步&#xff1a;测试环境结论 前言 在之前的文章中&#xff0c;我们介绍了Stable Diffusion基础入门和…...

拼多多笔试

拼多多2022数据分析笔试&#xff08;0822&#xff09; 一、选择题 1.已知样本量n&#xff0c;样本均值及方差求置信区间 2.决策树 3.峰度系数 4.协方差 5.第一、第二熵变 6.充分统计量 7.xgboost 8.方差分析中的多重比较 二、编程题 1. 一张用户点击路径的表&#x…...

Golang | Leetcode Golang题解之第119题杨辉三角II

题目&#xff1a; 题解&#xff1a; func getRow(rowIndex int) []int {row : make([]int, rowIndex1)row[0] 1for i : 1; i < rowIndex; i {row[i] row[i-1] * (rowIndex - i 1) / i}return row }...

Flutter 中的 SliverIgnorePointer 小部件:全面指南

Flutter 中的 SliverIgnorePointer 小部件&#xff1a;全面指南 Flutter 是一个由 Google 开发的跨平台 UI 框架&#xff0c;它提供了一系列的组件来帮助开发者构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的滚动组件中&#xff0c;SliverIgnorePointer 是一个用来包…...

比较两台计算机上的LabVIEW、工具包及驱动程序的一致性

比较两台计算机上的LabVIEW、工具包及驱动程序是否相同&#xff0c;可以通过以下步骤实现&#xff1a; 1. 检查LabVIEW版本 方法一&#xff1a;在LabVIEW中查看版本信息 步骤&#xff1a; 打开LabVIEW。点击菜单栏的 Help > About LabVIEW。记录显示的LabVIEW版本号和许可…...

参考——温湿度传感器DHT11驱动_STM32

设备&#xff1a;stm32f407ZGT6 环境&#xff1a;FreeRTOS HAL 到网上找DHT11的驱动&#xff0c;但是都无法使用。原因是RTOS环境中&#xff0c;由于多线程&#xff0c;使用循环计数阻塞式的delay_us延时函数就没那么准&#xff0c;且不同设备中delay_us的计数值不一样…...

架构每日一学 14:架构师如何进行可行性探索?

架构活动中&#xff0c;如果不进行可行性探索可能会导致重大失误&#xff0c;为企业发展带来风险。 可行性探索是架构活动的最后一个节点&#xff0c;在这之后的架构活动就像是离弦之箭&#xff0c;即便发现重大风险也很难再回头了。 互联网公司之间的竞争非常激烈&#xff0…...

信号处理中的数字滤波器设计策略指南:从理论到实际应用

信号处理中的数字滤波器设计策略指南&#xff1a;从理论到实际应用 【免费下载链接】gnuradio GNU Radio – the Free and Open Software Radio Ecosystem 项目地址: https://gitcode.com/gh_mirrors/gn/gnuradio 在现代通信系统和信号处理应用中&#xff0c;数字滤波器…...

WPF 实现windows文件压缩文件解压过程动画

目标&#xff1a;最终实现&#xff1a;整体拆分&#xff0c;分步实现&#xff1a;1.控件的基底&#xff0c;是一个实心的矩形2.在基底上绘制绿色网格线&#xff0c;类似棋盘的效果3.有进度条显示&#xff0c;进度条是长度可变的浅绿色的矩形块4.有实时速度显示&#xff0c;速度…...

嵌入式开发调试宏与性能优化实战

1. 嵌入式开发调试宏的妙用在嵌入式开发中&#xff0c;调试是最耗时耗力的环节之一。每次修改代码后都需要重新烧录、运行、观察结果&#xff0c;这个过程往往要重复数十次。而合理使用编译器提供的调试宏&#xff0c;可以大幅提升调试效率。1.1 基础调试宏解析GCC编译器提供了…...

YOLOv12性能优化 | 注意力融合 | 实战解析CBAM模块的集成与调优

1. CBAM注意力机制的核心原理与实战价值 第一次接触CBAM模块时&#xff0c;我被它简洁高效的设计惊艳到了。这个由通道注意力和空间注意力组成的双剑客&#xff0c;能在不显著增加计算量的情况下&#xff0c;让模型学会"该看哪里"。想象一下教小朋友看图说话&#xf…...

打破设备壁垒:Sunshine让游戏自由流动的串流革命

打破设备壁垒&#xff1a;Sunshine让游戏自由流动的串流革命 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 想象一下&#xff1a;你在客厅的高性能电脑上开始了一场紧张刺激的3A大…...

Keras图像分割模型训练完整指南:从参数配置到性能评估

Keras图像分割模型训练完整指南&#xff1a;从参数配置到性能评估 【免费下载链接】image-segmentation-keras Implementation of Segnet, FCN, UNet , PSPNet and other models in Keras. 项目地址: https://gitcode.com/gh_mirrors/im/image-segmentation-keras 图像分…...

FUTURE POLICE语音模型.NET平台调用实战:Windows桌面语音应用开发

FUTURE POLICE语音模型.NET平台调用实战&#xff1a;Windows桌面语音应用开发 你是不是也遇到过这样的场景&#xff1f;手头有一段重要的会议录音&#xff0c;或者一段外语学习材料&#xff0c;需要快速整理成文字。手动听写不仅耗时耗力&#xff0c;还容易出错。现在&#xf…...

Awoo Installer深度解析:破解Switch游戏安装困境的全能工具

Awoo Installer深度解析&#xff1a;破解Switch游戏安装困境的全能工具 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer 在Nintendo Switch破解社区…...

像素幻梦·创意工坊应用场景:独立音乐人专辑封面像素艺术生成流程

像素幻梦创意工坊应用场景&#xff1a;独立音乐人专辑封面像素艺术生成流程 1. 引言&#xff1a;像素艺术在音乐视觉中的价值 在数字音乐时代&#xff0c;专辑封面依然是艺术家表达音乐理念的重要载体。对于独立音乐人而言&#xff0c;独特的视觉风格往往能成为作品的标志性符…...

忍者像素绘卷惊艳案例:生成支持CSS Sprite切片的像素角色动作序列图

忍者像素绘卷惊艳案例&#xff1a;生成支持CSS Sprite切片的像素角色动作序列图 1. 像素艺术的新纪元 在游戏开发领域&#xff0c;像素艺术始终保持着独特的魅力。忍者像素绘卷作为一款基于Z-Image-Turbo深度优化的图像生成工具&#xff0c;为开发者带来了革命性的解决方案。…...