应用缓存:本地缓存、Redis 与一致性|课后复习

课堂课件 · 课前原始判断 · 本周导学

本次商城补强回收

本日产物:缓存一致性记录与订单 CSV 串行/线程/进程汇总工具。逐项回到课堂同名章节,解释 multiprocessing.Process、spawn/main、ProcessPoolExecutor、序列化与 GIL 适用范围;缓存命中、TTL、容量、改价失效,指出本人代码中输入、状态与失败的位置。再用独立变体证明解释有效,不把讲过当会做。

风险提前预防怎样发现怎样处理怎样复验
Windows 子进程反复启动main 入口保护,顶层工作函数查看重复启动、序列化错误和 PID移开导入时副作用,只传普通数据从文件重新运行 spawn,核对不同 PID
快但报表错或漏掉失败串行结果先核对,金额用 Decimal对比三种模式和坏行异常父进程合并,收取异常,不出半报表0.10+0.20=0.30,NaN 拒绝
缓存价格决定下单交易用数据库,展示缓存有 TTL改价后查详情再下单核对快照提交后失效并记录故障缓存故障与会话故障分别复验

自测:三种模式分组金额与数量完全一致;spawn 独立 PID;坏行不返回半报告;缓存命中/过期/失效;交易快照权威。下一日接口:用既有 Python 处理会话、权限拒绝与审计;缓存降级不能放松身份验证。

今天学会了什么

能读取商城导出的订单 CSV,按状态汇总并比较串行、线程和进程;能为商品详情设置缓存和失效边界,交易仍读取权威价格。

从可靠查询到商品详情缓存

沿图保留原有数据库查询基线,指出新增缓存作用在哪个读取边界;下单金额与库存仍沿权威数据库路径。

今天讲了什么(对照复习)

下面逐项对应课堂正文。先盖住右边那一栏,凭记忆回答;卡住了再翻回左边同名的小节。光说得出名字不算会,还要能讲清它会做什么、什么时候会失效。

课堂对应章节必须能解释的机制与边界
同一个商品为什么查了一百次数据库;缓存的四个基本动作命中直接返回可用结果,未命中回源,回填保存结果,失效移除旧值。TTL 控制存活时间,容量限制内存,LRU 根据最近访问淘汰;三者不能互相替代。
本地缓存:先用函数和字典看懂生命周期本地对象属于当前进程,重启即失;OrderedDict 的 move_to_end 和 popitem(last=False) 管访问顺序。monotonic 衡量经过时间,注入时钟可检查到期边界;锁保护复合操作,不让两个进程共享内存。
为什么引入 Redis 共享缓存;第一次连接 RedisRedis 独立服务可供多个进程共享键,增加网络、序列化和故障成本,单实例不等于高可用集群。实验按 LAB_REDIS_URL 连接;键含命名空间、对象、版本和 ID,金额以字符串序列化,键值不装密码或令牌。
Cache-Aside:由应用决定什么时候查数据库应用先查缓存,未命中查数据库再回填,Redis 不自动查询 MySQL。项目只缓存商品详情,订单、库存和筛选列表保持数据库查询;交易金额也不信任缓存值。
商品改价:先提交数据库,再删除旧缓存提交成功后删除详情缓存,后续读取回填。删除失败或并发旧读回填仍可能产生陈旧窗口;短 TTL 不能升级为强一致承诺,下单始终读取权威价格和库存。
缓存故障与会话故障要分开缓存有连接/读取超时,失败可按策略回源,回源受数据库容量限制。保存身份的 Redis 不可用时受保护请求应拒绝;单独模拟缓存客户端故障,避免把会话故障错误当成可放行。
三类风险先会识别穿透是反复查询不存在数据;击穿是热门键失效引发集中回源;雪崩是大量键同时到期或整体故障。分别考虑输入校验/短暂空值、请求合并、错峰过期与限流;高级机制今天只识别。
用实验决定是否保留缓存固定数据、请求序列、并发与环境,分别记录冷/热缓存的数据库查询数、命中率、p50/p95、错误率和样本数。缓存未必更快;命中率与正确性、成本一起评价。

出了问题:怎么发现、怎么修、怎么验证

只在你自己那份课程副本或专用实验数据上复验,把改之前和改之后的真实结果都留下来。

风险/现象提前预防怎样发现怎样处理怎样复验
本地无限增长或两个实例误当共享同时设容量与到期语义观察容量淘汰、到期时刻和两实例结果修 TTL/LRU,需共享时用独立服务边界命中符合预期,两个本地对象仍明确独立
金额/库存用陈旧缓存成交把交易与展示读取路径分开改库价后保留旧展示值,再查交易取价路径下单回权威数据库,缓存仅服务详情订单按有效库价生成,库存受事务保护
改价失效顺序错误或宣称强一致提交后删缓存,记录失败及 TTL查改价后的读取与并发旧值回填窗口修顺序,记录残留陈旧边界正常失效有效;未覆盖并发场景如实注明
缓存故障无限等待或身份故障放行超时和身份拒绝策略分别定义分别注入缓存故障与会话服务故障商品限时回源;身份故障保持拒绝商品与鉴权按各自合同响应,业务不越权
热缓存快一次就宣称提速固定基线并记录样本数对比查询次数、分位耗时与错误率统一实验条件,重新比较报告包含正确性及代价,允许结论为不值得缓存

闭卷自测

先自己答一遍,再去运行或翻回课堂核对;不确定的地方标出来,别用 AI 的答案顶掉你自己的第一次判断。

  1. TTL、容量与 LRU 各控制什么?本地加锁为什么不能让两个进程共享缓存?

  2. 画 Cache-Aside 命中与未命中路径,注明谁查询 MySQL、谁回填。

  3. 改价后先提交再删缓存为何仍不能保证永远没有旧值?下单从哪里取金额?

  4. Redis 同时保存商品缓存和登录会话时,故障处理为什么必须区分两条路径?

  5. 区分穿透、击穿、雪崩;给每种写一个第一层处理思路,不要求实现高级方案。

  6. 冷缓存和热缓存应记录哪些指标?p95 和单次最快响应为什么不同?

  7. Windows spawn为什么要求入口保护与顶层函数?为什么不能传入打开的数据库连接?三种模式金额相同而进程更慢时,应怎样选择?

再看一眼真实业务

回到预习的重复浏览记录,将“页面更快/没有变化”留作事实,将缓存位置留作未知。用课堂查询次数和缓存键实验,补上页面观察无法提供的技术证据。

今天留下什么,下节课怎么接着用

同时保留本人 CSV 读取和报表入口、三种执行方式相同结果及重复测量记录;不得将本页导出总额称作全库收入。

保留商品详情缓存、键与 TTL 说明、本地/Redis 对照、过期与 LRU 记录、改价失效和缓存故障回源、固定条件性能记录。W03-D03 接入 Redis 会话时沿用故障边界区分。

核心只覆盖商品详情的一条缓存路径。Redis Cluster、布隆过滤器、分布式锁和严格一致性工程留作拓展,不增加今天必修实现。