Redis Pipeline还可以这么用的

Redis Pipeline原来是这么用的 抛出,问题 最近项目碰到这么一个技术上的需求: 前端通过长轮询的机制(http long polling),获取服务端的消息数据。而服务端是需要订阅所有业务方的业务消息,再通知到给前端。 长轮询,其实简单来说,就是前端发起一个http请求,服务端把当前的请求 hang 住,直到超时或者有需要返回的内容,才return。 Apollo 配置中心就是使用这个机制实现配置的更新通知。 但有这么一种情况,假如服务端消费到消息,但此时前端与服务端的连接刚好断开了,那这个消息就没法通知到前端。 所以,我们得需 阅读详情

抛出,问题

最近项目碰到这么一个技术上的需求:

前端通过长轮询的机制(http long polling),获取服务端的消息数据。而服务端是需要订阅所有业务方的业务消息,再通知到给前端。

长轮询,其实简单来说,就是前端发起一个http请求,服务端把当前的请求 hang 住,直到超时或者有需要返回的内容,才return。 Apollo 配置中心就是使用这个机制实现配置的更新通知。

但有这么一种情况,假如服务端消费到消息,但此时前端与服务端的连接刚好断开了,那这个消息就没法通知到前端。

所以,我们得需要把服务端消费的消息保存下来,保证前端的每次发起长轮询的时候,都能拿到消息数据。

如果说,前端能直接订阅业务方的消息队列的话,那其实就没服务端什么关系了。当然,这是不允许的,前端不能连接咱们的消息中间件,并且业务方的消息数据也需要清洗处理后才能给到前端。

思考,方案

Apollo 的实现机制是,所有的配置都会写入数据库。每次请求过来,会去数据库获取是否有数据变更。

考虑到我们实际的业务场景,我们的业务消息其实时候时效性的,也就是说消息如果过期了,那其实也没用了。

要考虑轻量,我第一想到的就是 Redis Lists,利用其可以实现队列的特性,所以综合考虑最终采用 Redis 作为消息的存储模型。

优化,代码

Redis 的 Lists 数据结构,是简单的字符串链表,按插入顺序排序。可以在头部(Left)或者尾部(Right)添元素。

利用这个特性,我们可以实现队列(先进先出)的数据结构,搭配命令 rpush + lpop 或者 lpush + rpop 。

但是不管是 lpop 或是 rpop ,列表都只会弹出一个数据,没法达到我们的需求一次获取多个。

网上搜索了一下相关的解决方案,再结合官网的命令文档。

得出一种比较可行的方案: lrange + ltrim + pipeline

lrange 和 ltrim 是Redis Lists 的指令

lrange mylist 0 5

表示从队列头部(Left)开始取,下标为0,到下标为5的元素。如果是负数的话,表示队列尾部(Right)开始取。

ltrim mylist 0 5

ltrim 的含义是只保留指定范围的元素,上面的意思是,只保留列表下标为 0 - 5 的元素,其他的都会被删掉。

那如果要删掉前6条数据,就可能需要这么写:

ltrim mylist 5 -1

负数表示队列尾部(Right)开始取。

按实现来说, lrange + ltrim 就能实现从 List 获取多个元素的效果,为什么还需要用上 pipeline 呢?

其实这里有一个很显然的并发问题,这两个命令对于redis来说, 并不是原子操作 ,假如有其他线程在执行这两个命令的线程之间,删除了队列的一部分数据,那么第二个命令执行的时候,其实是list里面的数据已经是不对了。

而 Redis 的 pipeline 功能,可以解决我们上面说的这个问题。

大部分人可能对pipeline 比较陌生,因为平时业务上也很少用到。

先来看看 Redis Pipelining 的定义

A Request/Response server can be implemented so that it is able to process new requests even if the client hasn't already read the old responses. This way it is possible to send multiple commands to the server without waiting for the replies at all, and finally read the replies in a single step.

This is called pipelining, and is a technique widely in use for many decades. For instance many POP3 protocol implementations already support this feature, dramatically speeding up the process of downloading new emails from the server.

简单来说,它能够支持支持客户端一次发送多个命令,服务端接收到这些命令后,会统一按顺序处理,并且是在一个原子事务里。

显然,Pipelining 最明显的优势在于提高 client 与 server 的交互响应时间。将几个命令放在同一个请求中,和每个命令作为一个请求相比,效率是肯定提高的。

