缓存使用的具体场景有哪些?缓存的一致性问题如何解决?缓存使用常见问题有哪些?


缓存使用场景、一致性及常见问题解析


一、缓存的核心使用场景
1. 高频读、低频写场景
  • 典型场景:商品详情页、新闻资讯、用户基本信息。
  • 特点:数据更新频率低,但访问量极高。
  • 策略
    • Cache-Aside(旁路缓存):优先读缓存,未命中时查数据库并回填。
    • TTL(过期时间):设置合理过期时间(如5分钟),平衡数据新鲜度与缓存命中率。

示例

public Product getProduct(String id) {Product product = cache.get(id);if (product == null) {product = db.query("SELECT * FROM product WHERE id = ?", id);cache.set(id, product, 300); // 缓存5分钟}return product;
}
2. 热点数据加速
  • 典型场景:微博热搜、秒杀活动倒计时、直播在线人数。
  • 特点:短时间内流量突增,需快速响应。
  • 策略
    • 本地缓存 + 分布式缓存:如Guava Cache + Redis,减少网络开销。
    • Key分片:将热点Key分散到多个节点(如hot:item:123hot:item:123_{shardId})。
3. 复杂计算缓存
  • 典型场景:排行榜、聚合统计结果(如用户总积分)。
  • 特点:计算成本高,结果可复用。
  • 策略
    • 预计算+定时更新:定时任务生成结果并缓存。
    • Write-Through(直写):数据变更时同步更新缓存。
4. 会话与状态管理
  • 典型场景:用户登录状态、购物车信息。
  • 特点:临时性数据,读写频繁。
  • 策略
    • Redis Session存储:集中管理会话,支持分布式扩展。
    • TTL自动清理:设置会话过期时间(如30分钟)。

二、缓存一致性问题及解决方案
1. 一致性问题的根源
  • 数据源多副本:缓存与数据库存在两份数据。
  • 并发操作:多线程/多节点同时修改数据。
  • 网络延迟:缓存与数据库更新不同步。
2. 典型场景与解决方案
场景问题描述解决方案
先更新数据库,后删缓存删除缓存失败,后续请求读到旧数据。延迟双删:更新数据库 → 删除缓存 → 延迟几百毫秒再删一次。
先删缓存,后更新数据库删缓存后、更新数据库前,其他请求可能读到旧值并回填缓存。异步重试:删除缓存后,通过消息队列确保数据库更新成功,否则重试删除操作。
并发写导致覆盖多个线程同时更新同一数据,缓存与数据库不一致。分布式锁:更新时加锁(如Redis SETNX),串行化操作。

示例:延迟双删伪代码

public void updateProduct(Product product) {// 1. 更新数据库db.update(product);// 2. 删除缓存cache.delete(product.getId());// 3. 延迟再次删除(应对并发场景)executor.schedule(() -> cache.delete(product.getId()), 500, TimeUnit.MILLISECONDS);
}
3. 最终一致性方案
  • Binlog监听:通过Canal监听数据库变更,异步更新缓存。
  • 消息队列:数据库变更后发送MQ消息,消费者更新缓存。

三、缓存常见问题与应对策略
1. 缓存穿透(Cache Penetration)
  • 问题:大量请求查询不存在的数据(如无效ID),绕过缓存直接访问数据库。
  • 解决
    • 布隆过滤器(Bloom Filter):预存所有合法Key,拦截非法请求。
    • 缓存空值:对不存在的数据缓存NULL并设置短TTL(如30秒)。

示例

public Product getProduct(String id) {Product product = cache.get(id);if (product != null) {return product;}if (bloomFilter.mightContain(id)) { // 布隆过滤器检查product = db.query("SELECT * FROM product WHERE id = ?", id);if (product != null) {cache.set(id, product, 300);} else {cache.set(id, NULL, 30); // 缓存空值}}return product;
}
2. 缓存雪崩(Cache Avalanche)
  • 问题:大量缓存同时失效,请求直接冲击数据库。
  • 解决
    • 随机过期时间:在基础TTL上增加随机值(如TTL + random(0, 300))。
    • 热点数据永不过期:后台定时异步更新缓存。
3. 缓存击穿(Cache Breakdown)
  • 问题:热点Key过期瞬间,大量并发请求直达数据库。
  • 解决
    • 互斥锁(Mutex Lock):第一个请求重建缓存时加锁,其他请求等待。
    • 逻辑过期:缓存Value包含逻辑过期时间,异步刷新。

示例:互斥锁实现

public Product getProduct(String id) {Product product = cache.get(id);if (product == null) {Lock lock = redisLock.lock(id); // 获取分布式锁try {product = cache.get(id); // 双重检查if (product == null) {product = db.query("SELECT * FROM product WHERE id = ?", id);cache.set(id, product, 300);}} finally {redisLock.unlock(id);}}return product;
}
4. 数据漂移(Hot Key 不均)
  • 问题:某个节点缓存过多热点Key,导致负载不均。
  • 解决
    • 本地缓存:在应用层缓存热点数据,减少访问分布式缓存。
    • Key分片:将热点Key分散到多个节点(如product:123product:123_{shardId})。

四、缓存策略选择
策略适用场景优点缺点
Cache-Aside通用场景,需强一致性控制灵活,缓存与数据库解耦需处理一致性问题
Read-Through缓存作为主要数据源简化代码,自动加载数据缓存层需支持加载逻辑
Write-Through写操作频繁且需强一致性数据更新实时同步写延迟较高
Write-Behind高吞吐写场景(如日志记录)写性能高,批量更新数据库数据可能丢失(未持久化前宕机)

🐮🐎

  • 使用场景:缓存适用于读多写少、热点数据、复杂计算等场景,显著提升系统性能。
  • 一致性问题:通过延迟双删、异步消息、分布式锁等方案平衡性能与一致性。
  • 常见问题:穿透、雪崩、击穿需针对性设计防御策略(布隆过滤器、随机TTL、互斥锁)。
    合理选择缓存策略,结合监控与动态调优,可最大化缓存收益并规避潜在风险。

在这里插入图片描述

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

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

相关文章

谷歌 Gemini 2.0 Flash实测:1条指令自动出图+配故事!

今天看到很多人夸Gemini 2.0 Flash的能力很强。 强大的P图能力,改背景、换衣服、调整姿态、表情控制等等 其中最让人眼前一亮的是图文功能。 它不仅是理解图文,而是能根据文字描述创作出一整个的故事、步骤图文。 我上手试了一下,感觉效果…

雷电模拟器连接Android Studio步骤

打开雷电模拟器,点击桌面系统应用—>打开设置—>关于平板电脑→连续点击5次版本号,会出现开发者选项—->进入开发者选项—->勾选打开usb调试。 命令行提示符,进入雷电模拟器安装目录。然后执行 Plain Text adb.exe connect 127.0…

配置普通链接二维码规则 校验文件检查失败

配置普通链接二维码规则 校验文件检查失败 1.问题 2.解决思路: 直接访问地址,不跳转文本,感觉是nginx配置问题打开服务器nginx 域名默认走80端口,配置了指定的访问路径,命令行 nginx -t ,nginx -s reload,start ngin…

c语言经典基础编程题

c语言经典基础编程题 一、输出输出1.1温度输出1.2排齐数据1.3进制转换 二、选择分支2.1求最大值2.2成绩评定2.3分段函数求值2.4 利润计算2.5判断闰年2.6二次方程根 三、循环结构3.1倒数求和3.2最大数3.3判断素数3.4判断完全数3.5打印菱形🚀🚀&#x1f68…

java数据处理:Map<String, Object>、Map<String, List<Room>>、Map<String, Integer>

已知数据都存在WargameConfig.HallMap里。 一、Map<String, Integer> 需求:按照scenarioName进行分类,统计每种scenarioName下的Room对象有多少; 思路:统计一个名为WargameConfig.HallMap的集合中,每个不同场景名称(scenarioName)出现的次数。返回一个键值对映射…

安全的实现数据备份和恢复

&#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》&#xff08;基础篇&#xff09;、&#xff08;进阶篇&#xff09;、&#xff08;架构篇&#xff09;清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、…

TCP网络协议

TCP粘包 1. TCP在接收数据时&#xff0c;多包数据粘在了一起 2. 原因&#xff1a; 1. TCP发送数据时&#xff0c;没有及时发走&#xff0c;会根据缓冲区数据的情况进行重新组包&#xff1b; 2. TCP接收方&#xff0c;没有及时读走缓冲区数据&#xff0c;导致缓冲区大量数…

ES6回顾:闭包->(优点:实现工厂函数、记忆化和异步实现)、(应用场景:Promise的then与catch的回调、async/await、柯里化函数)

闭包讲解 ES6回顾&#xff1a;闭包->(优点&#xff1a;实现工厂函数、记忆化和异步实现&#xff09;、&#xff08;应用场景&#xff1a;Promise的then与catch的回调、async/await、柯里化函数&#xff09; 以下是与 JavaScript 闭包相关的常见考点整理&#xff0c;结合 Pro…

OpenMCU(三):STM32F103 FreeRTOS移植

概述 本文主要描述了STM32F103移植FreeRTOS的简要步骤。移植描述过程中&#xff0c;忽略了Keil软件的部分使用技巧。默认读者熟练使用Keil软件。本文的描述是基于OpenMCU_RTOS这个工程&#xff0c;该工程已经下载放好了移植STM32F103 FreeRTOS的所有文件 OpenMCU_RTOS工程的愿景…

生成对抗网络(GAN)原理与应用

目录 一、引言 二、GAN的基本原理 &#xff08;一&#xff09;生成器&#xff08;Generator&#xff09;的工作机制 &#xff08;二&#xff09;判别器&#xff08;Discriminator&#xff09;的工作机制 &#xff08;三&#xff09;对抗训练的过程 三、GAN在AIGC生图中的应…

STM32 内置的通讯协议

数据是以帧为单位发的 USART和UART的区别就是有没有同步功能 同步是两端设备有时钟连接&#xff0c;异步是没时钟连接&#xff0c;靠约定号的频率&#xff08;波特率&#xff09;接收发送数据 RTS和CTS是用来给外界发送已“可接收”或“可发送”信号的&#xff0c;一般用不到…

ES 使用geo point 查询离目标地址最近的数据

需求描述&#xff1a;项目中需要通过经纬度坐标查询目标地所在的行政区。 解决思路大致有种&#xff0c;使用es和mysql分别查询。 1、使用es进行查询 将带有经纬度坐标的省市区数据存入es中&#xff0c;mappings字段使用geo point类型&#xff0c;索引及查询dsl如下。 geo p…

Appium等待机制--强制等待、隐式等待、显式等待

书接上回&#xff0c;Appium高级操作--其他操作-CSDN博客文章浏览阅读182次&#xff0c;点赞6次&#xff0c;收藏7次。书接上回Appium高级操作--从源码角度解析--模拟复杂手势操作-CSDN博客。https://blog.csdn.net/fantasy_4/article/details/146162851主要讲解了Appium的一些…

【架构艺术】Go语言微服务monorepo的代码架构设计

近期因为项目架构升级原因&#xff0c;笔者着手调研一些go项目monorepo的代码架构设计&#xff0c;目标是长期把既有微服务项目重要的部分都转移到monorepo上面&#xff0c;让代码更容易维护&#xff0c;协作开发更加方便。虽然经验不多&#xff0c;但既然有了初步的调研&#…

深入解析 JVM —— 从基础概念到实战调优的全链路学习指南

文章目录 一、为什么要学习 JVM&#xff1f;1. 面试必备与技能提升2. 性能优化与问题诊断3. 编写高质量代码 二、JVM 基础概念与体系结构1. JVM 简介2. JDK、JRE 与 JVM 三、JVM 内存模型1. 线程私有区2. 线程共享区 四、类加载机制与双亲委派1. 类加载过程2. 双亲委派模型3. 动…

前端及后端实现csv文件下载功能

方法一、 前端内容&#xff1a; const url window.URL.createObjectURL(new Blob([res.data])); const link document.createElement(a); link.href url; const fileNameDateTime getFormattedDateTime(); const filename "用户提现列表"fileNameDateTime.csv…

QT中委托QStyledItemDelegate的使用

目录 一、子类化委托 二、委托方法实现 1)createEditor 2)setEditorData 3)setModelData 4)updateEditorGeometry 三、委托使用 四、总结 Qt的数据容器控件采用模型/视图(model/view)架构设计。模型用于存放控件的数据,视图则用于显示编辑数据,而委托则是…

OpenCV实现视频背景提取

在计算机视觉领域&#xff0c;背景减除&#xff08;Background Subtraction&#xff09;是一种常用的技术&#xff0c;用于从视频序列中提取前景对象。 背景减除的核心思想是通过建模背景&#xff0c;然后将当前帧与背景模型进行比较&#xff0c;从而分离出前景对象。 OpenCV…

NFS实验配置笔记

NFS NFS服务 nfs&#xff0c;最早是Sun这家公司所发展出来的&#xff0c;它最大的功能就是可以透过网络&#xff0c;让不同的机器&#xff0c;不同的操作系统&#xff0c;进行实现文档的共享。所以你可以简单的将他看做是文件服务器。 实验准备 ①先准备一个服务器端的操作…

C语言【数据结构】:理解什么是数据结构和算法(启航)

引言 启航篇&#xff0c;理解什么是数据结构和算法 在 C 语言编程领域&#xff0c;数据结构和算法是两个核心且紧密相关的概念 一、数据结构 定义 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合&#xff08;比如数组&#xff09;&#xff0c;它是组织和存储数…