实时同步缓存,与阶段性同步缓存——补充理解《补充》

根据 Redis 缓存的数据与 DBMS 中数据的同步性划分,缓存一般可划分为两类:实时同步缓存,与阶段性同步缓存

实时同步缓存是指,DBMS 中数据更新后,Redis 缓存中的存放的相关数据会被立即清 除,以促使再有对该数据的访问请求到来时,必须先从 DBMS 中查询获取到最新数据,然后 再写入到 Redis。

阶段性同步缓存是指,Redis 缓存中的数据允许在一段时间内与 DBMS 中的数据不完全 一致。而这个时间段就是这个缓存数据的过期时间。

一、用 "外卖订单状态" 这个生活场景,通俗解释 实时同步缓存

1. 初始状态(数据存储)

  • DBMS(数据库) :订单 ID=123 的状态是 "已接单"(这是最终数据,存在数据库里,不会丢)。
  • Redis 缓存 :也存着订单 123 的状态 "已接单"(方便外卖平台快速显示,不用每次查数据库,像手机里的 "缓存" 订单状态)。

2. 订单状态更新(DBMS 数据变化)

  • 商家做了饭,点击 "配送中"(更新 DBMS 数据:订单状态从 "已接单"→"配送中")。
  • 这时候,Redis 缓存里的旧状态必须马上失效(就像手机 APP 里的订单状态缓存被 "清空"),否则用户刷新还会看到 "已接单"(脏数据)。

3. 用户刷新订单(访问数据)

  • 第一次刷新
    • APP 先查 Redis 缓存(看有没有订单状态),发现缓存被清空了(缓存未命中)。
    • 只好去 DBMS 数据库查,拿到最新状态 "配送中" ,然后 把这个新状态存回 Redis 缓存(下次刷新就快了)。
  • 第二次刷新
    • APP 直接从 Redis 缓存拿 "配送中"(缓存命中),秒级显示,不用等数据库查询。

4. 为啥要这么做?(实时同步的意义)

  • 数据准 :用户看到的订单状态和数据库里的 完全一致(商家改了,APP 马上显示新状态,不会延迟)。
  • 速度快:第一次刷新后,缓存里有新状态,后续刷新不用查数据库,像 "已取餐""已送达" 这些状态切换时,用户体验更流畅。

5.对比 "阶段性同步"(比如外卖店铺名称,几天才改一次)

  • 假设店铺名称存在 Redis 缓存,设置 24 小时过期(阶段性同步)。
  • 商家改了店名(DBMS 数据变了),但 Redis 缓存里的旧店名还能存 24 小时(用户可能看到旧店名,直到缓存过期)。
  • 这种适合 变化少、对实时性要求低 的数据(店名几天改一次,用户暂时看旧的也没关系,换来缓存性能)。

6.总结(人话版)

  • 实时同步缓存数据库一变,缓存马上删,下次访问必须从数据库拿新数据,再存回缓存(保证数据 "即时准",适合订单状态、库存这些秒变的数据)。
  • 就像外卖 APP 里的订单状态:商家每动一步(接单、配送、完成),APP 马上更新(背后就是 DBMS 改了,Redis 缓存失效,重新存新状态),用户永远看最新的,还不卡。

二、中间搞这个缓存的作用?

超市收银台扫码 的例子,告诉你为啥非要在数据库(DBMS)和应用之间加一层 Redis 缓存,看完秒懂!

场景:超市收银台扫码查商品价格

假设你去超市买东西,收银员扫码查价格,背后有两种模式:

模式一:直接查数据库(无缓存)
  • 流程
    扫码 → 系统直接访问 DBMS 数据库 → 查商品表 → 返回价格(比如 "可乐 3 元")。
  • 问题
    • :如果同时有 100 个人排队结账,每个扫码都要查数据库,数据库像 "堵车的十字路口",响应变慢,排队时间暴涨。
    • 容易崩:数据库扛不住高并发查询(比如双 11 超市大促销),可能直接 "罢工",整个收银系统瘫痪。
