Redis 管道技术——Pipeline

背景

面试官:Redis 管道技术pipeline用过吗?为什么要用?解决什么问题?使用过程中应该注意什么?

我:一键三连,内心gg了,没听说过,也不知道用来干什么的,我只能说,没了解过

Redis大多数人都用过,说起来头头是道,但是说到redis的管道技术还是很陌生,第一次我听到的时候也是一脸懵,查询官方文档Pipeline才了解它是是什么,用来解决什么问题。说白了就是批量执行redis的命令

什么是Redis pipelining

Redis 流水线是一种通过一次发出多个命令而无需等待每个命令的响应来提高性能的技术,

通过批处理 Redis 命令来优化往返时间

往返时间

Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:

  • 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。
  • 服务端处理命令,并将结果返回给客户端。

请求流程如图:

客户端和服务器通过网络链接连接。这样的链接可以非常快(环回接口)或非常慢(通过互联网建立的连接,在两台主机之间有很多跃点)。无论网络延迟是多少,数据包从客户端传输到服务器,以及从服务器返回客户端以携带回复都需要时间这个时间称为RTT(往返时间)。当客户端需要连续执行许多请求时(例如,将许多元素添加到同一个列表中,或者使用许多键填充数据库),很容易看出这会如何影响性能。例如,如果 RTT 时间为 250 毫秒(在 Internet 链接速度非常慢的情况下),即使服务器每秒能够处理 100k 个请求,我们也能够每秒最多处理 4 个请求。

那有什么办法优化呢?redis的pipelining 进行批处理

流程如下:

可以实现请求/响应服务器,以便即使客户端尚未读取旧响应,它也能够处理新请求。这样就可以向服务器发送多个命令,而无需等待回复,并最终一步读取回复。

这次我们不再为每次调用支付 RTT 成本,而是为三个命令支付一次 RTT 成本。

重要提示:当客户端使用管道发送命令时,服务器将被迫使用内存对回复进行排队。因此,如果您需要通过管道发送大量命令,最好将它们分批发送,每个批次包含合理的数量,例如 10k 个命令,读取回复,然后再次发送另外 10k 个命令,依此类推。速度几乎相同,但使用的额外内存最多是对这 10k 命令的回复进行排队所需的内存量

I/O开销

管道化不仅仅是减少与往返时间相关的延迟成本的一种方法,它实际上极大地提高了给定 Redis 服务器中每秒可以执行的操作数量。这是因为,如果不使用管道,从访问数据结构和生成回复的角度来看,服务每个命令的成本非常低,但从执行套接字 I/O 的角度来看,成本却非常高。这涉及到调用 read()write() 系统调用,这意味着从用户态到内核态。上下文切换会带来巨大的速度损失。

使用管道时,通常使用单个 read() 系统调用读取许多命令,并使用单个 write() 系统调用传递多个回复。因此,每秒执行的总查询数最初随着管道的延长而几乎呈线性增加,最终达到没有管道化时获得的基线的 10 倍,如图所示。

管道技术解决了什么问题?

管道技术解决了多个命令集中请求时造成网络资源浪费的问题,加快了 Redis 的响应速度,让 Redis 拥有更高的运行速度。但要注意的一点是,管道技术本质上是客户端提供的功能,而非 Redis 服务器端的功能。

管理技术的使用场景

原则上有批量执行的需求都可以用,前后执行的命令没有因果关系。我举几个我平时用到的场景:

  1. 项目上线后,缓存预测,如果执行的命令比较多,就可以使用管理技术
  2. redis优化,发现大量的key不在使用,同时没有过期时间,那我就要删掉这些key,如果使用管理技术批量删除,大大提高我的效率

管道技术需要注意的事项

管道技术虽然有它的优势,但在使用时还需注意以下几个细节:

  • 发送的命令数量不会被限制,但输入缓存区也就是命令的最大存储体积为 1GB,当发送的命令超过此限制时,命令不会被执行,并且会被 Redis 服务器端断开此链接;
  • 如果管道的数据过多可能会导致客户端的等待时间过长,导致网络阻塞,分批执行,不要一把梭哈,造成不必须要的事故
  • 部分客户端自己本身也有缓存区大小的设置,如果管道命令没有没执行或者是执行不完整,可以排查此情况或较少管道内的命令重新尝试执行。

管道技术使用

使用 Jedis 客户端提供的 Pipeline 对象来实现管道技术。首先获取 Pipeline 对象,再为 Pipeline 对象设置需要执行的命令,最后再使用 sync() 方法或 syncAndReturnAll() 方法来统一执行这些命令

代码如下:

