☰
Redis 技术分享主线:数据结构、缓存三大问题与高可用落地
2026/10/15 19:46:34 网站建设 项目流程

简介:围绕 Redis 核心技术点的分享课件,适合后端开发、运维人员及对内存数据库感兴趣的学习者快速建立知识框架。PPT 从简介、配置文件、持久化机制到常用命令逐步展开,涵盖每秒 11 万次读、8.1 万次写的高性能表现,string、hash、set、sorted set、list 等数据结构,以及原子性操作与主从复制带来的读写分离优势,同时客观指出在线扩容困难、宕机时短暂影响读写等局限。内容系统梳理 redis.conf 中 port、timeout、daemonize、databases 等配置含义,对比 RDB 与 AOF 两种持久化策略的优缺点和核心参数,并对 EXISTS、DEL、EXPIRE、SET、GET、APPEND、INCR 等常用命令作了分类讲解,便于日常查阅与团队内部分享。Redis 常用于缓存、消息代理与数据存储等场景,这份课件对理解生产环境中的选型与调优尤其有帮助。资源包共 1 个文件,为 1.59MB 的 PPTX 演示文稿,已有 161 人学习。通过这份课件,读者可快速掌握 Redis 的选型依据、配置调优思路和持久化方案权衡,适合作为技术分享或入门复习的配套材料。

1. Redis 分享这个主题:一份能撑起两小时技术分享的 pptx 主线

Redis 分享这个主题,几乎是后端技术分享里出现频率最高的。团队里来了新同学要讲 Redis,季度技术交流轮到你也要讲 Redis,面试复盘时还是绕不开 Redis。这份 pptx 不是把官方文档搬进幻灯片,而是把一条主线讲清楚:缓存怎么用、数据怎么不丢、挂了怎么恢复、流量大了怎么扩容。下面按一线工程师准备分享的顺序,把这份 pptx 拆开来看——每个知识点怎么讲才有人听、演示命令跑哪几条、观众最可能追问的坑在哪。适合要准备内部技术分享的后端开发者,也适合想系统过一遍 Redis 核心知识的人照着搭自己的提纲。

2. 讲 Redis 先讲数据结构:五种类型与 IO 多路复用的分享切入点

一份 Redis 分享 pptx 的前半段,基本都围绕数据结构展开。这部分讲得好不好,直接决定听众愿不愿意继续听下去。常见做法是每个类型配一个业务场景,幻灯片上不要铺满命令,一页只放一个类型加两三行命令,现场用 redis-cli 跑一遍,比念文档直观得多。这里要特别注意:分享的目的是让听众记住"这个结构解决什么问题",而不是背命令。

2.1 五类基本类型加三个进阶结构:怎么讲才不变成念文档

下面这组命令可以原样放进课件里,分享时逐条执行,每执行一条就点出它对应的业务场景。String 配计数和会话,Hash 配对象存储,List 配轻量队列,Set 配去重和黑名单,ZSet 配排行榜——五个类型五个锚点,听众不容易走神。

# 分享现场直接演示,比念文档直观 redis-cli # String:计数场景,INCR 是原子的,并发下不会加出重复值 SET login:count 0 INCR login:count # String 带过期时间:会话、验证码都靠它,600 秒后自动消失 SETEX token:9527 600 "session-data" # Hash:对象存储,比拆成多个 String 省内存、好管理 HSET user:1001 name "A同学" age 24 HGETALL user:1001 # List:轻量消息队列,BRPOP 阻塞读,常用于任务分发 LPUSH notify:queue "task-1" BRPOP notify:queue 0 # Set:去重与集合运算,黑名单判断是 O(1) SADD blacklist:ip "10.0.0.1" SISMEMBER blacklist:ip "10.0.0.1" # ZSet:排行榜核心,按分数倒序取前三名 ZADD leaderboard 99 "userA" 85 "userB" ZREVRANGE leaderboard 0 2 WITHSCORES

逐条说明几个关键参数:INCR 的卖点是原子性,它的语义就是"加一",多线程并发下不会丢计数;SETEX 的 600 是过期秒数,这是 Redis 最常用的一个参数,后面讲缓存过期时要反复提到它。BRPOP 的 0 表示永久阻塞等待,直到队列里有数据才返回,这是用 List 做队列和用数据库轮询的本质区别。SISMEMBER 的时间复杂度是 O(1),所以黑名单、已读状态这类判断特别适合用 Set。ZREVRANGE 的 WITHSCORES 让结果带上分数,排行榜页面的原始数据就是这条命令出来的。

