06.2 - Pipeline 与批量操作
定位: 通过批量发送命令减少网络开销,大幅提升 Redis 吞吐性能 面试高频度: ⭐⭐⭐⭐ 考查方式: Pipeline 原理、与事务(MULTI)区别、批量大小控制
一、核心原理
二、实战验证
2.1 Pipeline 性能对比
bash
# 无 Pipeline
redis-benchmark -n 100000 -t SET -P 1 -q
# SET: 125000.00 requests per second
# Pipeline=100
redis-benchmark -n 100000 -t SET -P 100 -q
# SET: 5600000.00 requests per second ← 45x 提升
# Pipeline=200
redis-benchmark -n 100000 -t SET -P 200 -q
# SET: 6800000.00 requests per second
# Pipeline=500
redis-benchmark -n 100000 -t SET -P 500 -q
# SET: 7000000.00 requests per second ← 边际递减
# Pipeline=1000(注意:可能引起输出缓冲区满)
redis-benchmark -n 100000 -t SET -P 1000 -q
# error: 可能触发 client-output-buffer-limit2.2 Pipeline 大小选择
bash
# 不同 Pipeline 大小的效果对比(网络延迟 ~1ms)
# Pipeline 1(逐个):10000 次
time for i in $(seq 1 1000); do
redis-cli SET "k:$i" "v:$i" > /dev/null
done
# ~10 秒 (1000 × RTT 1ms = 1 秒 + 执行时间)
# Pipeline 100:1000 次
python3 -c "
import redis
r = redis.Redis()
pipe = r.pipeline()
for i in range(1000):
pipe.set(f'k:{i}', f'v:{i}')
pipe.execute()
"
# ~0.1 秒 (1 × RTT 1ms + 1000 × 1μs)
# 推荐大小:50-200(平衡延迟和内存)2.3 Pipeline vs 事务(MULTI)
Pipeline ≠ 事务
| 维度 | Pipeline | MULTI/EXEC(事务) |
|---|---|---|
| 主要目的 | 减少网络 RTT | 保证原子性 |
| 中间结果可视 | 是(可以读中间结果) | 否(EXEC 前排队) |
| 原子性 | 不保证 | 保证(被 EXEC 包裹) |
| 错误处理 | 不影响其他命令 | 语法错误 → 全部取消 |
| 是否阻塞 | 否(逐条执行) | 否(但 EXEC 前排队) |
| 可以混合使用 | Pipeline 里套事务 | 事务里不能用 Pipeline |
最佳实践:Pipeline + 事务
python
pipe = r.pipeline()
pipe.multi() # 开启事务
pipe.set('a', 1)
pipe.incr('b')
pipe.execute() # 批量发送 + 原子执行2.4 原生批量命令
如果只是简单操作,优先使用原生命令(比 Pipeline 更高效):
命令 替代
──── ──
MSET/MSETNX 多个 SET
MGET 多个 GET
DEL key1 key2... 多个 DEL
EXISTS k1 k2... 多次 EXISTS
SADD set a b c 逐个 SADD
HDEL hash f1 f2 逐个 HDEL
但 Pipeline 在混合不同类型命令时更灵活:
GET a
SET b 1
LPUSH list c
ZADD zset 1 d
→ 无法用原生命令组合三、面试视角
| 追问 | 答案要点 |
|---|---|
| Pipeline 和 MULTI/EXEC 的区别? | Pipeline 减少 RTT(非原子),MULTI 保证原子性(非减少 RTT);可以一起用 |
| Pipeline 大小怎么选? | 推荐 50-200;太小效果不明显,太大会占用输出缓冲区、增加延迟 |
| Pipeline 会阻塞 Redis 吗? | 不会。Pipeline 命令逐个执行,只是客户端不等待。但大量命令+大返回会占输出缓冲区 |
| Pipeline 的适用场景? | 批量数据导入、缓存预热、批量更新;延迟敏感的场景不适合(需逐条确认) |
| Pipeline 一定比逐条发送快吗? | 在网络延迟高时特别明显(跨机房提升 10-50x),本地测试提升 ~2-5x |
| Pipeline 的注意事项? | 控制批次大小、监控输出缓冲区、Pipeline 中的命令有先后顺序吗(有,按发送顺序) |
📚 相关链接
- **RESP 协议** — Pipeline 在协议层的实现
- **Lua 脚本** — Lua 脚本比 Pipeline 更强的原子性
- ← 返回 **性能优化与运维索引**