模式二:加 Redis 缓存(有缓存)
  • 流程
    1. 第一次扫码 (比如 "可乐"):
      • 系统先查 Redis 缓存 → 发现没数据(缓存未命中)。
      • 再查 DBMS 数据库 → 拿到价格 "3 元",同时把价格存到 Redis 缓存(比如存 1 小时)。
    2. 之后 1 小时内再扫可乐
      • 系统直接从 Redis 缓存取数据(缓存命中)→ 瞬间显示价格,不用查数据库。
  • 好处
    • 快如闪电:99% 的扫码请求直接走缓存,像从 "收银台抽屉" 里拿数据,比 "去仓库翻账本" 快 10 倍以上。
    • 数据库减压:数据库只需要处理第一次查询,后续请求全被缓存 "拦截",像给数据库雇了个 "前台接待",减少 90% 的压力。
    • 体验好:结账速度快,排队变短,顾客不抱怨,超市效率高。

缓存的核心作用总结(用大白话讲)

  1. 当 "快速访问" 比 "绝对实时" 更重要时,缓存就是救星

    • 比如:商品价格、用户信息、首页推荐数据(这些数据偶尔几分钟不一致没关系,但必须让用户秒级看到)。
    • 反例:银行转账金额(必须绝对实时,这时缓存可能闯祸,所以用实时同步策略,甚至不用缓存)。
  2. 给数据库 "减负",防止它被压垮

    • 数据库像 "慢条斯理的老会计",适合处理少量、复杂的写操作(比如修改库存);
    • 缓存像 "手脚麻利的临时工",专门处理大量、简单的读操作(比如查价格),分工合作。
  3. 提升用户体验:让 APP / 系统 "不卡顿"

    • 比如刷朋友圈、看新闻列表,数据先从缓存取,秒级刷新;后台再慢慢从数据库更新缓存,用户完全感知不到延迟。

回到之前的外卖例子:为啥订单状态要用实时同步缓存?

  • 订单状态(已接单→配送中) 是 "实时性要求高 + 读多写少" 的数据:
    • 写操作少:商家改状态是偶尔的(比如每天几百单)。
    • 读操作多:用户、骑手、商家可能每秒都在刷新订单状态(比如 10 万人同时看)。
  • 如果不用缓存:每次刷新都查数据库,数据库会被 "读爆",页面加载慢,甚至崩溃。
  • 用实时同步缓存
    1. 写数据时(改状态),先更新数据库,再立即删缓存(保证缓存无旧数据)。
    2. 读数据时,第一次查数据库 + 存缓存,后续全走缓存,速度起飞,同时数据还是准的。

一句话总结:缓存是 "用空间换时间" 的魔法

  • 牺牲一点内存空间(Redis 存在内存里),
  • 换来 10 倍以上的读取速度,并让数据库 "轻松活到下班"。
  • 就像超市在收银台抽屉里放常用商品价格表:查价快、不堵车,数据库(仓库账本)只需要处理罕见商品或价格变动。

现在明白为啥程序员总说 "先查缓存,再查数据库" 了吧?本质是为了 "快" 和 "稳",缺一不可~


三、用 "朋友圈头像" 这个生活场景,通俗解释 阶段性同步缓存

"朋友圈头像" 这个生活场景,通俗解释 阶段性同步缓存,让你秒懂 "为什么允许数据暂时不一致" 和 "过期时间" 的作用:

场景:微信朋友圈查看好友头像

假设你刷朋友圈,看到好友小明的头像,背后的技术逻辑是这样的:

数据特点
  • 读多写少:小明可能一年改一次头像(写操作少),但你和其他 1000 个好友每天会看他头像 10 次(读操作极多)。
  • 实时性要求低:即使小明刚改完头像,你过几分钟看到旧头像也没关系(不影响聊天,非关键数据)。