讲完五种基本类型,建议再补三个进阶结构,用一张表带过即可,不需要展开命令细节,目的是让听众知道 Redis 不止五种类型。Bitmap 做签到和在线状态,亿级用户也只要几百 MB 内存;HyperLogLog 做 UV 去重统计,单 key 固定占用约 12KB 内存,换来的是极低的内存开销,但要注意 PFCOUNT 返回的是近似值,误差在 0.81% 左右;Geo 底层就是 ZSet,存经纬度,附近的人、门店距离检索都靠它。

2.2 单线程与 IO 多路复用:把"为什么快"讲透

每场分享到这里,几乎必有人问:Redis 为什么快?最常见的回答是"因为它是内存数据库",这个答案只对了一半。内存快是基础,但真正让 Redis 在单线程模型下还能扛住高并发的原因,是 IO 多路复用加非阻塞 IO——一个线程同时盯着成千上万个连接,哪个连接有数据就处理哪个,没有数据就继续监听,避免了大量线程切换和锁竞争的开销。

单线程模型有一个非常容易被忽略的代价:任何一条慢命令都会堵住后面所有命令。分享时我会在这里放一个翻车演示,但强调必须用本地测试实例,别拿生产库开玩笑。正确的讲解方式是先跑反面教材,再给替代方案:

# 反面教材:别对生产库跑这条,几百万 key 的实例会直接卡顿 redis-cli KEYS "*" # 正确的巡检姿势:SCAN 分批扫,COUNT 只是每次遍历的期望条数 redis-cli --scan --pattern "user:*" --count 1000 # 看慢查询,确认有没有命令在拖后腿 redis-cli SLOWLOG GET 5

KEYS 是全量遍历所有 key,单线程执行期间所有其他命令都在排队,这就是线上抖动的常见来源。SCAN 基于游标分批返回,不会阻塞,但 COUNT 是提示不是保证,返回值可能多也可能少,代码里不能依赖它做严格分页。SLOWLOG 默认记录执行时间超过 10 毫秒的命令,阈值可以通过 slowlog-log-slower-than 调整,单位是微秒;看到慢查询日志后,用 SLOWLOG GET 5 取最近五条,基本就能定位是哪段业务代码在拖后腿。

注意:分享现场演示 KEYS 时,一定是对本地测试实例跑,不是对生产库。这个操作本身没有破坏性,但它的阻塞效果在线上会被放大成事故。

单线程还要讲清楚一个边界,否则容易被较真的听众抬杠:Redis 的单线程只指执行命令的核心线程,持久化、异步删除、AOF 重写这些都有后台线程或子进程在干。扩展读并发靠加从库做读写分离,合并多次网络往返靠 Pipeline,保证多条命令原子执行靠 Lua 脚本。把这个逻辑顺下来,听众对"为什么快"和"快有什么代价"就都有概念了。

3. 从演示到生产:缓存三大问题与持久化选型的落地讲法

数据结构是 Redis 的入门,真正决定一份分享含金量的,是把"缓存写入"这件事讲到生产级。这一章对应 pptx 的中段,也是听众最想抄作业的部分。很多团队用 Redis 只跑 GET 和 SET,问起来就说"缓存嘛",但缓存和数据库之间的那层逻辑,才是线上事故的高发区。分享时一定要把缓存读写的基本模式写出来,再讲三个经典问题。

3.1 穿透、击穿、雪崩:一张表讲清区别与对策

先给听众看一段最常见的缓存读写代码,也就是 cache-aside 模式。这段代码建议用 Python 或 Java 写,不要用 redis-cli 命令代替,因为听众回去要照着写业务代码,不是照着手敲命令行:

def get_user(user_id): cache_key = f"user:info:{user_id}" # 1. 先查缓存,命中直接返回 data = redis.get(cache_key) if data is not None: return data # 2. 缓存没命中,回源查数据库 user = db.query("SELECT * FROM user WHERE id=%s", user_id) # 3. 数据库也没有:空值也写缓存,TTL 给短一点,挡住穿透 if user is None: redis.set(cache_key, "", ex=60) return None # 4. 查询结果写回缓存,TTL 加随机值,避免同一时间集体过期 redis.set(cache_key, user, ex=300 + random.randint(0, 60)) return user

