一聚教程网:一个值得你收藏的教程网站

热门教程

Redis如何处理突发流量下的读写压力?

时间:2026-08-30 09:24:49 编辑:袖梨 来源:一聚教程网

Redis突发写压需绕开主线程或前置缓冲,主从架构下须按峰值写入×最长卡顿时间×安全系数计算client-output-buffer-limit硬限,软限设50%–70%,并配合读写分离、STREAM削峰、多级缓存及空值缓存TTL等综合防护。

Redis 本身不扛突发写压,读压靠架构分担,写压必须绕开主线程或前置缓冲——直接在主节点上硬扛高并发写入,等于主动触发雪崩。

主从架构下突发写入导致从节点断连?调 client-output-buffer-limit

主节点为每个从节点单独维护输出缓冲区(omem),一旦突发写入速率超过从节点消费能力,缓冲区堆积超限就会被强制断连,继而触发全量同步雪崩。

  1. 硬限不是“设大点就行”,要按峰值写入 × 最长卡顿时间 × 安全系数算:比如实测峰值 12MB/s,预估从节点最长卡顿 60s,安全系数取 1.5 → 至少设为 1200mb
  2. 软限建议设为硬限的 50%–70%,软时限保持 60 秒,避免网络毛刺误杀连接
  3. 检查当前积压:用 redis-cli -h info replication | grep master_repl_offset 每秒采样两次,算出真实增量速率
  4. 别忽略诱因:跨机房部署、appendfsync always、单次返回大数据集(如 HGETALL)都会加速缓冲区溢出

突发读请求打爆单节点?优先读写分离而非加机器

加 Redis 实例不如把读流量导到从节点——主节点只做写,从节点分担读,成本低、见效快,且避免集群跨槽操作的性能损耗。

  1. 从节点数量建议 3–5 个,用 replicaof 命令建立关系,不要依赖哨兵自动发现(故障时易漂移)
  2. repl-backlog-size 至少设为 100mb,否则网络抖动后从节点无法 PSYNC,只能全量同步
  3. 监控主从延迟:用 info replicationslave_repl_offsetmaster_repl_offset 差值,持续 > 100MB 就该告警
  4. 客户端需支持读写分离路由,Lettuce 可配 ReadFrom.SLAVE_PREFERRED,Jedis 需自行实现

核心链路里直接 PUBLISH 广播?这是把消息系统当缓存用

PUBLISH 是同步阻塞命令,向 5000 个订阅者发一次消息,延迟可能飙到 200ms+;更糟的是它不落盘、无 ACK、断连即丢,根本不是削峰设计。

  1. 真正能削峰的是 STREAM:用 XADD orders * order_id 123 写入,再由后台 worker 用 XREADGROUP GROUP wg1 c1 COUNT 10 STREAMS orders > 拉取并 XACK
  2. SUBSCRIBE 连接数极易打满:maxclients 默认 10000,但 2000+ 活跃订阅者就可能触发 ERR max number of clients reached
  3. Java 客户端默认为每个 MessageListener 开新连接,必须显式复用连接,改用单连接多频道订阅:SUBSCRIBE ch1 ch2 ch3
  4. 模式匹配慎用 PSUBSCRIBE alert.*,避免大量 SUBSCRIBE alert.error 分散频道耗尽连接

缓存层突然被穿透/雪崩?别只靠过期时间随机化

随机过期只是基础,真正防住突发流量冲击,得靠多级拦截和异步兜底。

  1. 空值缓存必须带 TTL(如 60s),否则穿透攻击会反复打穿 DB
  2. 热点 key 要拆:一个 user:1001 改成 user:1001:profileuser:1001:stats,避免单 key 成瓶颈
  3. 本地缓存(Caffeine)+ Redis + Nginx 静态缓存三级结构,90% 请求应落在本地层,而不是直击 Redis
  4. 更新逻辑别用“先删缓存再写 DB”,推荐“先写 DB 再删缓存”,一致性窗口更可控;对强一致场景,必须引入 Canal 订阅 binlog

最常被忽略的点是:突发流量从来不是单一维度的问题。写压、读压、订阅压、缓存失效压往往同时爆发,而 client-output-buffer-limitrepl-backlog-sizeSTREAM 的 pending list、本地缓存 TTL 这些参数,任何一个没对齐峰值场景,整条链路就会在压力下出现确定性断裂。

热门栏目