首页 > 数据库 >Redis 7.x 系列【19】管道

Redis 7.x 系列【19】管道

时间:2024-07-05 14:57:04浏览次数:13  
标签:19 Redis 命令 管道 pipelined 服务端 客户端

有道无术,术尚可求,有术无道,止于术。

本系列Redis 版本 7.2.5

源码地址:https://gitee.com/pearl-organization/study-redis-demo

文章目录

1. 往返时间

官方文档

Redis 是一种基于 CS 模型以及请求/响应协议的TCP服务。通常情况下一个请求会遵循以下步骤:

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

例如,一个客户端发送四次命令的流程如下所示:
在这里插入图片描述
客户端和服务端之间通过网络进行连接通信,无论网络延迟如何,数据包从客户端到服务端的传输,以及从服务端回到客户端的响应,都需要一定的时间,这段时间被称为往返时间RTT)。

当客户端需要连续执行许多请求时,例如向同一列表添加多个元素或者将数据库填充多个键,往返时间如何影响性能就很容易理解了。例如,如果往返时间为250毫秒(非常慢的连接),即使服务端能够每秒处理10万个请求,客户端每秒也只能发送四个请求。

2. 管道技术

对于上述问题,Redis 提供了管道(Plpeline)技术,允许客户端将多个命令一次性发送给服务器,而不需要等待每个命令的回复。这样可以减少每条命令的网络延迟时间,特别适合需要发送大量命令的场景。

执行流程如下所示:
在这里插入图片描述

管道技术不仅减少了 RTT ,并且极大地提升了在 Redis 服务器上每秒可以执行的操作数量。

使用注意事项:

  • 使用管道时,命令只是会依次以行,不保证原子性,如果其中某个命令令发生异常,将会继续执行
  • 组装的命令个数不能太多,不然数据量太大时,客户端阻塞的时间可能过久,同时服务端此时也被迫回复一个队列答复,占用很多内存
  • 需要发送大量的命令时,需要按照合理数量分批次的处理,例如一次发送10K的命令,读取回复后,后再发送另一个10k的命令。

3. 代码演示

下面代码中,使用 Jedis 插入 10000Key

    public static void main(String[] args) {
        // 创建连接池
        JedisPool pool = new JedisPool("localhost", 6379,"default","123456");
        // 获取客户端
        try (Jedis jedis = pool.getResource()) {

            // 1. 不使用管道, 插入 10000 个 Key
            long startTime = System.currentTimeMillis();
            for (int i = 10000; i > 0; i--) {
                jedis.set("key" + i, String.valueOf(i));
            }
            System.out.println("不使用管道执行时间:" + ( System.currentTimeMillis()-startTime)+"毫秒");

            // 2. 使用管道
            startTime = System.currentTimeMillis();
            Pipeline pipelined = jedis.pipelined();
            for (int i = 10000; i > 0; i--) {
                pipelined .set("key" + i, String.valueOf(i));
            }
            System.out.println("使用管道执行时间:" + ( System.currentTimeMillis()-startTime)+"毫秒");
        }
    }

可以看到,在使用了管道后,执行时间缩短了近 30 倍:

不使用管道执行时间:793毫秒
使用管道执行时间:26毫秒

对于查询命令,当然也可以使用管道,不过结果值是批量返回的:

            Pipeline pipelined = jedis.pipelined();
            for (int i = 10000; i > 0; i--) {
                //pipelined .set("key" + i, String.valueOf(i));
                pipelined.get("key" + i);
            }
            // 获取执行结果
            List<Object> results = pipelined.syncAndReturnAll();

4. 其他批处理

除了管道, Redis 还提供了其他批处理方式,可以根据具体需求选择合适的方式来操作 Redis

4.1 原生批处理命令

Redis 提供了两个常用的原生命令来处理多个键的操作:

  • MGET: 同时获取多个键的值
  • MSET: 同时设置多个键的值

MGETMSET 命令都是原子操作,即要么全部执行成功,要么全部执行失败。适合于需要一次性获取或设置多个键值对的场景。

示例:

MGET key1 key2 key3
MSET key1 value1 key2 value2 key3 value3

4.2 事务

通过事务机制,可以将多个命令打包在一起执行,事务中的所有命令要么全部执行,要么全部不执行。

示例:

MULTI
SET key1 value1
GET key2
INCR key3
EXEC

4.3 脚本

通过 Redis 脚本,可以将多个命令打包成一个原子操作,确保在执行期间不会被其他命令打断。

示例:

