Redis的Pipeline (管道)

Pipeline 是一种客户端优化技术。它允许客户端一次性发送多个命令,而不需要等待每个命令的响应,最后一次性读取所有响应。这大大减少了网络往返时间 (RTT)。

python 复制代码
import redis
import time

# 连接 Redis
r = redis.Redis(host='XX.XX.XX.XX', port=6379, password='123456', socket_timeout=2, db=0)

def without_pipeline():
    start = time.time()
    for i in range(1000):
        r.set(f'key_{i}', i)
        r.delete(f'key_{i}')
    end = time.time()
    print(f"Without Pipeline: {end - start:.4f} seconds")

def with_pipeline():
    start = time.time()
    pipe = r.pipeline()
    for i in range(1000):
        pipe.set(f'key_{i}', i)
        pipe.delete(f'key_{i}')
    # 一次性发送所有命令
    pipe.execute()
    end = time.time()
    print(f"With Pipeline:    {end - start:.4f} seconds")

if __name__ == "__main__":
    print("Running Pipeline Benchmark (1000 ops)...")
    try:
        r.ping()
        without_pipeline()
        with_pipeline()
    except redis.ConnectionError:
        print("Error: Could not connect to Redis. Please ensure Redis is running.")

这个程序是一个Redis管道(Pipeline)的性能对比演示,它展示了使用管道和不使用管道在性能上的巨大差异。

程序的功能详解:

1. 程序目的

比较在Redis中执行批量操作时,使用管道和不使用管道的性能差异。

2. 具体操作

  • 进行1000次操作(设置键值对 + 删除键值对)
  • 每次循环执行两个操作:
    1. SET key_i i - 设置键值对
    2. DELETE key_i - 删除刚刚设置的键

3. 两种模式的对比

不使用管道的情况 (without_pipeline()):
复制代码
for i in range(1000):
    r.set(f'key_{i}', i)      # 第1次网络往返
    r.delete(f'key_{i}')      # 第2次网络往返

过程:

  • 每次set()delete()都是独立请求
  • 需要2000次网络往返(1000个set + 1000个delete)
  • 每个命令都等待Redis响应后才发送下一个命令
  • 总耗时:43.99秒
使用管道的情况 (with_pipeline()):
复制代码
pipe = r.pipeline()          # 创建管道对象
for i in range(1000):
    pipe.set(f'key_{i}', i)  # 添加到管道队列
    pipe.delete(f'key_{i}')  # 添加到管道队列
pipe.execute()               # 一次性发送所有命令

过程:

  • 所有命令先缓存在本地队列中
  • 最后调用execute()一次性发送给Redis
  • 只需要1次网络往返
  • Redis批量执行所有命令,然后一次性返回所有结果
  • 总耗时:0.0645秒

4. 性能差异的原因

|---------|----------|-----------|
| 对比项 | 不使用管道 | 使用管道 |
| 网络往返次数 | 2000次 | 1次 |
| 网络延迟影响 | 每次操作都要等待 | 只等待一次 |
| 带宽利用率 | 低 | 高(命令批量发送) |
| Redis处理 | 逐个处理 | 批量处理 |

5. 实际运行结果解读

复制代码
Without Pipeline: 43.9989 seconds
With Pipeline:    0.0645 seconds
  • 性能提升:约682倍 (43.9989 ÷ 0.0645)
  • 不使用管道:主要时间花在网络延迟
  • 使用管道:主要时间花在实际数据处理

6. 适用场景

这种性能对比特别明显是因为:

  1. 网络延迟较高 :测试连接到远程Redis服务器(10.40.50.59)
  2. 操作简单:每个操作本身执行很快
  3. 批量操作:操作数量大(1000次)

7. 实际应用意义

在实际开发中,管道技术常用于:

  • 批量数据导入/导出
  • 批量更新用户状态
  • 日志批量写入
  • 计数器批量操作
  • 任何需要执行大量Redis命令的场景

这个程序完美展示了为什么在需要执行多个Redis命令时,应该优先考虑使用管道。

相关推荐
专注API从业者5 小时前
Open‑Claw 实战|无需逆向,快速搭建电商商品监控与数据分析系统
开发语言·数据结构·数据库·数据分析·php
2301_800074215 小时前
MySQL部分语句
数据库·mysql
CodeStats5 小时前
MySQL与Oracle数据类型底层设计原理对比(下)
数据库·mysql·oracle
疯狂打码的少年5 小时前
【数据库技术】SQL高级查询(分组/排序/聚合函数)
java·数据库·笔记·sql
IvorySQL5 小时前
PostgreSQL 日报|备用服务器 FSM 数据不一致(9 月 2 日)
服务器·数据库·postgresql
sunphp开发者5 小时前
明灯智慧地图导览系统制作教程
vue·php·uniapp·js·贴图
zcmodeltech5 小时前
风力发电沙盘模型控制系统设计与灯光联动实现方案——基于STM32与Modbus RTU,服务范围覆盖全国的多场景风力发电沙盘模型定制
网络·数据库·stm32·单片机·嵌入式硬件·能源
程序员黎剑6 小时前
MySQL-JOIN优化-NLJ与BNL的区别与实战
数据库·mysql
Java小白笔记6 小时前
MyBatis XML Mapper 标签与 CRUD 原理实战
xml·数据库·mybatis
JavaPub-rodert6 小时前
一个后台系统如何同时支持 MySQL、PostgreSQL、SQLite、SQL Server?从 ShiyuAdmin 的 GORM 多数据库适配说起
数据库·mysql·postgresql