public static void main(String[] args) {
        Jedis jedis = new Jedis("10.1.250.157", 6379);
        jedis.auth("google00");
        // 记录执行开始时间
        long beginTime = System.currentTimeMillis();
        // 获取 Pipeline 对象
        Pipeline pipe = jedis.pipelined();
        // 设置多个 Redis 命令
        for (int i = 0; i < 1000; i++) {
            pipe.set("key" + i, "val" + i);
            pipe.del("key" + i);
        }
        // 执行命令
        pipe.sync();
        // 记录执行结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("执行耗时:" + (endTime - beginTime) + "毫秒");
    }

执行结果:

执行耗时:102毫秒

如果要接收管道所有命令的执行结果,可使用 syncAndReturnAll() 方法,示例代码如下:

 public static void main(String[] args) {
        Jedis jedis = new Jedis("10.1.250.157", 6379);
        jedis.auth("google00");
        // 记录执行开始时间
        long beginTime = System.currentTimeMillis();
        // 获取 Pipeline 对象
        Pipeline pipe = jedis.pipelined();
        // 设置多个 Redis 命令
        for (int i = 0; i < 1000; i++) {
            pipe.set("key" + i, "val" + i);
            pipe.del("key" + i);
        }
        // 执行命令并返回结果
        List<Object> res = pipe.syncAndReturnAll();
        for (Object obj : res) {
            // 打印结果
            System.out.println(obj);
        }
        // 记录执行结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("执行耗时:" + (endTime - beginTime) + "毫秒");
    }

执行结果:

OK
1
OK
1
OK
1

执行耗时:103毫秒

如果不使用管理技术,效果如何?

public static void main(String[] args) {
        Jedis jedis = new Jedis("10.1.250.157", 6379);
        jedis.auth("google00");
        // 记录执行开始时间
        long beginTime = System.currentTimeMillis();
        // 单个 执行Redis 命令
        for (int i = 0; i < 1000; i++) {
            jedis.set("key" + i, "val" + i);
            jedis.del("key" + i);
        }
        // 记录执行结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("执行耗时:" + (endTime - beginTime) + "毫秒");
    }

执行结果:

执行耗时:745毫秒

从结果看,2000个命令,管道执行需要103毫秒,普通执行需要745毫秒,70倍的速度,如果命令更多,效果更明显。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/362420.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ //练习 3.10 编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分。

C Primer&#xff08;第5版&#xff09; 练习 3.10 练习 3.10 编写一段程序&#xff0c;读入一个包含标点符号的字符串&#xff0c;将标点符号去除后输出字符串剩余的部分。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /**…

Pycharm 关闭/退出烦人的Pytest模式

Pycharm 遇到&#xff1a;Run Python tests in ***.py &#xff0c;但很多时候我们并不需要&#xff0c;真心烦人&#xff01; 如何解决: 1 打开File-Settings &#xff08;图片是新版界面&#xff0c;旧版同样操作&#xff09; 2 Tools 中的Python Integrated Tools 在Tes…

[office] excel2010双向条形图制作 #经验分享#微信

excel2010双向条形图制作 本教程为大家介绍一下excel2010中excel2010双向条形图制作方法。 1.选中工作区域 2.点击插入-->图表,选择条形图 3.为美观可将中间竖线可去掉 4.方法是选中竖线,右击-->删除 5.接下来将图例靠上,选中图例,右击-->设置图例格式-->图例选项…

独立按键控制LED(基于51单片机)

师从江科大 独立按键 轻触按键&#xff1a; 相当于是一种电子开关&#xff0c;按下开关接通&#xff0c;松开开关断开&#xff0c;实现原理是通过轻触按键内部的金属弹片受力弹动来实现接通好和断开 独立按键原理图&#xff1a; 注&#xff1a;没有按下独立按键是高电平&am…

对同一文件多次mmap

abstract 问&#xff1a;对同一个文件多次mmap&#xff0c;返回的地址相同吗? 答&#xff1a;不相同 code #ifdef __linux__#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> …

1.D支撑线

从时间复杂度上来看&#xff0c;极点是O(n4)&#xff0c;极边是O(n3)&#xff0c;那么&#xff0c;还有没有可能使时间复杂度更小呢&#xff1f; 如上图所示将外部点X加入到原凸包&#xff0c;&#xff08;即S黄Vt蓝V所在的凸包&#xff09;那么可以观察到&#xff0c;将会组成…

【Java程序设计】【C00205】基于(JavaWeb+SSM)的商场停车服务管理系统(论文+PPT)

基于&#xff08;JavaWebSSM&#xff09;的商场停车服务管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于ssm的商场停车服务管理系统 本系统分为管理员和用户2个功能模块。 管理员&#xff1a;管理员进入主页面&…

网络协议与攻击模拟_12DNS协议及Windows部署DNS服务器

1、了解域名的结构 2、DNS查询过程 3、Windwos server部署DNS服务器 4、分析流量 实施DNS欺骗 再分析 一、DNS域名系统 1、DNS简介 DNS&#xff08;Domain Name system&#xff09;域名系统&#xff0c;作为将域名的IP地址的相互映射关系存放在一个分布式的数据库&#xff0c…