local result1 = redis.call('SET', KEYS[1], ARGV[1])
local result2 = redis.call('GET', KEYS[2])
local result3 = redis.call('INCR', KEYS[3])
return {result1, result2, result3}

标签:19,Redis,命令,管道,pipelined,服务端,客户端
From: https://blog.csdn.net/qq_43437874/article/details/139666943

相关文章

  • 安装Redis出现的问题
    当我使用brew下载redis时系统:macOS14$brewinstallredis报错信息:Error:git:unknownorunsupportedmacOSversion::dunnoError:'git'mustbeinstalledandinyourPATH!Warning:YouareusingmacOS14.Wedonotprovidesupportforthispre-releaseve......
  • Redis快速上手
    Redis检查Redis是否安装$redis-server--versionRedisserverv=7.2.4sha=00000000:0malloc=libcbits=64build=2d86b7859915655e如果成功安装,则会显示Redis的版本号。启动RedisMac:终端输入:$redis-serverWin:终端输入:$redis-server.exe启动后显示版本号和端口......
  • 【SPIE 独立出版 | 高录用稳检索 | 过往4届均已检索】第五届计算机视觉和数据挖掘国际
    第五届计算机视觉与数据挖掘国际学术会议(ICCVDM2024)将于2024年7月19-21日在中国长春举行。此前,ICCVDM系列会议于2020年在中国西安、2021年在中国长沙(线上)、2022年在中国呼伦贝尔(线上+线下)、2023年在中国长春(线上+线下)皆已成功举办。ICCVDM为世界各地该领域的专家、学者......
  • Redis数据结构-字典的实现
    字典,又称符号表(symboltable)、关联数组(associativearray)或者映射(map),是一种用于保存键值对(key-valuepair)的抽象数据结构。在字典中,一个键(key)可以和一个值(value)进行关联(或者说将键映射为值),这些关联的键和值就被称为键值对。字典中的每个键都是独一无二的,程序可以在字典......
  • 谷粒商城学习-11-docker安装redis
    文章目录一,拉取Redis镜像1,搜索Redis的Docker镜像2,拉取Redis镜像3,查看已经拉取的镜像二,创建、启动Redis容器1,创建redis配置文件2,创建及运行Redis容器3,使用dockerps查看运行状态的容器4,验证容器是否可用三,修改Redis配置文件一,拉取Redis镜像1,搜索Redis的Docker镜像......
  • 代码随想录算法训练营第十三天|今天量大管饱144、145、94、102、107、199、637、429、
    今天来处理二叉树part1、2、3,顶级享受,一次到位。完全二叉树和满二叉树概念没问题。二叉搜索树,左子树所有结点的值小于它的根结点的值,右子树上所有结点的值大于它的根结点的值平衡二叉搜索树,它是一棵空树或它的左右两个子树的高度差的绝对值不超过1。二叉树的存储方式:链式存储......
  • Redis详解
    Redis是一个开源的内存数据库,它属于NoSQL数据库的一种,以其高性能、支持丰富的数据结构、持久化特性、复制、集群以及发布/订阅等特性而闻名。以下是Redis的详细说明:一、Redis的基本介绍定义:Redis(RemoteDictionaryServer)是一个高性能的键值对存储系统,它可以用于缓存、消息队......
  • 基于Go1.19的站点模板爬虫
    要基于Go1.19创建一个站点模板爬虫,你可以使用Go语言的标准库和一些第三方库(如colly或goquery)来实现网页抓取和解析。以下是一个简单的示例,展示了如何使用colly库编写一个站点模板爬虫:安装Colly库:首先,确保你已经安装了Go,并设置好了Go的工作环境。然后使用以下命令安装col......
  • China.NETConf2019 - 用ASP.NETCore构建可检测的高可用服务
    一、前言2019中国.NET开发者峰会(.NETConfChina2019)于2019年11月10日完美谢幕,校宝在线作为星牌赞助给予了峰会大力支持,我和项斌等一行十位同事以讲师、志愿者的身份公司参与到峰会的支持工作中,我自己很荣幸能够作为讲师与大家交流,分享了主题《用ASP.NETCore构建可检测的高......
  • Redis 中如何让消息永不过期
    在Redis中,如果想要让消息(或任何键)永不过期,可以通过以下方式实现:1.不设置过期时间默认情况下,Redis中的键是永不过期的,除非明确为其设置了过期时间。因此,只要在设置键值时不使用任何过期时间相关的命令,键值就会一直保存在Redis中。示例SETmyKeymyValue在上面的示例中,......