当前位置: 首页 > article >正文

Redis数据库篇 -- Pipeline

一. 什么是Pipeline

在传统的请求-响应模式中,客户端与服务器之间的通信流程如下:

  1. 客户端发送一个命令到服务器。
  2. 服务器接收命令并执行。
  3. 服务器将执行结果返回给客户端。
  4. 客户端接收结果后,发送下一个命令
    在这里插入图片描述

在这种传统的模式下,每个命令都需要经历完整的 RTT,这在高延迟网络环境下会导致显著的性能瓶颈。

Redis Pipeline 是一种批量执行命令的技术,允许客户端在不等待服务器响应的情况下,一次性发送多个命令到 Redis 服务器。它通过消除或减少网络往返次数(Round-Trip Time, RTT),能够显著提高命令执行的吞吐量,客户端可以将多个命令打包发送,服务器则依次执行这些命令并将结果返回给客户端,从而有效地提升了网络利用率和整体性能。

Pipeline 工作流程可以总结成下面 5个步骤:

打包命令: 客户端将多个 Redis 命令按照特定的格式打包成一个请求包。
发送命令: 将打包好的请求一次性发送给 Redis 服务器。
执行命令: Redis 服务器按顺序执行接收到的所有命令。
接收响应: 服务器将所有命令的执行结果按顺序返回给客户端。
解析响应: 客户端解析接收到的响应,并将结果对应到各个命令。
在这里插入图片描述
这种方式通过减少网络往返次数,有效降低网络延迟对性能的影响,特别适合于需要执行大量 Redis 命令的高并发场景。

尽管 Pipeline带来了性能的提升,但它也有一些缺点:
1.资源消耗: 发送大量命令一次性执行,可能会消耗较多的服务器资源,导致 Redis 其他操作的响应时间增加。
2.错误处理复杂: 在批量执行命令时,单个命令的错误处理可能变得复杂,需要逐一检查每个命令的执行结果。
3.顺序依赖: 如果命令之间存在顺序依赖,Pipeline 的批量执行需要确保正确的命令顺序。
4.不支持事务功能: Pipeline 只是批量执行命令的工具,不具备事务的原子性和隔离性

二. Pipeline与非Pipeline性能对比

下面用Jedis客户端来对比Pipeline与非Pipeline模式下查询Hash类型数据性能。

import com.utils.DataImportToRedisUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import java.util.List;

public class RedisPipeLineTest {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.47.130", 6379);
        jedis.auth("Admin123!");
        jedis.select(0);

        int execTimes = 10000;
        long start = System.currentTimeMillis();
        for (int i = 0; i < execTimes; i++) {
            long ipScore = DataImportToRedisUtils.ipv4ToLong("1.0.32.0");
            String blockedIps = jedis.hget("blockedIps", "52.228.155.178");
        }
        long end = System.currentTimeMillis();
        System.out.println("the jedis total time is:" + (end - start));

        Pipeline pipe = jedis.pipelined(); // 先创建一个 pipeline 的链接对象
        long start_pipe = System.currentTimeMillis();
        for (int i = 0; i < execTimes; i++) {
            pipe.hget("blockedIps", "52.228.155.178");
        }
        List<Object> res = pipe.syncAndReturnAll(); // 获取所有的 response
        long end_pipe = System.currentTimeMillis();
        System.out.println("the pipe total time is:" + (end_pipe - start_pipe));
    }
}

运行结果:

the jedis total time is:3920
the pipe total time is:45

从运行结果可以看出,Pipeline比非Pipeline性能可以提升不少


http://www.kler.cn/a/538190.html

相关文章:

  • 利用二分法进行 SQL 盲注
  • C++20新特性
  • 继承(python)
  • 【算法】【高精度】acwing算法基础 794. 高精度除法
  • RabbitMq入门
  • 黑马React保姆级(PPT+笔记)
  • 【0404】Postgres内核 实现分配一个新的 Object ID (OID)
  • Python如何实现名称为”000-“~“999-”文件的自动生成,且后缀名可以自定义
  • 基于SeaTunnel同步数据
  • 使用Jenkins实现鸿蒙HAR应用的自动化构建打包
  • COBOL语言的云计算
  • 基于HTML、CSS 和 JavaScript 开发个人读书类网站
  • uniapp中使用uCharts折线图X轴数据间隔显示
  • 基于python多线程多进程爬虫的maa作业站技能使用分析
  • Python----Python高级(网络编程:网络基础:发展历程,IP地址,MAC地址,域名,端口,子网掩码,网关,URL,DHCP,交换机)
  • 【爬虫开发】爬虫开发从0到1全知识教程第13篇:scrapy爬虫框架,介绍【附代码文档】
  • <tauri><rust><GUI>基于rust和tauri,在已有的前端框架上手动集成tauri示例
  • RabbitMQ 消息顺序性保证
  • 多线程下jdk1.7的头插法导致的死循环问题
  • 学JDBC 第二日
  • OSwatch性能分析工具部署
  • 为什么要学习AI/机器学习
  • 2025年02月07日Github流行趋势
  • vnev/Scripts/activate : 无法加载文件
  • 深度学习之DCGAN算法深度解析
  • 微服务组件LoadBalancer负载均衡