二分查找-迭代法

Go 算法 每天5道&#xff0c;开心快乐每一天 一点都不开心 哈哈哈哈哈哈 -2.1 day 1 1.22&#xff08;1.23 1.25 1.29&#xff09; 1.23 已复习 704. 二分查找 力扣题目链接 //左闭右开 func search(nums []int, target int) int { right : len(nums) left : 0; for le…

6个AI写作工具,让你的文字变得生动有力

写作是一项需要耐心和技巧的任务&#xff0c;对于许多人来说&#xff0c;写作可能是一项困难的挑战。然而&#xff0c;随着人工智能的发展&#xff0c;AI智能写作软件逐渐崭露头角&#xff0c;为我们提供了更加便捷和高效的写作体验。在本文中&#xff0c;我们将介绍几款好用的…

算法练习01——哈希部分双指针

目录 1. 两数之和(*)242. 有效的字母异位词(easy)49. 字母异位词分组(*)349. 两个数组的交集202. 快乐数(1.使用Set存哈希&#xff0c;2.快慢指针)454. 四数相加 II383. 赎金信15. 三数之和*(双指针)18. 四数之和*(双指针)128. 最长连续序列 1. 两数之和(*) https://leetcode.…

边缘计算网关在智能制造中有哪些应用?-天拓四方

在智能制造和工业生产环境中&#xff0c;数据已经成为新的生产要素&#xff0c;工业生产对实时性、灵活性和智能化也提出了更高的要求。而在这个过程中&#xff0c;边缘计算网关发挥着不可或缺的作用。它作为设备层与网络层之间的关键桥梁&#xff0c;确保了数据的实时、高效处…

STM32F407移植OpenHarmony笔记6

继上一篇笔记&#xff0c;编译好STM32的裸机程序&#xff0c;能点亮LED灯了。 下一步就是启动liteos_m内核了。 不过为了更好的调试代码&#xff0c;需要先把printf重定向到串口&#xff0c;基于gcc的printf重定向和Keil不一样。 直接新建printf.c&#xff0c;在里面重写printf…

基于 NOVATEK NT98530 Multiview Stitching 应用解决方案

感测技术近来于影像监控系统应用有了进一步的发展&#xff0c;多镜头的应用也与日俱增&#xff0c;如 AI 视觉感测会议相机&#xff0c;能满足远端多人聚会、远距教育训练的多元需求等&#xff0c;相关应用层面广泛涵盖了在生活中所面对的各种场景&#xff0c;带动更加可观的潜…

【安装指南】nodejs下载、安装与配置详细教程

目录 &#x1f33c;一、概述 &#x1f340;二、下载node.js &#x1f337;三、安装node.js &#x1f341;四、配置node.js &#x1f33c;一、概述 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时&#xff0c;用于构建可扩展的网络应用程序。Node.js 使用事件驱动、…

各品牌主板快速启动热键对照表及CMOS进入方法

各品牌主板快速启动热键对照表 主板品牌 启动按键 笔记本品牌 启动按键 主机品牌 启动按键 华硕主板 F8 联想笔记本 F12 联想台式机 F12 技嘉主板 F12 宏碁笔记本 F12 惠普台式机 F12 微星主板 F11 华硕笔记本 ESC 宏碁台式机 F12 梅捷主板 F9 惠普笔…

机器学习数学基础

机器学习基础 1、标量、向量、矩阵、张量2、概率函数、概率分布、概率密度、分布函数3、向量的线性相关性4、最大似然估计5、正态分布(高斯分布)6、向量的外积(叉积)7、向量的内积(点积)8、超平面(H)1、标量、向量、矩阵、张量 标量、向量、矩阵和张量是线性代数中不同…

Java基础学习:System类和Static方法的实际使用

一、System类 1.在程序开发中&#xff0c;我们需要对这个运行的结果进行检验跟我们预判的结果是否一致&#xff0c;就会用到打印结果在控制台中显示出来使用到了System类。System类定义了一些和系统相关的属性和方法&#xff0c;它的属性和方法都是属于静态的&#xff0c;想使用…

win11安装wsl作为linux子系统并当作服务器

wsl安装 打开控制面板&#xff0c;找到启用或关闭windows功能 开启windows虚拟机监控平台和适用于Linux的Windows子系统&#xff0c;重启电脑。 打开microsoft store搜索ubuntu&#xff0c;找到合适的版本下载安装 输入wsl -l如下所示&#xff0c;即为安装成功。 安装过程比较…

怎么进行视频压缩大小?常见的4种压缩方法

在当今数字化的时代&#xff0c;我们经常处理大量的视频文件&#xff0c;无论是用于社交媒体分享、视频制作还是存储在我们的设备中。然而&#xff0c;随着视频质量的提升和分辨率的增加&#xff0c;视频文件的大小也相应地变得更加庞大&#xff0c;给存储、分享和传输带来了一…