pipeline本身不触发淘汰,但会加速触达maxmemory上限;单位时间写入总量陡增导致内存瞬时飙升,执行完即检查超限并立即按策略淘汰。

PIPELINE 写入本身不触发淘汰,但会加速触达 maxmemory 上限
Redis 的 PIPELINE 只是把多个命令打包发过去、一次性解析执行,它不改变单条命令的内存开销。真正导致淘汰被频繁触发的,是「单位时间内写入总量陡增」——比如原本 100 次 SET 分散在 1 秒内,现在用 PIPELINE 在 10ms 内全塞进去,内存瞬间涨了一大截,极可能跨过 maxmemory 阈值。
常见错误现象:
- 监控看到
evicted_keys突增,但没查到大 key 或慢日志报警 - 应用层批量预热缓存(如凌晨商品列表加载)后,紧接着出现大量缓存 miss 和 DB 压力飙升
关键点在于:淘汰不是发生在 PIPELINE 执行中,而是在它执行完、内存统计刷新后立刻触发。Redis 每次执行完一批命令,会检查当前内存是否超限,一旦超,马上按策略选 key 删除。
为什么 PIPELINE 容易让 LFU/LRU 误判热 key
allkeys-lfu 或 volatile-lru 依赖访问频次或时间戳做淘汰决策,但 PIPELINE 中的写入操作不会更新 key 的 LFU 计数器或 LRU 时间戳——只有读操作(GET)或带访问语义的写(如 INCR)才会。这意味着:
- 你用
PIPELINE一口气写入 1 万个新 key,它们的 LFU 初始值都是 1,且无历史访问记录 - 下一轮淘汰采样时,这 1 万个 key 在
maxmemory-samples(默认仅 5)里被随机抽中概率极高 - 结果就是:刚写入的“潜在热 key”被当成冷数据删掉,而真正不常访问的老 key 因为有历史计数反而留下
这就是为什么生产环境必须把 maxmemory-samples 调高到 10~20:不是为了更准,而是为了降低随机偏差对批量写入的误伤。
使用位于 ci-tools.xrow.de 的 CI Tools 组件目录构建和维护 GitLab CI/CD 流水线,适用于创建或修复 .gitlab-ci.yml 文件,选择合适的组件。
PIPELINE + 大 value 是双重暴击
单个大 value(比如 1MB 的 JSON 字符串)在 PIPELINE 中写入时,不仅占内存多,还会带来三重压力:
- 主线程分配内存时间变长,阻塞后续命令处理
- RDB/AOF 持久化时需完整拷贝该 value,延长 fork 后的写时复制(COW)时间
- 淘汰时若选中这个 key,同步删除会卡住主线程;必须开启
lazyfree-lazy-eviction yes,否则一次淘汰就拖慢整条 pipeline 的响应
验证方式很简单:用 redis-cli --bigkeys 扫描,重点关注 string 类型中 size > 100KB 的 key。这类 key 一旦进 PIPELINE,基本就是淘汰风暴的导火索。
别只盯 pipeline,要管住写入节奏和 TTL 设计
单纯优化 PIPELINE 包大小或拆分批次,解决不了根本问题。真正要控制的是「单位时间写入的数据量」和「这些数据的生存周期」:
- 避免所有 key 设置相同 TTL(例如全部
EXPIRE key 3600),必须加随机偏移,哪怕 ±300 秒也能显著摊平淘汰压力 - 对预热类批量写入,优先用
SET key value EX 3600而非先SET再EXPIRE—— 减少命令数,也避免中间状态被误淘汰 - 如果业务允许,把部分低频配置类 key 改用
allkeys-lfu+ 不设 TTL,比依赖volatile-*更稳;漏设 TTL 不再是致命错误
最易被忽略的一点:从节点不参与淘汰决策,但主节点淘汰后会发 DEL 命令给从节点。如果你的读流量部分打到从节点,而它还没来得及同步删除,就会短暂返回已淘汰的旧值——这不是 bug,是机制使然,敏感逻辑必须在应用层校验时间戳或版本号。










