Redis pipeline

  关于 Redis pipeline

  为什么需要 pipeline ?

  Redis 的工作过程是基于 请求/响应 模式的。正常情况下,客户端发送一个命令,等待 Redis 应答;Redis 接收到命令,处理后应答。请求发出到响应的时间叫做往返时间,即 RTT(Round Time Trip)。在这种情况下,如果需要执行大量的命令,就需要等待上一条命令应答后再执行。这中间不仅仅多了许多次 RTT,而且还频繁的调用系统 IO,发送网络请求。为了提升效率,pipeline 出现了,它允许客户端可以一次发送多条命令,而不等待上一条命令执行的结果。

  实现思路

  客户端首先将执行的命令写入到缓冲区中,最后再一次性发送 Redis。但是有一种情况就是,缓冲区的大小是有限制的:如果命令数据太大,可能会有多次发送的过程,但是仍不会处理 Redis 的应答。

  实现原理

  要支持 pipeline,既要服务端的支持,也要客户端支持。对于服务端来说,所需要的是能够处理一个客户端通过同一个 TCP 连接发来的多个命令。可以理解为,这里将多个命令切分,和处理单个命令一样。对于客户端,则是要将多个命令缓存起来,缓冲区满了就发送,然后再写缓冲,最后才处理 Redis 的应答。

  Redis pipeline 的参考资料

  Redis 官网对于 pipeline 的介绍

  Spring Data Redis 对于 pipeline 的介绍

  在 SpringBoot 中使用 Redis pipeline

  基于 SpringBoot 的自动配置,在使用 Redis 时只需要在 pom 文件中给出 spring-boot-starter-data-redis 依赖,就可以直接使用 Spring Data Redis。关于 Redis pipeline 的使用方法,可以阅读 Spring Data Redis 给出的解释。下面,我给出一个简单的例子:

  import com.imooc.ad.Application;

  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.StringRedisConnection;

  import org.springframework.data.redis.core.RedisCallback;

  import org.springframework.data.redis.core.RedisOperations;

  import org.springframework.data.redis.core.SessionCallback;

  import org.springframework.data.redis.core.StringRedisTemplate;

  import org.springframework.test.context.junit4.SpringRunner;

  /**

  *

Redis Pipeline 功能测试用例


  * 参考: https://docs.spring.io/spring-data/redis/docs/1.8.1.RELEASE/reference/html/#redis:template

  * Created by Qinyi.

  */

  @RunWith(SpringRunner.class)

  @SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.NONE)

  public class RedisPipelineTest {

  /** 注入 StringRedisTemplate, 使用默认配置 */

  @Autowired

  private StringRedisTemplate stringRedisTemplate;

  @Test

  @SuppressWarnings(all)

  public void testExecutePipelined() {

  // 使用 RedisCallback 把命令放在 pipeline 中

  RedisCallback redisCallback = connection - {

  StringRedisConnection stringRedisConn = (StringRedisConnection) connection;

  for (int i = 0; i != 10; ++i) {

  stringRedisConn.set(String.valueOf(i), String.valueOf(i));

  }

  return null; // 这里必须要返回 null

  };

  // 使用 SessionCallback 把命令放在 pipeline

  SessionCallback sessionCallback = new SessionCallback() {

  @Override

  public Object execute(RedisOperations operations) throws DataAccessException {

  operations.opsForValue().set(name, qinyi);

  operations.opsForValue().set(gender, male);

  operations.opsForValue().set(age, 19);

  return null;

  }

  };

  System.out.println(stringRedisTemplate.executePipelined(redisCallback));

  System.out.println(stringRedisTemplate.executePipelined(sessionCallback));

  }

  }

  总结:Redis pipeline 的特性以及使用时需要注意的地方

  pipeline 减少了 RTT,也减少了IO调用次数(IO 调用涉及到用户态到内核态之间的切换)

  如果某一次需要执行大量的命令,不能放到一个 pipeline 中执行。数据量过多,网络传输延迟会增加,且会消耗 Redis 大量的内存。应该将大量的命令切分为多个 pipeline 分别执行。



转载于:https://juejin.im/post/5c8613d66fb9a049f362ec86

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值