这段代码里藏着两个应对思路:第 3 步的"空值短 TTL"是防穿透的标准做法,一个根本不存在的 user_id 反复被查时,数据库不会被打穿,代价是缓存里会多一批空 key,所以 TTL 只给 60 秒;第 4 步的"TTL 加随机值"是防雪崩的最朴素手段,批量写入时每个 key 的过期时间错开 0 到 60 秒,就不会出现整点集体过期的场面。ex 参数是 Redis 设置过期时间的标准写法,后面所有涉及 TTL 的地方都是同一个语义。

穿透解决了,击穿还得单独讲。击穿和穿透最大的区别是:击穿打的是一个真实存在、且访问量极高的热点 key,它在过期的那一瞬间,大量请求同时回源。这时候空值缓存没用,因为 key 是真实存在的。常见做法是互斥重建,只让一个请求去查库,其余请求等锁:

def rebuild_hot_key(cache_key, expire_time): # nx=True 保证只有一个请求拿到锁,其余请求走等待重试 lock_key = f"lock:{cache_key}" if redis.set(lock_key, "1", nx=True, ex=10): try: # 只有拿锁的请求查数据库并重建缓存 data = db.query("SELECT ...") redis.set(cache_key, data, ex=expire_time) finally: # 释放锁,严谨的做法是 Lua 比较 value 再删,防止误删别人的锁 redis.delete(lock_key) else: # 没拿到锁:短暂等待后读缓存,通常已经重建完成 time.sleep(0.1) return redis.get(cache_key)

参数说明:nx=True 对应 SET 命令的 NX 选项,key 不存在时才写入成功,这就是"拿锁"的语义;ex=10 是锁的自动过期时间,防止拿到锁的线程还没执行完就崩溃,锁变成死锁。finally 里释放锁是必须的,但严谨的团队会用 Lua 脚本先比较锁里的 value 再删除,避免一个线程误删另一个线程的锁。锁的过期时间也不能拍脑袋,要大于查库和重建缓存的最坏耗时,否则锁先过期,又放进来一批并发重建。

三个问题放一起对比,听众最容易搞混,一张表讲清楚:

问题现象根因对策
缓存穿透缓存永远不命中,压力全到数据库查询的 key 本身不存在空值短 TTL 缓存、布隆过滤器、接口入参校验
缓存击穿某个热点 key 过期瞬间数据库被打单个热 key 到期且并发极高互斥重建、逻辑过期、热点永不过期
缓存雪崩大面积 key 同时过期,数据库瞬时崩溃批量 key TTL 相同或实例宕机TTL 加随机值、多级缓存、限流降级

3.2 RDB 与 AOF:持久化选型表与演示命令

缓存之外,Redis 作为存储用的时候,持久化是分享里不能跳过的一段。很多团队把 Redis 当纯缓存用就关了持久化,这没问题;但一旦里面放了会话、任务状态、计数,就得想清楚重启后数据还在不在。分享时我常跟听众说一句话:缓存不是保险箱,没配持久化的 Redis 重启后就是一张白纸,这时候才想起来做配置,是没有后悔药的。

持久化部分放两组配置就够了,一组是 RDB 快照触发点,一组是 AOF 开关和刷盘策略:

# RDB 自动触发点:满足任意一条就执行 bgsave save 3600 1 save 300 100 save 60 10000 # AOF 开关与刷盘策略 appendonly yes appendfsync everysec

save 的写法是"时间 变化次数":3600 秒内有 1 次写就存,300 秒内有 100 次写就存,60 秒内有 10000 次写就存,多行之间是"或"的关系,满足任意一条就触发。appendfsync 有三个取值:always 每条命令都刷盘,最安全也最慢;everysec 每秒刷一次,是默认平衡点,最多丢一秒数据;no 完全交给操作系统,性能最好但丢得最多。生产环境绝大多数选 everysec,这个参数值得在分享时重点讲,因为它就是"性能和数据安全"之间的那个旋钮。

RDB 和 AOF 的取舍,用表格一页讲完:

