本文来说下Redis的管道pipeline

文章目录

  • 概述
  • Redis管道技术
  • SpringDataRedis使用管道
  • 使用管道技术的注意事项
  • 本文小结

概述

Redis提供了一个称为管道(Pipeline) 的机制将一组Redis命令进行组装,通过一次 RTT 传输给 Redis,再将这些 Redis 命令的执行结果按顺序传递给客户端。即使用pipeline执行了n次命令,整个过程就只需要一次 RTT。底层避免了用户态切换到内核态

正常情况下,每个请求命令发出后client通常会阻塞并等待redis服务端处理,redis服务端处理完后将结果返回给client。当client使用pipeline发送命令时,redis server必须部分请求放到队列中(使用内存)执行完毕后一次性发送结果。在一定程度上,可以较大的提升性能,性能提升的原因主要是TCP链接中较少了“交互往返”的时间。


Redis管道技术

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

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

这就是普通请求模型。


所谓RTT(Round-Trip Time),就是往返时延,在计算机网络中它是一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延

一般认为,单向时延 = 传输时延t1 + 传播时延t2 + 排队时延t3

为了解决这个问题,Redis支持通过管道,来达到减少RTT的目的。


SpringDataRedis使用管道

SpringDataRedis提供了executePipelined方法对管道进行支持。下面是一个Redis队列的操作,放到了管道中进行操作。

package net.ijiangtao.tech.framework.spring.ispringboot.redis.pipelining;import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;import java.time.Duration;
import java.time.Instant;/*** Redis Pipelining** @author ijiangtao* @create 2019-04-13 22:32**/
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class RedisPipeliningTests {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final String RLIST = "test_redis_list";@Testpublic void test() {Instant beginTime2 = Instant.now();redisTemplate.executePipelined(new RedisCallback<Object>() {@Overridepublic Object doInRedis(RedisConnection connection) throws DataAccessException {for (int i = 0; i < (10 * 10000); i++) {connection.lPush(RLIST.getBytes(), (i + "").getBytes());}for (int i = 0; i < (10 * 10000); i++) {connection.rPop(RLIST.getBytes());}return null;}});log.info(" ***************** pipeling time duration : {}", Duration.between(beginTime2, Instant.now()).getSeconds());}
}

注意executePipelined中的doInRedis方法返回总为null。


使用管道技术的注意事项

当你要进行频繁的Redis请求的时候,为了达到最佳性能,降低RTT,你应该使用管道技术。

但如果通过管道发送了太多请求,也会造成Redis的CPU使用率过高。

下面是通过循环向Redis发送出队指令来监听队列的CUP使用情况:


当管道中累计了大量请求以后,CUP使用率迅速升到了100%,这是非常危险的操作。

对于监听队列的场景,一个简单的做法是当发现队列返回的内容为空的时候,就让线程休眠几秒钟,等队列中累积了一定量数据以后再通过管道去取,这样就既能享受管道带来的高性能,又避免了CPU使用率过高的风险。

Thread.currentThread().sleep(10 * 1000);

本文小结

本文详细介绍了redis中有关管道相关的知识与内容。

Redis的管道pipeline相关推荐

  1. redis 使用管道pipeline和不使用管道的性能对比

    predis3.php代码如下所示: <?php  include('runtime.php'); try{ $redis = new Redis(); $redis->connect(' ...

  2. python redis pipeline使用方法_Redis中的管道Pipeline操作

    点击上方蓝色字体,选择"设为星标" 回复"资源"获取更多资源 点击右侧关注,大数据开发领域最强公众号! 点击右侧关注,暴走大数据! Redis默认每次执行请求都 ...

  3. Redis事务与Pipeline功能

    一.Redis事务 Redis中的事务(transaction)是一组命令的集合,对事物的支持有限,不能保证原子性,在集群分片环境中,由于不同key可能存在不同的机器上,所以造成事务无法使用(可以简单 ...

  4. jenkins~管道Pipeline里使用公用类库

    Pipeline使用了groovy语法,同时可以使用所有jenkins插件在groovy里进行调用,可以说通过UI可以实现的功能使用pipeline也可以实现,这一点我在上一篇文章里已经说明,今天主要 ...

  5. Boost:基于Boost的管道pipeline通信

    Boost:基于Boost的管道pipeline通信 实现功能 C++实现代码 实现功能 boost::asio模块,基于Boost的管道pipeline通信 C++实现代码 #include < ...

  6. [并发并行]_[线程模型]_[Pthread线程使用模型之一管道Pipeline]

    场景 1.经常在Windows, MacOSX 开发C多线程程序的时候, 经常需要和线程打交道, 如果开发人员的数量不多时, 同时掌握Win32和pthread线程 并不是容易的事情, 而且使用Win ...

  7. Spark机器学习管道 - Pipeline

    Spark机器学习管道 - Pipeline 一.实验目的 二.实验内容 三.实验原理 四.实验环境 五.实验步骤 5.1 启动Spark集群和Zeppelin服务器. 5.2 使用管道创建一个小型工 ...

  8. redis cluster使用pipeline

    redis cluster使用pipeline 为什么cluster无法使用pipeline 基于redisCluster整合pipeline 设计思路 代码实现 为什么cluster无法使用pipe ...

  9. Redis 笔记(15)— 管道 pipeline(客户端将批量命令打包发送用来节省网络开销)

    Redis 是一种基于客户端-服务端模型以及请求/响应协议的 TCP 服务.这意味着通常情况下一个请求会遵循以下步骤: 客户端向服务端发送一个查询请求,并监听 Socket 返回,通常是以阻塞模式,等 ...

最新文章

  1. 如果地府需要一个后台管理系统,你会如何设计?
  2. 软件随想: 软件 = 程序 + 软件工程
  3. 20行python代码的入门级小游戏-python实现石头剪刀布小游戏
  4. 程序员讨论技术问题时说话都很直接,哪个国家都不例外
  5. layout_gravity
  6. idea教程--Maven 骨架介绍
  7. Mysql 8.0 安装
  8. 昨天要成为反弹一日游?关键看下午了
  9. 国内统一Android应用市场,最全最干净的安卓应用市场
  10. 高数(数一)知识点自我归纳(思维导图)
  11. 数学笔记(四)线性代数知识点总结
  12. 深度神经网络与卷积神经网络的区别
  13. ddr5内存上市时间_DDR5内存年底开始量产,2022年成为主流!
  14. 光谱共焦位移传感器原理和特性
  15. Google Python命名规范
  16. html5加号展开减号缩减,CSS3 linear-gradient线性渐变生成加号和减号的方法
  17. 如何将学堂在线(安卓)APP视频保存到本地并重命名
  18. [转] 记住亦舒的话
  19. 奇虎360scribe日志采集系统
  20. Openmv(一)OpenMV图像处理的基本方法

热门文章

  1. 《深入理解Android:卷III A》一一第3章 深入理解AudioService
  2. HTTP之Cookie
  3. 在.net中序列化读写xml方法的总结(转载)
  4. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3
  5. web前端的渐进增强式开发模型
  6. scala 模式匹配详解 1
  7. SQL Server 调优系列基础篇 - 子查询运算总结
  8. latex中括号大小控制 [转]
  9. 如何在XSLT中将字符串转换为大写或小写形式
  10. access制作封装软件_用Access开发《社工服务管理系统》