Redis-场景缓存+秒杀+管道+消息队列

缓存一致性

1.两次更新

  • 先更新数据库,再更新缓存;
  • 先更新缓存,再更新数据库;

出现不一致问题场景:

先更新数据库,再更新缓存;

先更新缓存,再更新数据库;

两次更新的适用场景:

        如果我们的业务对缓存命中率(一定要用到缓存)有很高的要求,我们可以采用「更新数据库 + 更新缓存」的方案,因为更新缓存并不会出现缓存未命中的情况

 解决缓存不一致的办法

  • 在更新缓存前先加个分布式锁,保证同一时间只运行一个请求更新缓存,就会不会产生并发问题了,当然引入了锁后,对于写入的性能就会带来影响。
  • 在更新完缓存时,给缓存加上较短的过期时间,这样即时出现缓存不一致的情况,缓存的数据也会很快过期,对业务还是能接受的。

2.更新+删除策略

2.1 先删除缓存再更新数据库

出现问题的场景

请求A更新 请求B读取

解决办法

延迟双删:

        请求A先删除缓存然后再更新数据库,再给A加个睡眠时间,主要是为了确保其他请求完成读操作写入的缓存,然后请求 A 睡眠完,再删除缓存。

        所以,请求 A 的睡眠时间就需要大于请求 B 「从数据库读取数据 + 写入缓存」的时间。

但是具体睡眠多久其实是个玄学,很难评估出来,所以这个方案也只是尽可能保证一致性而已,极端情况下,依然也会出现缓存不一致的现象。

因此,还是比较建议用「先更新数据库,再删除缓存」的方案。

2.2 先更新数据库再删除缓存

请求A读取 请求B更新

上图是可能出现不一致的场景,但是在实际中,这个问题出现的概率并不高因为缓存的写入通常要远远快于数据库的写入。

出现问题的场景:

     「先更新数据库, 再删除缓存」其实是两个操作,在删除缓存(第二个操作)的时候可能会失败,导致缓存中的数据是旧值,而数据库是最新值

确保删除成功的办法
消息队列重试机制

        我们可以引入消息队列,将第二个操作(删除缓存)要操作的数据加入到消息队列,由消费者来操作数据。

  • 如果应用删除缓存失败,可以从消息队列中重新读取数据,然后再次删除缓存,这个就是重试机制。当然,如果重试超过的一定次数,还是没有成功,我们就需要向业务层发送报错信息了。
  • 如果删除缓存成功,就要把数据从消息队列中移除,避免重复操作,否则就继续重试。

缺点是,对代码入侵性比较强,因为需要改造原本业务的代码。

订阅 MySQL binlog,再操作缓存

        如果是MySQL、Redis缓存同步场景,为了保证成功率,可以用一个消费服务订阅MySQL binlog 日志,拿到具体要操作的数据,然后再向Redis执行缓存删除操作。

更具体的说法:

        可以通过订阅 binlog 日志,拿到具体要操作的数据,然后再执行缓存删除,阿里巴巴开源的 Canal 中间件就是基于这个实现的。

        Canal 模拟 MySQL 主从复制的交互协议,把自己伪装成一个 MySQL 的从节点,向 MySQL 主节点发送 dump 请求,MySQL 收到请求后,就会开始推送 Binlog 给 Canal,Canal 解析 Binlog 字节流之后,将binlog日志采集发送到MQ队列里面,然后编写一个简单的缓存删除消息者订阅binlog日志,根据更新log删除缓存,并且通过ACK机制确认处理这条更新log,保证数据缓存一致性。

八股总结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Windows] 字体渲染 mactype v2025.4.11

[Windows] 字体渲染 mactype 链接:https://pan.xunlei.com/s/VONeCUP2hEgO5WIQImgtGUmrA1?pwdyruf# 025.4.11 Variable font support 可变字体支持已到来。 本版本将可变字体支持扩展到所有 GDI 应用程序。 所有 win32 程序中的字体,如 Noto Sans、Se…

