
Kill-redis-plan本地模拟缓存击穿、缓存穿透、缓存雪崩用于研究redis缓存开源网站自行本地复现 Redis 缓存穿透、击穿、雪崩。注意力在缓存层Compose 只跑 Redis存储用进程内 FakeDB用 Go goroutine 打并发。观测挂在内核上每秒输出一个生产指标窗口结束后汇总全程指标由人根据关联变化判断缓存状态。穿透penetrate查不存在的数据。缓存一直空每次请求都打到存储。击穿breakdown单个热点 key 过期大量并发同时 miss瞬间打到存储。雪崩avalanche大批量 key 同一时刻过期大面积 miss存储被打满。reports日志 观测格式avalancheconcurrency2000planned2400qps400duration6skeys200expiry2s backendredis127.0.0.1:6379db_latency100msdb_concurrency20refill_ttl30stimedonerequest_total request_p99 request_errors redis_hit redis_miss redis_hit_rate redis_miss_rate redis_expired redis_errors origin_total origin_unique_keys origin_breadth origin_hot_share db_total db_saturation db_max_waiting db_wait_p99 db_found db_not_found 1s400/24004001.553ms03990100.0%0.0%00000.0%0.0%00.0%00s002s794/24003991.082ms0395598.8%1.2%6055100.0%20.0%50.0%00s003s1143/2400401506.879ms016523541.2%58.8%194023519583.0%0.9%19896.2%100455.679ms18304s1600/2400400556.031ms04000100.0%0.0%00000.0%0.0%3719.4%0157.456ms5705s1999/2400399992µs04000100.0%0.0%00000.0%0.0%00.0%00s006s2400/24004001.109ms04000100.0%0.0%00000.0%0.0%00.0%00s00resultstatusokelapsed6.001sdone2400/2400failures0requesttotal2400errors0input_rejected0p99505.855msoverflow0redishit2160miss240hit_rate90.00%errors0ops_p991.074msoverflow0expired200evicted0origintotal240unique_keys200duplicate_reads40valid_rate100.00% hot_keykeyitem:155total2share0.83%max_inflight2dbtotal240found240not_found0errors0max_waiting100wait_p99455.679mswait_overflow0query_p99101.055msquery_overflow0具体还是可以到项目中去观察最好来到本地跑一下观测一下数值在面对 三大问题的变化。数据流一次请求cache.Get(id)→ RedisGET。hit 则返回FakeDB 不动。miss 则store.Get占槽、睡延迟、查 map。有值就 RedisSET带 TTL 再返回没值只返回空不写 Redis。回源回源Redis Miss -向 DB 发起查询(不管 Found 还是 Not Found)回源是个动作Found一次有效回源Not Found一次无效回源回源率 origin_total/redis_miss回源集中度 origin_hot_key_total/origin_total穿透penetrateRedis 返回 nil -回源查询 DB -DB 返回结果为空 / 影响行数为0-缓存穿透捕获一次就是一次穿透穿透次数 origin_total∩DB Not Found观测Server / 全链路监控层 中加入Redis MissDB Not Found的复合判定埋点.恶意攻击攻击者构造大量不存在的 ID如负数 ID、随机字符串频繁请求接口业务 bug前端传入了错误的参数如删除了某条数据后仍然不断查询爬虫扫描遍历式爬虫尝试访问不存在的资源-t unique默认。下标 i从 0 起打 id1000000i每个 ID 只请求一次模拟不断生成新 ID 的随机扫描。-t repeat从一组不存在 ID 中均匀抽取并打散后齐发模拟失效链接、爬虫或攻击脚本同时反复访问一批不存在资源。默认id_pool100当-n较小时自动缩小池子确保会产生重复请求。两个模式都会齐发。开启方案 2 后repeat的首波仍可能在空值写入前并发回源只有首波结束后的后续请求才会命中短 TTL 空值缓存。QA 为什么没有用redis_miss?防击穿组件SingleFlight / 互斥锁的拦截如果有 1000 个并发请求打过来Redis 确实记录了 1000 次 Miss。但如果应用层配置了 singleflight只有 1 个请求真正去查了 DB其余 999 个在内存里挂起等待复用。此时Redis Miss 1000 ! 真实回源数 1如果拿 Redis Miss 当回源你会误以为数据库正承受 1000 次冲击但实际上数据库压力只有 1。击穿breakdown击穿 针对同一 Key 的高并发回源(origin_hot_key_max_inflight)∩DB Foundorigin_total106origin_unique_keys1origin_hot_keyitem:1 origin_hot_key_total106origin_hot_key_max_inflight105origin_hot_key_total/origin_total(回源集中度)≈100% origin_hot_key_max_inflight1针对同一 key 的高并发回源: 106 次回源全部针对 item:1其中最多有 105 次同时进行。热点 Key 过期/失效 -大量并发请求同时 Redis Miss -瞬间并发回源 DB -DB 成功返回有效数据 -缓存击穿预热把item:1写入 RedisTTL 用 config 里的值每 50ms 轮询EXISTS直到 key 消失时限为ttl3s超时则失败退出。然后-n个 goroutine 同时打 id1。回写完成前其余请求也会 miss叠到同一条回源上。雪崩avalanche雪崩特征 大面积 Redis Miss∩多 Key 的有效回源∩DB 满载、排队与请求延迟上升redis_expired200redis_miss_rate56.3% origin_total224origin_unique_keys200origin_breadth89.3% origin_hot_share0.9% db_found180db_saturation91.4% db_max_waiting100db_wait_p99453.375ms request_p99503.295ms大面积 Redis Miss200 个 key 同时过期Redis Miss 率在该窗口升至 56.3%。、多 Key 的有效回源224 次回源覆盖 200 个不同 key广度为 89.3%排除击穿与穿透db_found180表示这些请求查到有效数据不是缓存穿透。origin_hot_share0.9%表示回源没有集中在单一热点 key因此不是击穿。DB 满载、排队与请求延迟上升DB 在该窗口 91.4% 的时间处于满载最多 100 个请求等待并发槽DB 等待 P99 为 453.375ms最终将请求 P99 推高到 503.295ms。预热先用同一个绝对过期时间预热item:1..keys随后立即启动固定 QPS 的持续流量0..ttl缓存正常命中。key 集体过期后多 key 同时 miss、回源DB 开始满载和排队。回填完成后Redis 命中恢复DB 清空积压请求。文章内容来自README非AI编写以及润色