资讯动态

Redis缓存设计避坑指南:穿透、击穿、雪崩与一致性全解析

发布时间:2026/10/21 11:23:54 来源:尧图企业网站定制
1. 缓存设计的第一课先想清楚要不要缓存不少同学一听到查询慢、数据库压力大第一反应就是“上Redis”。这个方向没有错但很多项目恰恰是死在“无脑上缓存”这一步。你花了半天把热点数据塞进Redis结果发现缓存命中率不到3%还引入了一堆数据不一致的麻烦最后性能没上去线上事故倒先来了。1.1 什么场景才值得用Redis我的判断标准很简单缓存是用来挡住“重复且昂贵”的读请求。什么叫重复就是同一份数据在短时间内被大量地读什么叫昂贵就是拿到这份数据需要跨服务调用、查数据库、做复杂计算超过几十毫秒甚至几百毫秒。举个例子一个商品详情页数据库里存了20万条商品记录但每天真正被反复点开的就是头2000个爆款商品。商店首页一刷新后端要查商品表、库存表、评价表三张表联查加聚合可能花了80毫秒才拼出一个页面。现在峰值流量每秒过来500个请求数据库就得抗500次复杂查询CPU和连接池瞬间告警。这种场景就是Redis的主场把拼装好的页面数据存进RedisKey是商品IDValue是序列化后的页面JSONTTL设为5分钟。下一次请求直接内存命中1毫秒返回数据库压力直接归零。反过来如果你的数据是冷数据一天也就被访问十几次或者你的查询本身就极快走主键索引只要0.5毫秒又或者业务对实时性要求极高、容忍不了任何延迟那缓存非但无益反而添乱。我见过有人对一张只有几百行、几乎不更新的配置表做缓存结果数据变更后总是忘记清理缓存线上线下数据不一致该生效的配置迟迟不生效用户投诉了才去排查。这种缓存就是纯负资产。1.2 过度缓存是怎么毁掉一个系统的过度缓存带来的问题比没有缓存更隐蔽。第一是内存被垃圾Key塞满Redis是一个内存数据库单机上8到16G内存非常常见存一些聊天记录还好但要是一次性把几十个大批量的全表数据都放进去内存马上吃紧触发淘汰策略以后热点Key反而被淘汰掉命中率断崖式下跌。第二是维护成本急剧上升每个缓存Key都需要定义Key命名规则、TTL、更新和删除时机一旦散落七八个团队都在自行其是排查线上问题就得靠猜。我参与过的一个模拟项目就是典型反面教材。当时团队里有一名新同学下面称他A同学为了应付大促之前的性能压测把一批字典数据全部缓存起来大约300万条。结果内存直线飙到14G淘汰策略是默认的noevictionRedis直接开始报OOM错误写入全部失败。那天所有依赖Redis的业务线一起崩了。后来把Key拆成几百个大类缓存按访问频率分级内存立刻降回5G以内。所以并不是“缓存越多越好”而是“该缓存的缓存不该缓存的别碰”。2. 三大经典缓存问题穿透、击穿与雪崩即便缓存设计对了线上还是会出幺蛾子。最经典的就是缓存穿透、缓存击穿和缓存雪崩。这三个词很多人面试能背得滚瓜烂熟但真遇到线上问题仍然容易混。我逐个拆开讲顺带给出每个问题的排查命令和解决方案代码示例。2.1 缓存穿透——查了一个根本不存在的数据缓存穿透可以简单理解为“空数据攻击”。攻击者或业务方请求一个Redis中必然不存在、数据库里也没有的Key比如一个被删除的商品ID或者一个不合法的用户ID。因为缓存里没有请求就直接漏到数据库。如果流量一大数据库就会被这种无效查询打挂而Redis却什么都没做等于白给了。举个例子某个社区App的个人主页接口接收uid参数。正常用户被访问时缓存里有数据直接返回。但是有人写了一个脚本循环请求大量不存在的老UID比如100万到200万号段的用户早被清掉了。这些请求每个都会穿透Redis直达数据库数据库每秒多了几千次无谓查询连接数被打满。更麻烦的是这些查询完全是垃圾流量业务上没有任何价值。解决穿透的两种常用方案一是把空值也缓存起来查询数据库后发现结果为空仍然设置一个KeyValue是空字符串或占位符TTL设短一点比如60秒。这样短期内的重复空查询就都会被挡住。二是用布隆过滤器Bloom Filter在缓存前面加一道“过滤网”把所有合法存在的ID都放进去。查询时先判断ID在不在过滤器中如果不在就直接返回404连Redis都不会去查。布隆过滤器的特点是“宁可放过不会误杀”判断为存在的数据不一定真的存在但判断为不存在的数据一定不存在所以可以安全地拦截绝大多数无效Key。我个人的偏好是“空值缓存短TTL”因为它代码改动量最小也容易人工理解。布隆过滤器适合ID规模特别大、空查询流量极高的场景但要额外维护一份布隆数据结构还要考虑扩容问题。假如你的服务里允许用户上传文本内容生成内容ID存在缓存中偶尔被扫描到几个不存在的ID空值缓存完全够用。某些场景下还可以用接口层做限流比如针对同一个用户或同一个IP的接口调用做频率限制。但这不是缓存层该做的事属于额外的防护手段别指望它能替代缓存层的设计。2.2 缓存击穿——单个热点Key到期一瞬间击穿和穿透最大的区别在于穿透的Key本来就不存在击穿的Key是真实存在的热点Key只是缓存刚好过期了。这个“刚好”发生在高并发的一瞬间后果很严重。举个例子某航空公司在大促开始前把爆款机票的库存数据放进了缓存Key的TTL设置为10分钟。促销刚开始的第一秒几十万个请求同时涌到机票详情页。如果其中一个爆款机票的缓存Key在促销开始的刹那过期等第一个请求来发现缓存Miss去数据库查到数据回填缓存这中间有几十毫秒的空窗。但在这几十毫秒里后面成千上万的请求也都发现缓存Miss全部穿透到数据库数据库瞬间被挤爆连正常业务也一起遭殃。解决击穿的典型方案有三种第一种是“互斥锁重建缓存”当缓存Miss时不是让所有请求都去查数据库而是只有一个请求能拿到锁去重建缓存其他请求要么等待要么先返回旧值。这个方案逻辑清晰效果也明显但引入了额外的开发量和锁等待时间。第二种是“逻辑过期”存进Redis的Value不只是数据本身而是“数据过期时间”。读取缓存时不看Redis TTL而是自行判断逻辑上的过期时间。到了过期时间请求会异步触发一个后台任务去刷新缓存而当前请求仍然先返回旧数据。这个方案的好处是永远不会出现空窗期缺点是实现稍复杂需要有一个可靠的异步刷新线程池。第三种是“永不过期主动更新”热点Key不设TTL只在数据变更时主动更新缓存。缺点是真到了数据库里数据被误删或者忘记更新的时候缓存会一直保留脏数据必须配合定时校验。我自己的建议是先评估你对“脏数据”的容忍度。如果业务能接受短暂的不一致比如商品展示、资讯详情用永不过期加主动更新最省事。如果必须严格一致比如库存扣减那还是用互斥锁方案宁可让后端流量压垮一台哨兵服务也不要让数据库被击穿。2.3 缓存雪崩——大面积Key同一时间集体过期击穿是单个热点Key爆炸雪崩是大批量Key在同一时间段集中过期或者Redis服务整体不可用。集中过期最为常见也最容易被忽视。举个例子你运营一个资讯类App每天凌晨零点发布一期内容把当天所有热点新闻的缓存TTL统一设置为凌晨2点过期。到了凌晨2点零1秒所有客户端都开始请求这批新闻但Redis里一个都没有所有请求同时穿透到数据库。此时的数据库面对的是“全量热点数据的冲击”几乎必挂。预防雪崩的常规手段有几条一是给TTL加随机扰动。同样是过期时间不要让所有Key整整齐齐地同时过期而是把过期时间分散到一个区间内比如原本都是30分钟现在在20到40分钟之间随机化。这个改动一行代码就能搞定效果立竿见影。二是多级缓存。在Redis前面再加一层本地缓存比如进程内缓存一层挡不住还有下一层。但本地缓存要控制好容量别让老年代频繁Full GC。三是做限流降级。即便缓存失效数据库也要能扛住一瞬间的压力。这意味着数据库连接池要预留一些缓冲服务端要配置合理的超时时间和熔断阈值。如果数据库真的扛不住该返回旧数据就返回旧数据也不要让整个服务雪崩开去。四是Redis高可用。用主从复制加哨兵结构如果主节点挂了从节点自动提升为主节点尽可能避免Redis服务整体不可用导致的雪崩。但高可用方案不能替代缓存过期时间的分散设计两者缺一不可。2.4 缓存雪崩的宕机版Redis不可用之后这里补充一个很多人没注意到的坑Redis不可用期间你的服务在做什么服务端连接Redis超时的默认行为通常是把异常抛给上层。如果上层不做兜底比如没有用“本地缓存挡一节数据库兜底”的降级逻辑服务就会集体超时、线程池被占满最终整条业务链路由上到下全挂。这种事叫“雪崩的延续”虽然最初的问题出在Redis但最终被打死的是数据库甚至整个应用。所以哪怕Redis部署了哨兵模式业务代码里也应该准备好“缓存挂了本地缓存接住”的降级方案。降级的思路是查询时先走Redis如果Redis超时或熔断再走一层服务本地缓存本地缓存也没有再查数据库。这中间的差异是本地缓存永远只能保证单体应用内部的命中命中率不会太高但至少能在极端情况下让数据库喘息一会儿。3. 缓存一致性从项目立项前就要想清楚如果说前面三个问题是“性能问题”那么缓存一致性问题就是“正确性问题”。缓存和数据库的数据不一致轻则页面显示错乱重则涉及金额、库存等核心数据的错账。更麻烦的是一致性问题通常不是立刻暴露而是延迟几个小时甚至几天才被发现。3.1 四种主流更新策略的取舍业界常用的缓存更新策略无非这么几大类“先更新数据库再删缓存”、“先删缓存再更新数据库”、“先更新缓存再更新数据库不推荐”、“双删延迟删”。先说结论我推荐在绝大多数业务场景下用“先更新数据库再删除缓存”。这个策略核心思路是数据库是权威数据源缓存只是一个可以被随时重建的副本。业务更新时只改数据库改完之后顺手把缓存删掉。下一次请求发现缓存Miss就会从数据库读出最新数据并回填缓存。它的优点是实现最简单、最符合“缓存是数据副本”的直觉。缺点是更新后到删除缓存的窗口期里旧缓存还在被读取可能有短暂的不一致。但这个窗口期通常只有几毫秒到几十秒取决于数据库更新后到代码执行删除操作的间隔。如果更新和删除不是原子操作还要考虑如果删除失败怎么办。3.2 先更新还是先删除一个必须理解的并发坑为什么“先删缓存、再更新数据库”不推荐假设一个热点商品的详情页过程是请求A要修改商品数据先把缓存删掉还没等它完成数据库更新请求B此时来查数据缓存Miss从数据库里读到旧的商品信息回填缓存。然后请求A才完成数据库更新。这时候缓存里存的是旧数据而数据库里已经是最新数据一直要等到缓存再次过期才会被纠正。这种窗口期可能长达几分钟甚至几小时对很多业务来说是不可接受的。而“先更新数据库、再删缓存”相对安全因为数据库先更新后哪怕删除缓存失败缓存里存的是旧数据但并发期间可能出现很小的窗口期不一致而删除成功后缓存会立即重建为最新数据。风险主要集中在“删除失败”这一个点上。但“双删延迟删”是为了进一步降低这一点的风险而生的。它的做法是在第一次删缓存之后延迟几十毫秒或数秒再删一次缓存。为什么要延迟再删因为在极端并发下请求A更新数据库后第一次删除缓存时请求B可能刚好读到了旧数据并回填了缓存如果A删完之后马上有一个C请求再读可能又会读到旧数据。延迟一次删除可以确保在B回填缓存之后再清掉一次旧数据。这个方案会增加代码复杂度但对于一致性要求极高的场景是值得的。这里有一个很关键的实施细节也是很多人在代码里忽略的。删除缓存时除了调用Redis的del命令最好把删除失败的消息放到一个可靠队列里由后台任务重试直至删除成功。业界管这种模式叫“延迟双删异步补偿”。我不建议你把“删除失败就同步重试”写成同步逻辑因为重试期间如果Redis持续不可用你的业务线程会被白白占住延长整体响应时间。更稳妥的是把失败的Key推进一个本地内存队列或者消息队列由后台线程异步重试。重试次数建议控制在5到10次每次间隔指数退避如1秒、2秒、4秒……以免重试风暴打挂Redis。3.3 读多写少不等于不需要一致有一种常见的错误心态这个数据读多写少偶尔不一致问题不大。确实有很多读多写少的场景比如用户昵称、商品规格、文章标题稍微延迟一秒钟几乎感知不到。但如果你用着“读多写少”这个借口省去了对一致性的设计后续一旦写入频率上升或者某个数据对一致性非常敏感系统就会立刻暴露隐患。我之前参与过的一个积分商城模拟项目积分余额放在Redis里用于高并发扣减同时用户中心数据库也维护了一份余额。本来积分余额的展示应该完全以Redis为准再用数据库异步落账但当时为了“简单”每次用户获得积分时先更新数据库再删缓存。结果扣减积分时用户看到已更新但数据库落账的异步任务还没完成另一次扣减又把缓存删了这时候用户看到的积分忽多忽少多次事故之后才统一改成“数据库最终一致性Redis作为瞬态扣减凭证”的方案。所以针对业务在需求评审的时候就要明确一个问题这项数据允许几分钟甚至几小时内的不一致吗如果允许那就大胆用最简单的先更新数据库再删缓存。如果不允许比如支付结果、库存扣减、优惠券核销就要用延时双删或把Redis降级为旁路状态核心数据只以数据库为准Redis只承担“提升读性能”的角色不要让它参与写路径。4. 实用的健康检查命中率分析、Key治理与快速定位热点Redis缓存跑了一段时间之后切忌只靠直觉判断性能。缓存命中率、Key空间分布、响应延迟这些指标直接决定一个缓存设计是否达标。很多系统刚开始建的时候还好但数据量增长后如果不对缓存做定期体检Redis迟早会变成又一个只有监控图好看、实际性能却很不稳定的组件。以下是我自己常用的一套体检方法。4.1 命中率统计与阈值参考缓存命中率是衡量缓存价值最直观的指标。计算公式很简单命中率 命中次数 / (命中次数 未命中次数) * 100%。Redis的INFO stats命令中可以直接看到keyspace_hits和keyspace_misses两个字段。我建议至少统计一天内的数据分小时看曲线变化。一般来说静态热点数据比如商品详情、基础配置命中率应当高于95%读多写少、有大量带用户ID的个性化数据场景命中率可能会偏低到75%左右这时要分析是不是Key粒度太细导致每个用户的数据都被单独缓存而复用率极低。如果命中率掉到60%以下就要认真思考是不是缓存Key设计错了或者过期时间设置太短导致频繁回源。用命令查命中率的示例redis-cli info stats | grep keyspace结果会类似keyspace_hits:186123 keyspace_misses:23445命中率约为88.8%如果F5刷新几次还能看到misses在涨就属于正常波动。但当命中率低于预期时你可能需要检查一下是否存在某些随机Key或带时间戳的Key这种Key几乎永远不可能命中。4.2 Key命名规范与空间治理Redis缓存最怕的就是Key命名混乱。我见过一个系统里同一个业务数据有的同学用user:info:{userId}有的用userinfo_{id}还有的用cj_user_{id}排查问题时要全库搜索痛苦得要命。这里给出一个我自己的推荐命名规范业务域:对象类型:ID:额外标识比如商品详情mall:product:detail:1用户会话auth:user:session:8f6a购物车数据cart:user:1024:items好处是维护者一眼就能看出Key属于哪个业务、对应什么ID而且用Redis的scan命令按前缀扫描时过滤和统计也方便。别用SETEX key value这种没有业务含义的裸Key线上事故有一半都是从“这个Key到底是谁写入的”开始查起的。同时需要警惕的还有大Key问题。单个Key的Value过大比如超过1MB删除、序列化和网络传输都会很慢还会触发内存碎片和高内存占用。建议设置一个检查阈值比如String值超过512KB、List长度超过1万、Hash的field数超过5000就可以当作大Key处理。删大Key时不要直接用DEL在主线程中操作否则会阻塞Redis实例。大Key要分拆、定期清理或者用UNLINK异步删除。4.3 如何定位热点Key缓存热点Key往往和高流量相关。有时候你的业务上线了一个新功能某个Key的访问量突然飙到每秒数万次即使命中缓存Redis输出网络流量的压力也很大。定位热点Key的方法有好几种在客户端代码里为每个Key的访问次数做计数定期上报或者用Redis Server的MONITOR命令观察近期命令生产环境慎用有性能损耗或者用专业的缓存监控采集工具抓取慢命令和热命令。这里我推荐一种轻量级方案在应用层的Redis客户端里封装一层拦截器统计每个Key被访问的频率定时把top N的Key打印到日志里。虽然会有少量性能损耗但好处是精确定位到“哪个业务模块的哪个Key是热点”比事后抓包猜测直观得多。实际使用时可以把采样比例调低比如每100个请求记录一次控制开销。5. 缓存穿透/击穿/雪崩的实战排查命令与快速止血清单前面讲了原理和方案这一节直接给一套可以照抄的排查和止血流程。真正遇到线上告警时几十秒内判断问题是穿透、击穿还是雪崩比翻阅文档重要得多。5.1 现场观察清单问题发生时我建议立刻执行下面几条命令快速摸清状态# 查看整体统计信息 redis-cli INFO stats # 查看最近访问最多的Key通常需要借助工具或自定义脚本 redis-cli --hotkeys # 需要开启object maxmemory 相关设置的支持 # 查看当前缓存中的键总数 redis-cli DBSIZE # 检查是否有大量Key即将过期 redis-cli INFO keyspace另外不要忘了看应用层的监控面板请求延迟、数据库QPS、Redis内存使用率。如果数据库QPS在某一秒突然暴涨而上游流量并没有明显增加十有八九就是某个或某一批热点Key在过期时间点失效了。5.2 判断陷阱先排除慢SQL还是先排除缓存这里有一个容易被绕进去的地方线上数据库慢查询上涨你去数据库里抓慢SQL抓出来的全是同一条SQL是不是就一定是这条SQL写得烂不一定。很可能是某个热点Key过期导致大量流量瞬间涌入数据库把一两毫秒的简单SQL放大成了几百个并发同时排队最终单条查询慢得离谱。这种时候你反复优化SQL反而没有意义SQL本身不是瓶颈流量突刺才是瓶颈。正确的排查顺序我建议是先看Redis的命中率是否瞬间下降再看数据库QPS曲线是否有尖峰最后才定位是哪一类SQL或哪一个Key。命中率下降曲线和数据库QPS尖峰时间能对上基本就是缓存失效问题对不上再去查慢SQL本身的执行计划。5.3 常用止血脚本模板这里给出一个Java类的简单伪代码用于带互斥锁的缓存重建逻辑。实际使用时务必加上超时和容错。public String getProductDetail(String productId) { String cacheKey mall:product:detail: productId; String cached redis.get(cacheKey); if (cached ! null) { return cached; } // 查询数据库前先尝试获取互斥锁 String lockKey lock:product:detail: productId; boolean locked redis.setIfAbsent(lockKey, 1, 3, TimeUnit.SECONDS); if (!locked) { // 拿不到锁说明其它线程正在重建缓存先短暂暂停后重试读取缓存 try { Thread.sleep(50); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } return getProductDetail(productId); // 注意需设置递归深度或转迭代防止栈溢出 } try { // 这里存在多个线程同时通过——但只有一个能拿到锁其余被挡在外面 String detail loadFromDb(productId); redis.setex(cacheKey, 300, detail); return detail; } finally { redis.del(lockKey); } }这段代码在业务中非常常见。但有几个细节需要提醒你第一setIfAbsent必须指定超时时间防止持有锁的线程中途崩溃导致死锁。我习惯设为3秒但最好根据“数据库查询耗时回填耗时”的1.5倍来定过长会拖慢等待方的延迟过短又起不到拦截并发的作用。第二等待方递归调用getProductDetail可能会导致深层次栈溢出更稳妥的方式是用循环重试比如最多重试3次仍拿不到就直接查数据库返回并做好降级统计。或者也可以引入一个轻量级的短暂自旋每轮sleep 20到50ms总等待上限500ms。第三不要忘了在数据库查询方法里做兜底判断如果数据库返回空同样要把空值缓存起来避免穿透叠加击穿变成“事件风暴”。5.4 击穿与雪崩的缓存预警很多团队会同时开启“慢查询监控”“数据库QPS监控”和“Redis命中率监控”三块面板但这三块面板的告警阈值一般设置得比较宽松等到真正触发告警时数据库已经压力很大了。更好的方式是做“预测式监控”在缓存Key快过期之前提前预判并主动刷新。这听起来复杂实际上有很多现成方案比如后台跑一个定时任务扫描即将过期的热点Key提前10秒到30秒把缓存重置一遍。这样热点Key实际上保持“永不过期”的假象旧数据在过期前就被新数据替换掉。实现成本不高收益却很显著。另一个预警维度是Redis的大Key预警和内存增长趋势预警。每日凌晨记录一次内存水位连续3天涨幅超过20%就要排查是否有新业务在盲写缓存按需治理。5.5 日常缓存监控看板的应配指标如果从零搭建一套简单的Redis缓存监控建议至少包含这样几类指标缓存命中率、Key总数、内存使用量、每秒操作次数、慢查询数量、大Key数量、过期Key数量、连接客户端数量、阻塞平均耗时。这些指标大多可以通过Redis的INFO直接拿原始数据再配合开源监控采集工具做可视化。可别只看一个“平均响应时间”平均响应时间是最骗人的指标热点Key和大Key对平均数的拉升远不如P99和Max耗时敏感。6. 几个很容易被忽略的实现细节最后这部分算不上什么高深内容都属于我踩过很多次坑后才养成的习惯拿出来分享给你。6.1 序列化方式曾经的痛读取缓存时如果Value存在的时候用的是JDK序列化后来你换了JSON序列化线上会瞬间出现大量反序列化异常。换序列化方案之前先在灰度环境放量并准备回滚方案。另外建议在缓存Value里跑一个版本号字段格式类似{v:2,data:{...}}后续做版本迁移时会省下无数心碎时刻。6.2 别在写路径里用缓存有些业务喜欢在“更新数据库”的同时直接同步把新的值写入Redis。这个思路放在某些读多写少、且允许短时间不一致的场景下问题不大但一旦写入频繁Redis会花大量时间做无意义的写入热Key也会被写流量放大。写入的主流路径应该只有数据库Redis的值只能通过“读取时回填”或“特定变更事件触发刷新”这两种方式变化而不是跟随每一次数据库写操作实时同步。6.3 TTL设置的两个极端TTL太短命中率低、数据库压力大TTL太长数据过期时间远脏数据留存时间久。我在不同业务场景下推荐的区间基础配置类的缓存可以保持数小时到一天热点页面数据如商品价格、库存展示最好控制在3到10分钟用户个性化数据如用户头像、昵称可以长一点但也不要超过24小时特别需要强一致的数据尽量别用缓存太久用消息推送失效或者版本号机制驱动更新。6.4 给Redis节点预留足够的内存余量Redis的maxmemory建议设置为物理内存的60%到70%不要顶到100%。主要原因是Redis在内存写满之后会启动虚拟内存互换或淘汰策略而常见的allkeys-lru、volatile-lru策略都会在内存紧张时优先淘汰掉“近期未使用”的Key。某个缓存Key明明还有效却被淘汰掉下次请求穿透到数据库可能会引发一次小规模击穿。预留20%到30%的内存余量等于给缓存留了喘息空间比调多少参数都管用。我在一次压测中曾经把maxmemory设成物理内存的90%结果Redis在淘汰Key时CPU毛刺极高请求延迟从1毫秒飙到30毫秒。把maxmemory降到70%后淘汰频率大幅下降延迟曲线立刻平缓下来。内存是很便宜的资源别为它跟稳定性较劲。6.5 日志和面试时的杀手锏不管是在代码评审时还是在面试中谈到Redis缓存如果只说“用了Redisson分布式锁”“加了空值缓存”那只是入门水平。把“命中率监控、TTL随机化、延迟双删、异步补偿队列、大Key拆分、热点预刷新”这些点串成一套有逻辑的工程方案聊的时候放到具体业务背景里去比如“当时订单查询是典型的读多写少我们设计了先更新数据库再删缓存的旁路策略命中率稳定在97%写入路径完全绕开Redis”这个表达就比干讲数据结构高出一个段位。我个人在实际项目里的体会是缓存设计永远不是“引入一个组件”那么简单。它是一套围绕“数据访问模式”的权衡体系哪些数据值得缓存、以什么粒度缓存、如何保证缓存与数据源最终一致、如何在异常时刻降级兜底。把这些想透了Redis才算真正为你所用而不是为你埋雷。以后每一次往Redis里塞Key、设TTL时多问自己一句“这个Key失效瞬间会发生什么”很多事故原本可以被拦在代码评审阶段。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