维度RDBAOF
文件形态二进制快照,体积小命令追加日志,体积大,可压缩
恢复速度快慢
数据丢失最近一次快照之后的写入everysec 最多丢 1 秒,always 不丢
性能影响bgsave 时 fork 子进程,大内存机器有毛刺刷盘频率直接影响写延迟
首选场景缓存、可重建数据数据不能丢、一致性要求高

现在主流的做法是两者同时开,或者用混合持久化,重启时先用 RDB 快照快速加载,再补 AOF 增量,兼顾恢复速度和完整性。分享现场可以演示两条手动命令和两个体检工具:BGSAVE 手动触发快照,BGREWRITEAOF 手动压缩 AOF 文件;redis-check-rdb 和 redis-check-aof 分别校验两个文件是否损坏。这几个命令在面试里也常被问,讲清楚等于给听众送分。

4. 高可用与集群:主从、哨兵、Cluster 的边界和参数

讲到高可用,ppt 的进度大概过了三分之二,听众开始进入"这些我好像知道"的状态。这一章的关键不是背概念,而是把三个层次的边界讲清楚:主从解决的是读写分离和宕机恢复,哨兵解决的是自动故障切换,Cluster 解决的是数据量超过单机容量。很多人把哨兵和 Cluster 混为一谈,分享时一定要从"解决的问题不同"切入。

4.1 主从复制与哨兵:故障切换的流程与最小配置

主从复制的最小配置就一行,从节点上写好主节点地址,重启生效,主节点不用改任何东西:

# 从节点配置:一行就够 replicaof 192.168.1.10 6379 # 主库写保护:从库少于 1 个或延迟超过 10 秒时拒绝写入 min-replicas-to-write 1 min-replicas-max-lag 10

复制的流程要讲两句:第一次连接做全量同步,主库生成 RDB 快照发给从库,同时把快照期间的写命令缓冲下来补发;之后是增量同步,主从各自维护复制偏移量,从库落后不多时用 backlog 补差价,落后太多才重新全量同步。min-replicas-to-write 这个参数一定要讲,它和后面的脑裂场景直接相关:当从库数量不足或延迟过大时,主库拒绝写入,宁可损失可用性也不让数据产生分裂。

主从本身不提供自动切换,主库宕机后需要人工把从库提升为主,或者交给哨兵。哨兵的最小部署是三台,配置核心就三行:

# 三台哨兵,quorum 为 2:至少 2 台哨兵认为主库挂了才发起切换 sentinel monitor mymaster 192.168.1.10 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 15000

这里的 2 是 quorum,指"判定主库故障需要几票";哨兵总数是奇数,三台配 quorum 2,五台配 quorum 3,避免出现平票。down-after-milliseconds 是主观下线的判定时长,5000 毫秒内主库没有响应就标记为疑似下线;failover-timeout 控制整个切换过程的超时,防止切换卡死。切换流程可以一句话概括:哨兵确认主库客观下线,从候选从库中选一个数据最新的提升为主,其余从库改为复制新主,客户端通过哨兵感知新的主节点地址。

这里有个高频追问:主从切换后,最近几秒的写入丢了怎么办。复制是异步的,从库大概率落后主库一段增量,切换时这段增量没同步完就丢了,这是异步复制的固有窗口。结合上面的 min-replicas-to-write 就能兜住脑裂场景:旧主库被隔离后切断了和所有从库的连接,写保护触发,拒绝写入,把损失控制在隔离期间而不是让旧主库继续接收业务写入。

4.2 Redis Cluster:槽位分配与多 key 操作的边界

单机内存不够了,才轮到 Cluster 出场。Cluster 把数据打散到多个节点,每个节点负责一部分槽位,整个集群一共 16384 个槽。分享时的演示命令如下:

# 创建三主三从集群:--cluster-replicas 1 表示每个主节点带 1 个从节点 redis-cli --cluster create 192.168.1.10:6379 192.168.1.11:6379 \ 192.168.1.12:6379 192.168.1.13:6379 192.168.1.14:6379 192.168.1.15:6379 \ --cluster-replicas 1 # 查一个 key 应该落在哪个槽位:CRC16(key) 对 16384 取模 redis-cli cluster keyslot "user:1001" # 查当前槽位分布,确认数据是否均匀 redis-cli cluster slots

