Redis管道技术的使用

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis管道技术的使用

目录

Redis 管道技术

Redis是一种基于客户端-服务端模型(C/S模型)以及请求/响应协议的TCP服务。

这意味着通常情况下一个请求会遵循以下步骤:

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

这就是普通请求模型。

[外链图片转存中...(img-2IlvOfYe-1676540455858)]

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

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

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

通过管道减少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 {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final String RLIST = "test_redis_list";

    @Test
    public void test() {

      Instant beginTime2 = Instant.now();

      redisTemplate.executePipelined(new RedisCallback<Object>() {
          @Override
          public 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 管道的性能测试

上面简单演示了管道的使用方式,那么管道的性能究竟如何呢?

下面我们一起来验证一下。

首先,redis提供了redis-benchmark工具测试性能,我在自己的电脑上通过cmd打开命令行,不使用管道,进行了一百万次set和get操作,效果如下:

$ redis-benchmark -n 1000000 -t set,get -q
SET: 42971.94 requests per second
GET: 46737.71 requests per second

平均每秒处理4万多次操作请求。

通过-P命令使用管道,效果如下:

$ redis-benchmark -n 1000000 -t set,get -P 16 –q
SET: 198098.27 requests per second
GET: 351988.72 requests per second

使用管道以后,set和get的速度变成了每秒将近20万次和35万次。

然后我在服务器上,测试了使用SpringDataRedis进行rpop出队2000次的性能。

分别使用单线程出队、32个线程并发出队和单线程管道出队。下面是测试的结果:

[外链图片转存中...(img-QWZ12DYR-1676540455860)]

从统计结果来看,出队2000次,在单线程下大约需要6秒;32个线程并发请求大约需要2秒;而单线程下使用管道只需要70毫秒左右。

使用管道技术的注意事项

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

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

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

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

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

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

代码示例

Github-ispringboot-redis

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
12天前
|
NoSQL 网络协议 Java
【赵渝强老师】Redis的管道Pipeline
Redis采用客户端-服务器模型和请求/响应协议,通常一个请求包括客户端发送查询请求并等待服务端响应。为了提高性能,Redis引入了管道PipeLine技术,可以一次性发送多条命令并一次性返回结果,减少客户端与服务器间的通信次数,从而降低往返延迟。示例代码展示了普通命令和管道命令在插入1万条数据时的性能差异,后者执行时间显著缩短。视频讲解提供了更详细的解释。
|
26天前
|
移动开发 NoSQL 网络协议
Redis 管道技术
10月更文挑战第21天
20 3
|
1月前
|
缓存 监控 负载均衡
如何解决Redis热点Key问题?技术干货分享
【10月更文挑战第2天】在Redis的使用过程中,热点Key问题是一个常见的性能瓶颈。热点Key指的是那些被频繁访问的Key,它们可能导致Redis服务器的负载不均衡,进而影响整体性能。本文将深入探讨热点Key问题的成因、影响以及多种解决方案,帮助读者在实际工作中有效应对这一挑战。
54 3
|
1月前
|
JSON 缓存 NoSQL
Redis 在线查看序列化对象技术详解
Redis 在线查看序列化对象技术详解
37 2
|
2月前
|
存储 缓存 NoSQL
解决Redis缓存击穿问题的技术方法
解决Redis缓存击穿问题的技术方法
73 2
|
2月前
|
存储 NoSQL Redis
Redis 管道技术
【9月更文挑战第16天】Redis 管道技术通过批量发送命令并一次性读取响应,显著提升了与 Redis 服务器交互的性能。其工作原理包括命令缓冲、批量发送、响应接收与处理。管道技术减少了网络往返次数,提高了资源利用效率,并使代码更简洁。适用于批量操作、高并发环境及复杂业务逻辑等场景,是优化 Redis 应用性能的强大工具。
|
2月前
|
缓存 NoSQL PHP
使用PHP-redis实现键空间通知监听key失效事件的技术与代码示例
通过上述方法,你可以有效地在PHP中使用Redis来监听键空间通知,特别是针对键失效事件。这可以帮助你更好地管理缓存策略,及时响应键的变化。
96 3
|
2月前
|
存储 NoSQL Redis
10)Redis 的管道技术
10)Redis 的管道技术
48 0
|
2月前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
NoSQL 云栖大会 Redis
【云栖大会】Redis技术的实践与探索
Redis作为高性能的key-value数据库,目前包括Twitter、微博、GitHub在内等众多IT互联网企业都在使用它。本专场阿里云高级技术专家兼Redis中国用户会发起人子嘉等人齐聚首,分享了Redis的实践经验,以及Redis云服务的技术架构、云上客户的典型问题等内容。
3452 0
下一篇
无影云桌面