一个首页商品改价,失效广播发给 200 台实例,Redis 出口流量瞬间 800MB/s,其他接口开始超时,广播消息体里带着完整商品对象。乍看像缓存或者权限的锅,追下去往往不是。

channel.publish('cache:invalidate', key + '|' + version);
// 消费端按 key 合并,100ms 窗口只处理一次

追下去是这么回事:每个 key 一条广播,扇出等于实例数,消息体还是几 KB 的完整对象。批量改价时几百条消息叠在一起,网络先于数据库成为瓶颈。

「热点广播风暴」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。报错里带路径的,先去看那个路径在不在、权限对不对。

具体做法是,广播只发 key 和版本号 不带 value;同一批 key 合并成一条消息 消费端按批处理;限流发送 每秒不超过一百条 观察 Redis 出口带宽。

验收就看一点,同样改 300 个商品,广播消息合并成 3 条,Redis 出口峰值降到 20MB/s,其他接口延迟没有波动。

作者 9823189