Cluster 最大的坑在"边界"上。因为 key 分散在不同节点,跨槽位的多 key 操作就不成立了:MSET 涉及多个 key 时所有 key 必须落在同一槽,Pipeline 里跨槽的命令会报错,Lua 脚本操作多个 key 时也要求在同一槽。解决方法是哈希标签,用花括号把要绑定在一起的 key 包起来,CRC16 只对花括号里的内容计算:

# 用 {} 让两个 key 落进同一槽,才能做多 key 操作 redis-cli MSET {order}:1001 amount 99 {order}:1001 status paid

客户端访问 Cluster 时还会遇到两种重定向:MOVED 表示这个 key 的槽已经迁移到另一个节点,客户端要更新路由表;ASK 表示槽正在迁移中,数据可能还在旧节点,客户端要带 ASKING 去新节点试试。这两个状态码在分享时提一句即可,听众知道"迁移期间请求会被重定向"这个事实就够了。

主从、哨兵、Cluster 三种模式放一张对比表收尾,听众就能记住各自的适用边界:

模式自动故障转移数据分片适合规模典型场景
主从无,需人工介入无读多写少读写分离、备份
哨兵有无单机容量内高可用、自动切换
Cluster有有数据量超单机大规模缓存、存储

5. 分享现场最容易被追问的坑:5 个高频事故的排查路径

问答环节才是分享的高潮。听众不会问"ZSet 底层是什么"这种背课文的问题,他们问的都是线上真实事故。这一章的内容建议直接做成 pptx 的附录页,遇到追问就翻出来。以下 5 个场景每个都按现象、原因、解决三步讲,都是我在准备分享和帮同事排查时反复遇到过的,算是一线积累下来的血泪经验。

5.1 大 key 删除让主线程卡了几秒

现象:某接口平时 5 毫秒返回,某天突然出现几秒的超时,Redis 监控里 ops 曲线瞬间掉到 0 又弹回来,应用日志里全是超时重试。

原因:有人在清理数据时对一个超大集合执行了 DEL,或者业务把十几万元素的 List 当队列用,删除时 DEL 是 O(N) 操作,在单线程模型里执行期间所有命令都在排队。

解决:删除大 key 用 UNLINK,后台线程慢慢回收,不阻塞主线程;同时打开 lazyfree 相关配置,让 key 的释放都走异步。日常巡检用 redis-cli --bigkeys 提前扫出大 key,超过一定大小的集合要做拆分,或者换 Hash 分片存储。这个坑最麻烦的地方在于它不是每次必现,而是数据量涨到某个阈值才爆发,所以分享时一定要强调"提前发现"而不是"事后处理"。

5.2 整点缓存雪崩,数据库被打垮

现象:每天整点或零点,缓存命中率骤降,数据库 CPU 和连接数同时拉满,缓存重建也建不起来,接口大面积超时。

原因:批量初始化数据时 TTL 全部写成一样的,时间一到集体过期,所有请求同时回源。定时任务在整点刷新缓存是最常见的触发方式,比随机写入更容易踩中。

解决:写入时 TTL 加随机秒数,比如 300 到 360 之间随机;热点数据干脆不设置过期时间,由后台任务定时刷新;再不行就在数据库前面加一层限流和降级,让数据库先活下来。这里有个容易被忽略的点:如果缓存重建本身很慢,雪崩后会形成"一边过期一边打库"的恶性循环,所以热点 key 的逻辑过期方案比单纯加随机值更彻底。

5.3 主从切换后,最近几秒的写丢了

现象:主库宕机,哨兵完成切换后业务恢复,但业务方对比数据库和 Redis,发现 Redis 里少了最近几秒的写操作。

原因:复制是异步的,从库大概率落后主库一段增量,切换时这段增量没来得及同步就丢了。这是异步复制的固有窗口,不是配置错误。

解决:对不能丢的数据,写主库后调 WAIT 命令等待至少一个从库确认再返回;在哨兵模式配上 min-replicas-to-write 和 min-replicas-max-lag,让孤立主库少写甚至拒写。分享时可以明确告诉听众:Redis 默认是可用性优先,想要强一致就别让它当唯一数据源,数据库或消息队列才是兜底。

5.4 一条 KEYS 命令让线上抖了一下

现象:版本发布后某个接口偶发超时,慢查询日志里出现大量 GET 排队超过 1 秒,Redis 的 ops 曲线出现周期性凹陷。