PS:这种方式,跟我为什么要获取多个list 数据的思路类似的。前端长轮询获取数据结果时,要返回多个数据。

话不多说,直接贴上示例代码:

@AutowiredRedisTemplate<String, Object> redisTemplate;public void run() throws Exception {    System.out.println("start......");    String key = "key:list";    Integer number = 5;    // 每次获取5个    List<Object> objects = redisTemplate.executePipelined(new RedisCallback<Object>() {        @Override        public Object doInRedis(RedisConnection connection) throws DataAccessException {            connection.lRange(key.getBytes(StandardCharsets.UTF_8), 0, number - 1);            connection.lTrim(key.getBytes(StandardCharsets.UTF_8), number, -1);            return null;        }    });    System.out.println(Arrays.toString(objects.toArray()));    System.out.println("end......");}

redisTemplate 提供了两种类型的方法:

  • executePipelined(RedisCallback action)
  • executePipelined(SessionCallback session)

这两者实现的功能都差不多,只不过 SessionCallback 比 RedisCallck 封装的更友好一下,后者的话更加底层,用法更加贴近与原生命令。

 

Redis Pipeline管道使用 1.Redis单条命令使用场景 Redis客户端连接到Redis服务端执行一条命令需要经历的步骤如下: 以上过程称为Round Trip Time(RTT,往返时间),mget和mset命令节约了RTT,但是大部分指令不支持批量操作。 Redis通过TCP来对外提供服务,Client通过Socket连接发起请求,每个请求在命令发出后会阻塞等待Redis服务器进行处理,处理完毕后将结果... 阅读详情

相关推荐

Redis Pipeline管道命令使用

概述 目录 1.Redis单条命令使用场景 2.Redis单条命令执行耗时 3.Redis连接池 4.Redis Pipeline管道命令的使用 5.总结 本文源码地址:https://github.com/online-demo/redis-pipeline.git 第1节 Redis单条命令使用场景 Redis客户端连接到Redis服务端执行一条命令需要经历的步骤如下: 上过程称为Round Trip Time(RTT,往返时间),mget和mset命令节约了RTT,但是大部分指令不支持批量操作

weixin_47367675的博客 1755

Redis基础面试题:Redis中的管道(Pipeline)技术及其在高并发场景下的性能优化

面试官:今天的讨论非常深入。最后,你能总结一下Pipeline的核心价值和使用建议吗?Victor:Pipeline的核心价值在于通过批量执行命令减少网络延迟,提升Redis在高并发场景下的性能。明确适用场景:Pipeline适合命令独立、对性能要求高的场景。合理设置批量大小:根据网络和服务器性能动态调整批量大小。结合其他技术:Pipeline可以与连接池、Lua脚本等技术结合,进一步提升性能。监控与调优:通过实时监控和调优,确保Pipeline的稳定性和高效性。

qq_61302385的博客 952

数字音频接口之I2S总线协议详解

1、SDATA,也就是串行数据信号,使用二进制传输数字信号。请注意数据的传输形式为补码的方式2、例如音频的采样率是8K,一s内存采样8K个点,一个点包含一个左声道,一个右声道,所以LRCK是8K,BCLK是2×采样频率×采样位数3、同时双向(TX和RX)音频流:串行数据同步移位到时钟信号SCK和LRCK。在SCK的下降沿将TX数据写入SDOUT引脚,并在SCK的上升沿从SDIN引脚读取RX数据。始终首先发送最高有效位(MSB);TX和RX均可在主模式和从模式下使用。

卓学课堂 3万+

Redis中的管道操作pipeline

在 Redis 中,Pipeline(管道)是一种客户端与服务器间通信的优化机制,旨在减少网络往返时间和提高命令执行效率。使用 Pipeline 时,客户端不再逐条发送命令,而是将多个命令一次性打包成一个请求包发送给 Redis 服务器。相应地,服务器在接收到这个请求包后,不是立即返回每条命令的执行结果,而是先将所有命令依次执行完毕,然后将所有结果打包成一个响应包返回给客户端。这种做法显著减少了客户端与服务器之间网络通信的次数,尤其是对于需要执行大量命令的场景,能够极大地降低网络延迟带来的影响。

LuckFairyLuckBaby的博客 2692

LWIP协议栈在STM32H7上的内存优化实战:如何用32KB RAM实现稳定千兆以太网通信

本文深入探讨了在STM32H7微控制器上,如何通过内存优化策略,在仅32KB的D2 SRAM中稳定运行LWIP协议栈以实现千兆以太网通信。文章详细分析了STM32H7的内存架构、LWIP的内存消耗瓶颈,并提供了从描述符表与PBUF池精确分配、链接脚本修改到MPU区域划分的一整套实战优化方案,旨在解决大数据量传输卡死等常见配置问题。

gg901的博客 605

windows 下AD9361的 no-os master 工程搭建

参考网站: https://wiki.analog.com/resources/fpga/docs/build#windows_environment_setup https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/software/no-os-setup 参考博客: https://blog.youkuaiyun.com...

Bronceyang的博客 7295

Redis学习笔记 ——(8)Pipeline

Redis可以通过Pipeline机制有效提高客户端性能。

weixin_42510648的博客 900

高通thermal-engine.conf配置详解:从虚拟传感器到CPU频率控制的完整指南

本文深入解析了高通thermal-engine.conf配置文件的架构与调优方法。从虚拟传感器的加权融合原理,到监控算法与CPU频率控制的多级策略,提供了完整的配置详解与实战调试指南。文章旨在帮助开发者与高级用户掌握底层温控逻辑,在性能与散热间实现精准平衡,并详细介绍了日志调试与场景化配置等高级技巧。

weixin_28327051的博客 495

redis之pipeline详解

一、pipeline出现的背景: redis客户端执行一条命令分4个过程: 发送命令-〉命令排队-〉命令执行-〉返回结果 1 这个过程称为Round trip time(简称RTT, 往返时间),mget mset有效节约了RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量操作,需要消耗N次RTT ,这个时候需要pipeline来解决这个问题 二、pepeline的...

疯一样的女子 1万+

【嵌入式底层知识修炼】按键和LED共用IO口的分时复用扫描方法

文章目录01 - PCB原理图例程02 - 分时复用的注意项和设计2.1 - 注意项2.2 - 设计03 - 代码实现 只要我跑的速度够快,寂寞就追不上我 只要Key和Led切换速度够快,人眼就看不出来 ————小白   如果你存在按键Key和显示Led共用同一个IO时,需要分时复用的需求,则可以移植代码进行使用: 代码所占code少于0.5K 线程安全,中断安全 可移植性高,配置容易 注意:系统需要存在一个至少为1ms的时钟中断 01 - PCB原理图例程   举2个Key和Led共用IO口的

单眼皮根号三的博客 1万+

Halcon图片拼接避坑指南:特征点匹配常见问题与解决方案

本文深入解析Halcon图片拼接中特征点匹配的常见问题与解决方案,涵盖特征点提取、匹配优化及变换模型选择等关键环节。针对工业视觉检测中的拼接错位、重影等问题,提供参数调优、图像预处理和算法选择等实战技巧,帮助开发者高效避坑并提升拼接精度。

weixin_28694169的博客 199

Redis Pipeline讲解

一、pipeline出现的背景 Redis是一种基于客户端-服务端(CS)模型以及请求/响应协议的TCP服务,这意味着通常情况下一个请求会遵循以下步骤: 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应。 服务端处理命令,并将结果返回给客户端。 这样一次命令消耗的时间就包括四个部分:请求从客户端到服务器的时间、命令排队的时间和命令真正执行时间、结果从服...

diweikang的博客 2893

Allegro如何画Photoplot_Outline操作指导

在用Allegro进行PCB设计的时候,最后进行光绘输出前,Photoplot_Outline是必备一个图形,所有在Photoplot_Outline中的图形将被输出,Photoplot_Outline以外的图形都将不被输出。如何绘制Photoplot_Outline,具体操作如下。如何画Photoplot_Outline操作指导。

weixin_54787054的博客 2639

Redis Pipeline技术

Redis Pipeline通过批量执行命令减少网络往返次数,提高性能和吞吐量。它降低了延迟,简化了客户端代码,同时保证了操作的原子性。使用Jedis库,可以轻松在Java中实现Redis Pipeline。示例代码展示了如何连接到Redis服务,获取Pipeline实例,添加命令,执行并处理结果。在生产环境中,需优化Jedis配置以提高性能和可靠性。

技术铺掌柜 1416

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统(深度学习模型+UI界面+训练数据集)

随着人工智能技术在农业领域的深入应用,基于深度学习的害虫检测系统已成为智慧农业的重要组成部分。本文详细介绍了一种基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的农作物害虫检测系统,涵盖算法原理、数据集构建、模型训练、系统实现及完整代码。该系统能够实时检测并识别多种农作物害虫,为农业生产提供精准的病虫害监测解决方案。

YOLO 273

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Redis之pipeline与事务

Redis使用的是网络模型,也就是io多路复用+非阻塞io的异步处理流程(注册事件,在事件循环callback处理事件)。我们可以将每个连接抽象看成一个pipe,哪个pipe中的数据先满就先处理。注意,单reactor指的是acceptor只有一个,而工作线程在6.0版本之前只有一个,也就是单reactor单线程,6.0版本之后就是单reactor多线程。下图为6.0版本之后的reactor模型。但之后的讨论我们基于6.0版本之前,也就是单reactor单线程。

oxygen3000的博客 1601

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

如何用好redis pipeline

戳蓝字「TopCoder」关注我们哦!编者注:pipeline是Redis的一个提高吞吐量的机制,适用于多key读写场景,比如同时读取多个key的value,或者更新多个...

luoxn28的专栏 594

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

redis:Redis Pipeline深度解析

Redis Pipeline(管道)是一种批量执行命令的优化机制,其核心价值在于。传统模式下,客户端执行一条命令需要经历"发送请求-等待响应"的往返过程,而Pipeline允许客户端一次性发送多条命令,服务器批量处理后一次性返回结果,从而显著降低网络延迟带来的性能损耗。

weixin_43290370的博客 1272

Redis的Pipeline

Redis Pipeline机制通过批量发送命令优化网络性能,减少往返通信次数。相比传统单命令模式,Pipeline允许客户端一次性发送多个指令,服务器顺序执行后返回结果。该机制与事务不同,不保证原子性。通过Java Jedis客户端示例展示了Pipeline的典型用法:批量执行set、append、incr等操作后统一获取响应,显著提升批量处理效率,特别适合高延迟网络环境下的Redis操作优化。

weixin_41510616的博客 821

Redis pipeline

Redis pipeline

1021

Redis 使用 Pipeline 加速查询速度

如果使用的是本地环回接口,RTT 就短得多,但如如果需要连续执行多次写入,这也是一笔很大的开销。Redis 很早就支持 Pipeline 技术,因此无论你运行的是什么版本,你都可以使用 Pipeline 操作 Redis。使用 Pipeline 发送命令时,每次 Pipeline 组装的命令个数不能没有节制,否则一次组装的命令数据量过大,一方面会增加客户端的等待时间,另一方面会造成一定的网络阻塞,可以将一次包含大量命令的 Pipeline 拆分成多个较小的 Pipeline 来完成。

SmartSi 1305

php redis 如何使用pipeline,redis中pipeline详解

一、pipeline出现的背景:redis执行一条命令有四个过程:发送命令、命令排队、命令执行、返回结果;这个过程称为Round trip time(简称RTT, 往返时间),mget mset有效节约了RTT,但大部分命令(如hgetall,并没有mhgetall)不支持批量操作,需要消耗N次RTT ,这个时候需要pipeline来解决这个问题。二、pepeline的性能1、未使用pipelin...

weixin_39606118的博客 1331

Redis之PipeLine

文章目录背景性能对比适用场景注意事项 背景 Redis是使用请求/响应协议的TCP服务器,所以说通常的执行流程如下: 客户端发送请求,同时监听对应的socket,等待服务端响应,一般是一个阻塞的状态 服务端将结果发送给客户端,客户端获取到结果 整个流程如图: 由官方提供的数据来看,Redis每秒可以进行100000+次查询,但是这只是查询的性能,在实际操作中,还需要进行TCP报文的打包和发送...

SCUTJAY的博客 499

Redis批处理之pipeline

前言 Redis是基于TCP连接进行通信 Redis是使用客户端 - 服务器模型的TCP服务器,称为请求/响应协议。 这意味着通常一个请求是通过以下步骤完成的: 客户端向服务器发送查询,并通常以阻塞的方式从套接字读取服务器响应。 服务器处理命令并将响应发送回客户端。 知道redis是基于TCP连接进行通信的,每一个request/response都需要经历一个RTT(Round-Trip Ti...

ChengYanan的博客 815
上一篇: 还记得我们一起优化的SQL吗?
下一篇: ServiceStack.Redis的源码分析
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值