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

Redis缓存一致性难题:如何让数据库和缓存不“打架”?


标题:Redis缓存一致性难题:如何让数据库和缓存不“打架”?(附程序员脱发指南)


导言:当数据库和缓存成了“异地恋”

想象一下:你刚在美团下单了一份麻辣小龙虾,付款后刷新页面,订单却显示“待支付”——因为缓存没更新!此时的数据库和缓存就像一对异地恋情侣,一个在拼命改变,另一个却毫不知情。如何让这对“情侣”保持同步?今天我们就来聊聊Redis缓存一致性那些事儿,顺便拯救程序员的发际线!


一、缓存一致性翻车现场:程序员の噩梦

先来围观几个经典翻车案例,看看你的代码是否也中过招:

  1. 场景1:老板让我改价格,用户却还在疯狂薅羊毛
    “快把商品价格从99改成199!” 你自信地更新了数据库,但忘记清理Redis缓存。结果用户看到的还是99元,公司血亏,你喜提“本月背锅侠”称号。

  2. 场景2:双11零点,缓存和数据库集体“摆烂”
    促销开始瞬间,缓存突然过期,海量请求直接冲垮数据库。运维小哥含泪重启服务器,而你被拉进“事故复盘会”写检讨。

  3. 场景3:用户刚删了帖子,刷新后居然又“秽土转生”
    用户删除操作明明成功了,但缓存里的帖子还在“阴魂不散”。用户怒喷:“这APP怕不是闹鬼?”

结论:缓存不一致 ≈ 程序员脱发的罪魁祸首!


二、缓存一致性の核心矛盾:先更新谁?先删谁?

解决缓存一致性,本质是回答哲学三问:什么时候更新缓存?怎么更新?删还是改?

方案1:Cache Aside Pattern(旁路缓存)—— 老实人的选择

“读时加载缓存,写时更新数据库+删缓存”

// 写操作伪代码
public void updateProduct(Product product) {// 1. 先怼数据库db.update(product); // 2. 再删缓存(别问,问就是“延迟双删”保平安)redis.del("product:" + product.getId());
}

优点:简单粗暴,适合大部分场景。
缺点:极端情况下仍可能不一致(比如删缓存失败)。
适用场景:适合“读多写少”的业务,比如电商商品详情页。

方案2:Write Through/Write Behind(读写穿透)—— 强迫症的福音

“所有写操作都先过缓存,缓存自己同步到数据库”

// 写操作伪代码(以Write Through为例)
public void updateProduct(Product product) {// 1. 先更新缓存redis.set("product:" + product.getId(), product);// 2. 缓存自己负责写数据库(比如定时批量刷)cacheWriter.asyncWriteToDB(product);
}

优点:强一致性,适合金融等高敏感场景。
缺点:实现复杂,性能损耗大。
适用场景:账户余额、库存秒杀等“不容有失”的业务。

方案3:异步补偿机制—— 佛系程序员的终极奥义

“不一致?反正用户可能发现不了……”