【C++】深拷贝与浅拷贝

重开也不是不可能 ~.~ 浅拷贝 #include <iostream> #include <cstring>class ShallowCopyExample { public:int m_nValue;int* m_pData;// 构造函数&#xff0c;初始化指针成员ShallowCopyExample(int value) : m_nValue(value) {m_pData new int(0);*m_pData va…

SpringBoot企业级开发之【用户模块-更新用户头像】

功能如下所示&#xff1a; 我们先看一下接口文档&#xff1a; 为什么头像是一串字符串呢&#xff1f;因为我们是将头像图片放到第三方去存储&#xff0c;比如&#xff1a;阿里云等 开发思路&#xff1a; 实操&#xff1a; 1.controller 注意!这里使用【PatchMapping】注解…

vue3+vite+js项目引入electron构建跨平台桌面应用

1.准备工作 ① 必要安装node.js、vue、vite、electron、pnpm 本人用的node版本v18.17.1、vue版本^3.4.19、vite版本^3.2.7、electron版本^35.1.4 ② 开发调试打包安装 "devDependencies": {"concurrently": "^9.1.2","electron-builder&…

(51单片机)串口通讯(串口通讯教程)(串口接收发送教程)

前言&#xff1a; 今天有两个项目&#xff0c;分别为&#xff1a; 串口接收: 串口发送&#xff1a; 如上图将文件放在Keli5 中即可&#xff0c;然后烧录在单片机中就行了 烧录软件用的是STC-ISP&#xff0c;不知道怎么安装的可以去看江科大的视频&#xff1a; 【51单片机入门…

《汽车制造技术基础》第一次作业

作业内容 查阅相关资料&#xff0c;谈谈对汽车制造技术的发展的理解。 可以是关于汽车的先进制造技术 或 汽车先进制造技术 与 制造理念的发展趋势 或 汽车先进制造技术对环境与可持续发展的影响等。 以下从技术突破、制造理念转型及环境影响三个维度展开对汽车制造技…

Scala day4(tuple, set and map)

Foreword Hi!! my dear friends, are you lazy at today?? Oh! I am also lazy sometimes, but you will know keep study that’s a right way at last. Now!! let’s start new travel about Scala. Text The all Codes in file day3.scala, like the below program: i…

docker compose搭建博客wordpress

一、前言 docker安装等入门知识见我之前的这篇文章 https://blog.csdn.net/m0_73118788/article/details/146986119?fromshareblogdetail&sharetypeblogdetail&sharerId146986119&sharereferPC&sharesourcem0_73118788&sharefromfrom_link 1.1 docker co…

第二期:[特殊字符] 深入理解MyBatis[特殊字符]MyBatis基础CRUD操作详解[特殊字符]

前言 &#x1f31f; 在掌握了 MyBatis 的基本配置与环境搭建之后&#xff0c;接下来的重点便是深入理解其核心功能——CRUD 操作&#xff08;增删改查&#xff09;。&#x1f4bb; 数据库操作是任何应用开发中不可或缺的一环&#xff0c;而 MyBatis 正是通过灵活的 SQL 映射机…

Java面试黄金宝典46

1. Python 如何写爬虫 定义:Python 爬虫是借助 Python 语言编写程序,模拟浏览器行为向目标网站发送 HTTP 请求,获取网页内容,再通过解析工具提取所需数据的程序。其本质是自动化的数据采集过程。要点: 发送请求:利用requests库发送 HTTP 请求,如 GET、POST 等,获取网页…

建设“大数据智慧招商平台”,助力园区突破招商瓶颈!

在数字经济高速发展的今天&#xff0c;传统招商模式正面临信息不对称、效率低下、匹配不精准等瓶颈。产业园区作为区域经济发展的核心载体&#xff0c;亟需借助智能化手段提升招商效能。构建大数据智慧招商平台&#xff0c;利用大数据、人工智能等技术获取精准招商线索、促进产…

Vue事件修饰符课堂练习

Vue事件修饰符课堂练习 题目‌&#xff1a;基于 Vue 2.0&#xff0c;使用事件修饰符 .stop、.prevent、.capture、.self 和 .once&#xff0c;为按钮绑定 click 事件&#xff0c;并展示每个修饰符的作用。 要求‌&#xff1a; 创建一个 Vue 实例&#xff0c;并绑定到一个 HT…

【C#】线程回调

在 C# 中&#xff0c;线程回调是一种常见的编程模式&#xff0c;用于在线程完成任务后执行某些操作。通过使用 Thread 类或其他更高层次的并发工具&#xff08;如 Task&#xff09;&#xff0c;可以实现线程回调的功能。 回调机制 特点 直接性&#xff1a;回调通常是通过委托…

【C++游戏引擎开发】第14篇:视图空间与相机坐标系

一、视图空间的基础数学框架 1.1 齐次坐标与变换矩阵 三维坐标系变换采用44齐次坐标矩阵,其通用形式为: M = [ A 3 3 b 3 1 0 1 3 1 ] \mathbf{M} = \begin{bmatrix} \mathbf{A}_{33} & \mathbf{b}_{31} \\ \mathbf{0}_{13} & 1 \end{bmatrix} M=[A33​013​​…

【大模型理论篇】关于生成式模型中联合分布概率学习必要性以及GPT是生成式模型的讨论

1. 背景 之前我们在《生成式模型与判别式模型对比(涉及VAE、CRF的数学原理详述)》以及《生成式模型算法原理深入浅出&#xff08;涉及Stable Diffusion、生成对抗网络、高斯混合模型、隐马尔可夫模型、朴素贝叶斯等算法原理分析及生成式模型解释&#xff09;》中&#xff0c;我…

DIP支付方式改革下各种疾病医疗费用的影响以及分析方法研究综述

DIP支付方式改革下各种疾病医疗费用的影响以及分析方法研究综述 摘要 本文综述了DIP支付方式改革对不同疾病医疗费用的影响及其分析方法&#xff0c;通过分析12篇相关文献&#xff0c;探讨了DIP支付方式在控制医疗费用、优化费用结构、提升医疗服务效率等方面的作用及其局限性…

嵌入式硬件篇---单片机周期

文章目录 前言 前言 在单片机中&#xff0c;时序控制是其执行指令和协调外设的核心基础。以下是单片机中常见的各种周期及其详细说明&#xff0c;以层次结构展开&#xff1a; 时钟周期&#xff08;Clock Cycle&#xff09; 定义&#xff1a; 时钟周期是单片机的最小时间单位&a…

游戏引擎学习第221天:(实现多层次过场动画)

资产: intro_art.hha 已发布 在下载页面&#xff0c;你会看到一个新的艺术包。你将需要这个艺术包来进行接下来的开发工作。这个艺术包是由一位艺术家精心制作并打包成我们设计的格式&#xff0c;旨在将这些艺术资源直接应用到游戏中。它包含了许多我们会在接下来的直播中使用…

【3GPP核心网】【5G】精讲5G系统的策略和计费控制框架

1. 欢迎大家订阅和关注,精讲3GPP通信协议(2G/3G/4G/5G/IMS)知识点,专栏会持续更新中.....敬请期待! 目录 1. 系统架构 1.1 非漫游架构 1.2 漫游架构 1.3 支持Rx接口 2. 服务化接口及参考点 2.1 PCF 与 AF 间接口 2.2 PCF与SMF间接口 2.3 PCF与AMF间接口 2.4 V-PC…

榕壹云门店管理系统:基于Spring Boot+Mysql+UniApp的智慧解决方案

项目背景&#xff1a;数字化赋能服务行业&#xff0c;破解传统门店管理痛点 在消费升级与数字化转型浪潮下&#xff0c;传统服务行业&#xff08;如美容、美发、美甲、采耳等&#xff09;面临诸多管理挑战&#xff1a;会员流失率高、预约排班混乱、员工绩效统计低效、数据孤岛等…