原因:新上线的同学用 KEYS 做模糊搜索,或者用 HGETALL 拉取了一个持续增长的大 Hash,执行时间越来越长,单线程被打满。这类问题隐蔽在代码审查里很难发现,因为本地数据量小,跑不出性能差异。

解决:模糊匹配改成 SCAN 游标遍历分页处理;大 Hash 用 HSCAN 分页读取,或者拆成多个小 key。排查时用 SLOWLOG GET 确认是哪条命令、执行了多久,再顺着调用链找到代码位置。如果慢查询里反复出现同一个 key 的 HGETALL,那基本可以断定是"大 key 读"而不是命令本身的问题。

5.5 连接数被打满,新请求被拒绝

现象:应用日志报 "max number of clients reached",Redis 新连接全部失败,业务大面积报错,重启应用后恢复,过一段时间又复现。

原因:客户端没有用连接池,每个请求都新建连接;或者某台机器连接泄漏,TIME_WAIT 堆满,把 maxclients 顶穿。Redis 单机默认连接数上限通常是一万,看起来很多,但架不住每个请求一条连接。

解决:客户端统一走连接池,设置合理的 maxTotal 和 maxIdle,空闲连接及时回收;服务端调 timeout 让空闲连接被回收;排查期间用 INFO clients 看 connected_clients 和 blocked_clients,定位是哪个客户端没还连接。我在某跨平台系统的压测阶段就真实踩过这个坑,压测脚本不走连接池,直接把 Redis 打到拒绝连接,后来所有压测脚本都默认先检查连接池配置。

6. 最后一页演示:用三个命令验证 Redis 状态,顺便收尾分享

分享的最后一页别放"谢谢"两个字就结束,放一个现场体检环节,听众记住的是动作,不是口号。我习惯用三个命令收尾,分别对应内存、性能、状态三个维度,每一页放一条加一句解读,三分钟讲完,比任何总结都有效。

# 1. 内存体检:自动扫描各类 key 的大小分布,揪出大 key redis-cli --bigkeys # 2. 压测:现场跑出每秒几万的 ops,证明 Redis 单线程也能扛高并发 redis-benchmark -c 50 -n 100000 -t set,get # 3. 看关键指标:命中率、连接数、运行状态 redis-cli INFO stats redis-cli INFO clients

--bigkeys 会遍历实例并对每个 key 做类型和大小估算,只读不阻塞,适合分享现场跑,扫完会按类型列出最大的几个 key。redis-benchmark 的 -c 是并发连接数,-n 是总请求数,-t 是只测 set 和 get,现场看到每秒几万的 ops,比讲一百遍"Redis 快"都有说服力。INFO stats 里重点看 keyspace_hits 和 keyspace_misses,两个值一除就是命中率,命中率长期低于 90%,基本可以断定缓存设计有问题;INFO clients 看 connected_clients 是否异常增长,结合上面的连接数事故一起讲,正好首尾呼应。

最后再补一个动作,算是给想回去改代码的听众一个抓手:缓存和数据库的一致性。很多人问"先更新数据库还是先删缓存",我的习惯是"先更新数据库,再删缓存",并且删两次:

def update_user(user_id, new_data): # 1. 先更新数据库 db.execute("UPDATE user SET ... WHERE id=%s", user_id) # 2. 再删缓存,让下次读的时候重建 redis.delete(f"user:info:{user_id}") # 3. 延迟后再删一次,兜住并发读把旧值写回缓存的窗口 time.sleep(0.5) redis.delete(f"user:info:{user_id}")

更新顺序必须是先库后缓存,因为先删缓存再更新库的话,更新期间读请求会把旧值写回缓存,脏数据窗口更长。延迟双删解决的是"更新完库还没删缓存"的间隙里,并发读把旧值写回缓存的问题——睡 0.5 秒再删一次,把这个脏窗口补上。这个 0.5 不是固定值,按业务读链路耗时调,读链路越慢睡得越久;更彻底的方案是订阅数据库 binlog,异步删缓存,但那需要额外的组件,分享时点到为止即可。

我自己在给某跨平台系统做缓存改造时,就因为只删了一次缓存,线上出现过一次老数据回写,用户看到的是改完的资料又变回旧值。从那以后凡是用 cache-aside 的地方,默认都带上延迟双删。分享收尾时把这个动作连同三个体检命令一起留给听众,比再背一遍数据结构有用。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询