// 订阅数据库的Binlog(比如用Canal)
canal.subscribe("product_table", (event) -> {if (event.isUpdate()) {// 默默更新缓存redis.set("product:" + event.getId(), event.getData());}
});

优点:最终一致性,对业务代码无侵入。
缺点:延迟可能高达几分钟。
适用场景:对实时性要求不高的业务,比如新闻资讯。


三、防脱发の实践指南:Redis缓存一致性的“六脉神剑”

  1. 绝招1:延迟双删
    “第一次删缓存可能失败?那我删两次!”

    public void updateProduct(Product product) {db.update(product);redis.del("product:" + product.getId());// 等数据库主从同步完成(比如500ms后)Thread.sleep(500);redis.del("product:" + product.getId());
    }
    

    适用场景:主从复制延迟较高的系统。

  2. 绝招2:加锁!加锁!加锁!
    “缓存失效时,只让一个线程去查数据库!”

    public Product getProduct(String id) {Product product = redis.get(id);if (product == null) {// 只让一个线程抢到锁(比如用Redis的SETNX)if (lock.tryLock()) {try {product = db.get(id);redis.set(id, product);} finally {lock.unlock();}} else {// 其他线程睡个回笼觉再重试Thread.sleep(100);return getProduct(id);}}return product;
    }
    

    适用场景:防止缓存击穿(比如热点Key突然失效)。

  3. 绝招3:给缓存加个“保质期”
    “就算不一致,最多也只丢脸一小会儿!”

    // 设置缓存过期时间(比如30分钟)
    redis.setex("product:" + id, 1800, product);
    

    适用场景:容忍短期不一致的配置类数据。

  4. 绝招4:版本号控制(防止“诈尸”)
    “数据更新?必须带上版本号!”

    // 缓存Value带上版本号
    redis.set("product:" + id, "{data:..., version:2}");
    // 更新时校验版本号
    if (request.version > cached.version) {db.update(product);
    }
    

    适用场景:并发写较多的场景(比如评论区盖楼)。


四、灵魂拷问:到底该选哪种方案?

—— 答:看你的头发还剩多少!

业务场景推荐方案脱发指数
普通电商商品详情Cache Aside + 延迟双删⭐⭐
秒杀库存Write Through + 分布式锁⭐⭐⭐⭐⭐
用户昵称修改异步补偿 + 版本号控制⭐⭐
金融账户余额不用缓存,直接读库!

五、总结:缓存一致性の终极奥义

  1. 没有银弹:不同业务需要不同策略,别妄想一招通吃。
  2. 监控为王:给Redis和数据库加上健康检查,不一致时告警比用户投诉更快!
  3. 接受不完美:有时候“最终一致性”比“强一致性”更能保住你的头发。

最后送上一句鸡汤

“缓存不一致就像爱情里的误会,及时沟通(更新)才能长久。如果沟通失败……记得加个重试机制!”


附录:防脱发周边推荐

  • 《Redis设计与实现》(书籍)
  • Redisson框架(解决分布式锁的神器)

在这里插入图片描述

相关文章:

Redis缓存一致性难题:如何让数据库和缓存不“打架”?

标题:Redis缓存一致性难题:如何让数据库和缓存不“打架”?(附程序员脱发指南) 导言:当数据库和缓存成了“异地恋” 想象一下:你刚在美团下单了一份麻辣小龙虾,付款后刷新页面&#…...

动态部署Web应用程序与web.xml配置详解

文章目录 前言一、动态部署Web应用程序1.1 什么是动态部署?1.2 动态部署的步骤1.3 动态部署的优势 二、web.xml 配置文件2.1 什么是web.xml?2.2 web.xml 文件的结构2.2.1常见配置(1) 配置上下文参数(2) 配置Servlet(3)配置过滤器(…...

2025年软考报名费用是多少?全国费用汇总!

软考报名时间终于确定了!想要参加2025年软考的同学们注意啦!特别是那些一年只有一次考试机会的科目,千万不要错过哦!这里为大家整理了各地的报名时间、科目、费用等信息,快来看看吧! 一、2025年软考时间安…...

DeepSeek 15天指导手册——从入门到精通 PDF(附下载)

DeepSeek使用教程系列--DeepSeek 15天指导手册——从入门到精通pdf下载: https://pan.baidu.com/s/1PrIo0Xo0h5s6Plcc_smS8w?pwd1234 提取码: 1234 或 https://pan.quark.cn/s/2e8de75027d3 《DeepSeek 15天指导手册——从入门到精通》以系统化学习路径为核心&…...

【Javascript】js精度丢失

当JS处理大整数或者浮点数的时候会出现精度丢失的情况。 Javascript的数字都使用双精度浮点数表示,遵循IEEE754标准 比如我遇到的问题,对一个小数的四舍五入,保留2位小数: 235.985≈235.98 235.9851≈235.99 原理请大家参考百度&…...

让Word插上AI的翅膀:如何把DeepSeek装进Word

在日常办公中,微软的Word无疑是我们最常用的文字处理工具。无论是撰写报告、编辑文档,还是整理笔记,Word都能胜任。然而,随着AI技术的飞速发展,尤其是DeepSeek的出现,我们的文字编辑方式正在发生革命性的变…...

秒杀系统的常用架构是什么?怎么设计?

架构 秒杀系统需要单独部署,如果说放在订单服务里面,秒杀的系统压力太大了就会影响正常的用户下单。 常用架构: Redis 数据倾斜问题 第一步扣减库存时 假设现在有 10 个商品需要秒杀,正常情况下,这 10 个商品应该均…...

【文件基础操作】小笔记

Step1: 现在项目文件夹(我的项目叫做RunPony)下创建一个a.txt文本文件,手动写入一些数字,保存 Step2: 现在在main.c内写一个基本的文件处理的程序 Step3: 现在已经知道如何打开关闭文件,下一步要搞懂如何读取txt内的…...

RabbitMQ系列(七)基本概念之Channel

RabbitMQ 中的 Channel(信道) 是客户端与 RabbitMQ 服务器通信的虚拟会话通道,其核心作用在于优化资源利用并提升消息处理效率。以下是其核心机制与功能的详细解析: 一、Channel 的核心定义 虚拟通信链路 Channel 是建立在 TCP 连…...

本地搭建Koodo Reader书库结合内网穿透打造属于自己的移动图书馆

文章目录 前言1. Koodo Reader 功能特点1.1 开源免费1.2 支持众多格式1.3 多平台兼容1.4 多端数据备份同步1.5 多功能阅读体验1.6 界面简洁直观 2. Koodo Reader安装流程2.1 安装Git2.2 安装Node.js2.3 下载koodo reader 3. 安装Cpolar内网穿透3.1 配置公网地址3.2 配置固定公网…...

DeepSeek R1 训练策略4个阶段解析

DeepSeek R1 训练策略解析 DeepSeek R1 训练策略解析1. 冷启动监督微调(Cold Start SFT)**该阶段的主要目标**: 2. 面向推理的强化学习(RL for Reasoning)**该阶段的主要目标**: 3. 拒绝采样和监督微调&…...

【博资考4】网安学院-硕转博考试内容

【博资考4】硕转博考试内容 - 网络安全与基础理论 写在最前面一. **21年硕转博面试内容回顾**网络、逆向、操作系统、攻防、漏洞1. **网络安全常见攻击方式及其防范措施**1.1 **DDoS攻击(分布式拒绝服务)**1.2 **SQL注入攻击**1.3 **XSS攻击(…...

30 分钟从零开始入门 CSS

HTML CSS JS 30分钟从零开始入门拿下 HTML_html教程-CSDN博客 30 分钟从零开始入门 CSS-CSDN博客 JavaScript 指南:从入门到实战开发-CSDN博客 前言 最近也是在复习,把之前没写的博客补起来,之前给大家介绍了 html,现在是 CSS 咯…...

C语言综合案例:学生成绩管理系统

C语言综合案例:学生成绩管理系统 需求 1.存储最多50名学生的信息(不使用结构体) 2.每个学生包含: 学号(字符数组)姓名(字符数组)3门课程成绩(一维数组) …...

使用python做http代理请求

有这样一个需求现在有两台A,B两台电脑组成了一个局域网,在A电脑上开发webjava应用,需要调用第三方接口做http请求,但是这个请求只能在B电脑上请求。 一种解决方案:自定义一个中间服务,在电脑B上运行一个简…...

数据库事务的基本要素(ACID)

数据库事务的基本要素(ACID) 在数据库管理系统(DBMS)中,事务(Transaction)是一个或多个数据库操作的集合,这些操作要么全部成功,要么全部失败。事务的目标是保证数据的一…...

DeepSeek R1满血+火山引擎详细教程

DeepSeek R1满血火山引擎详细教程 一、安装Cherry Studio。 Cherry Studio AI 是一款强大的多模型 AI 助手,支持 iOS、macOS 和 Windows 平台。可以快速切换多个先进的 LLM 模型,提升工作学习效率。下载地址 https://cherry-ai.com/ 认准官网,无强制注册。 这…...

大型语言模型技术对比:阿里Qwen qwq、DeepSeek R1、OpenAI o3与Grok 3

1. 引言 在人工智能(AI)领域中,大型语言模型(Large Language Models,简称LLM)近年来取得了显著的突破。从早期的GPT-3到如今的各种高级模型,这些技术不仅推动了自然语言处理(NLP&am…...

ArcGIS Pro可见性分析:精通地形视线与视域分析

在地理信息系统(GIS)的广泛应用中,可见性分析作为一项关键技术,发挥着不可替代的作用。 无论是城市规划、环境监测,还是军事侦察、景观设计,可见性分析都能提供精确的数据支持,帮助我们更好地理…...

计算机工具基础(五)——Vim

Vim MIT《Missing in CS Class(2020):Class 3》笔记 Vim是终端环境中常用的纯文本编辑器。Vim的默认配置文件位于~/.vimrc 模式 Vim有如下5种模式: 常规模式(Normal):进入Vim后的默认模式,用于阅读文件。以Esc自其他模式中退至此模式插入模…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

Kafka入门-生产者

生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

Web后端基础(基础知识)

BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...