阶段性同步缓存的流程(带过期时间)
  1. 初始状态(第一次看头像)

    • DBMS(数据库) :存储小明的头像地址 img/123.jpg(最新数据)。
    • Redis 缓存:无数据(首次访问)。
    • 流程
      • 你刷到小明的朋友圈 → 系统先查 Redis 缓存(未命中)→ 查数据库 → 拿到头像地址 img/123.jpg存入 Redis 缓存,并设置过期时间 30 分钟SET user:123:avatar img/123.jpg EX 1800)。
  2. 小明改头像了(DBMS 数据更新)

    • 小明把头像换成 img/456.jpg → 系统 只更新数据库不主动删除 Redis 缓存(这是关键!)。
    • 此时 Redis 缓存中还是旧头像 img/123.jpg(允许暂时不一致)。
  3. 你在 30 分钟内刷新朋友圈(缓存未过期)

    • 系统查 Redis 缓存 → 拿到旧头像 img/123.jpg → 直接显示(无需访问数据库,速度极快)。
    • 你看到的是旧头像,但小明的新头像已经存在数据库里了(数据不一致,但在允许的时间范围内)。
  4. 30 分钟后(缓存过期)

    • 你再次刷新 → 系统查 Redis 缓存(发现过期 / 失效)→ 回源数据库 → 拿到新头像 img/456.jpg更新 Redis 缓存(下次刷新就显示新头像了)。

核心逻辑:用 "时间换性能" 的权衡

  • 为什么允许不一致?

    • 如果每次改头像都强制删除缓存(实时同步),那么:
      • 小明改一次头像,接下来 1000 个好友的每次访问都要查数据库(数据库压力大)。
      • 而实际场景中,头像属于 "非敏感非实时数据",晚几分钟看到新头像不影响用户体验。
    • 阶段性同步的策略:设置合理的过期时间(如 30 分钟),在这段时间内用旧缓存响应请求,大幅减少数据库压力,同时最终(过期后)保证数据一致。
  • 过期时间(TTL)的作用

    • 相当于给缓存数据设置一个 "保质期",确保旧数据不会永远存在。
    • 时间设置原则:数据更新频率越低,过期时间可以越长(如静态页面设 1 天;半静态数据设 1 小时)。

适用场景举例(适合阶段性同步的典型数据)

场景 数据类型 过期时间设置 为什么用阶段性同步?
电商商品详情页 商品描述、规格参数 1 小时 - 1 天 商品信息很少修改,用户偶尔看到旧描述不影响购买。
新闻 APP 首页新闻列表 新闻标题、摘要 30 分钟 新闻更新有周期性,旧列表不影响用户浏览体验。
网站静态资源(CSS/JS) 静态文件版本号 12 小时 静态文件几乎不变,浏览器和缓存共同加速访问。
社交平台用户粉丝数 用户粉丝数统计(非实时) 5 分钟 粉丝数偶尔延迟显示,用户不敏感(非交易数据)。

对比实时同步缓存(一目了然)

维度 实时同步缓存 阶段性同步缓存
数据一致性 强一致(DBMS 改后缓存立即失效) 最终一致(过期时间内允许不一致)
适用场景 交易数据(如订单金额、库存) 非实时数据(如头像、商品描述)
数据库压力 较高(每次写操作都可能触发查库) 低(大部分读请求走缓存)
典型过期时间 无(缓存随写操作立即更新) 分钟级 - 天级(根据数据更新频率)
相关推荐
21号 110 分钟前
9.Redis 集群(重在理解)
数据库·redis·算法
爬山算法11 分钟前
Redis(73)如何处理Redis分布式锁的死锁问题?
数据库·redis·分布式
Chen-Edward16 分钟前
有了Spring为什么还有要Spring Boot?
java·spring boot·spring
jason.zeng@150220732 分钟前
centos中安装redis
linux·redis·centos
陈小桔1 小时前
idea中重新加载所有maven项目失败,但maven compile成功
java·maven
小学鸡!1 小时前
Spring Boot实现日志链路追踪
java·spring boot·后端
xiaogg36781 小时前
阿里云k8s1.33部署yaml和dockerfile配置文件
java·linux·kubernetes
yumgpkpm2 小时前
华为鲲鹏 Aarch64 环境下多 Oracle 、mysql数据库汇聚到Cloudera CDP7.3操作指南
大数据·数据库·mysql·华为·oracle·kafka·cloudera
逆光的July2 小时前
Hikari连接池
java
微风粼粼2 小时前
eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
java·ide·eclipse