Redis-12Redis 流水线( pipeline )

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis-12Redis 流水线( pipeline )

概述


Redis 的事务的各类问题,在事务中 Redis 提供了队列, 这是一个可以批量执行任务的队列,这样性能就比较高,但是使用 multi…exec 事务命令是有系统开销的,因为它会检测对应的锁和序列化命令。


有时候我们希望在没有任何附加条件的场景下去使用队列批量执行一系列的命令,从而提高系统性能,这就是 Redis 的流水线( pipelined )技术。


而现实中 Redis 执行读/写速度十分快,而系统的瓶颈往往是在网络通信中的延时,如下


20180927194457759.png



为了解决这个问题,可以使用 Redis 的流水线 , 但是 Redis 的流水线是一种通信协议没有办法通过客户端演,不过我们可以通过 JavaAPI 或者使用 Spring 操作它.


前置条件: reids中的各种属性JavaAPI或者是Spring操作的时候保持一致,一边观察性能。


JavaAPI 操作Redis Pipeline


package com.artisan.redis.pipelined;
import java.util.List;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
public class PipelineWithJavaDemo {
  public static void main(String[] args) {
    // 实例化jedisPoolConfig并设置相关参数
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
    jedisPoolConfig.setMaxIdle(6);
    jedisPoolConfig.setMaxTotal(20);
    jedisPoolConfig.setMaxWaitMillis(3000);
    jedisPoolConfig.setMinEvictableIdleTimeMillis(300000);
    jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000);
    // 使用jedisPoolConfig初始化redis的连接池
    JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.31.66", 6379);
    // 从jedisPool中获取一个连接
    Jedis jedis = jedisPool.getResource();
    jedis.auth("artisan");
    long beginTime = System.currentTimeMillis();
    // 开启流水线
    Pipeline pipeline = jedis.pipelined();
    // 测试10 万条的读/写 2 个操作
    for (int i = 0; i < 100000; i++) {
      int j = i + 1 ;
      jedis.set("pipeline_key" + j , "pipeline_value" + j);
      jedis.get("pipeline_key" + j);
    }
    // 这里只执行同步,但是不返回结果
    // pipeline.sync();
    // 将返回执行过的命令返回的 List 列表结果
    List list = pipeline.syncAndReturnAll();
    long endTime = System.currentTimeMillis();
    System.out.println("10 万条的读/写 2 个操作 ,耗时:" + (endTime - beginTime) + "毫秒");
  }
}


输出

10 万条的读/写 2 个操作 ,耗时:87030毫秒


Spring操作Redis Pipeline

在 Spring 中使用 RedisTemplate提供的 executePipelined 方法即可行流水线

package com.artisan.redis.pipelined;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
public class PipelineWithSpringDemo {
  @SuppressWarnings({ "rawtypes", "unchecked", "unused", "resource" })
  public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/spring-redis-string.xml");
    RedisTemplate redisTemplate = ctx.getBean(RedisTemplate.class);
    SessionCallback sessionCallback = (SessionCallback) (RedisOperations ops) -> {
      for (int i = 0; i < 100000; i++) {
        int j = i + 1 ;
        ops.boundValueOps("pipeline_key" + j).set("pipeline_value" + j);
        ops.boundValueOps("pipeline_key" + j).get();
      }
      return null;
    };
    long beginTime = System.currentTimeMillis();
    // 执行 Redis 的流水线命令
    List list = redisTemplate.executePipelined(sessionCallback);
    long endTime = System.currentTimeMillis();
    System.out.println("10 万条的读/写 2 个操作 ,耗时:" + (endTime - beginTime));
  }
}
INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@73a8dfcc: startup date [Thu Sep 27 19:55:06 CST 2018]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring/spring-redis-string.xml]
10 万条的读/写 2 个操作 ,耗时:2161


这里只是为了测试性能而己,当你要执行很多的命令并返回结果的时候 , 需要考虑 List 对象的大小,因为它会“吃掉”服务器上许多的内存空间 , 严重时会导致内存不足,引发 JVM 溢出异常.


代码

代码托管到了 https://github.com/yangshangwei/redis_learn

相关实践学习
基于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
相关文章
|
2月前
|
NoSQL 网络协议 Java
【赵渝强老师】Redis的管道Pipeline
Redis采用客户端-服务器模型和请求/响应协议,通常一个请求包括客户端发送查询请求并等待服务端响应。为了提高性能,Redis引入了管道PipeLine技术,可以一次性发送多条命令并一次性返回结果,减少客户端与服务器间的通信次数,从而降低往返延迟。示例代码展示了普通命令和管道命令在插入1万条数据时的性能差异,后者执行时间显著缩短。视频讲解提供了更详细的解释。
|
5月前
|
监控 NoSQL Go
Go语言中高效使用Redis的Pipeline
Redis 是构建高性能应用时常用的内存数据库,通过其 Pipeline 和 Watch 机制可批量执行命令并确保数据安全性。Pipeline 类似于超市购物一次性结账,减少网络交互时间,提升效率。Go 语言示例展示了如何使用 Pipeline 和 Pipelined 方法简化代码,并通过 TxPipeline 保证操作原子性。Watch 机制则通过监控键变化实现乐观锁,防止并发问题导致的数据不一致。这些机制简化了开发流程,提高了应用程序的性能和可靠性。
81 0
|
存储 NoSQL Java
Redis性能优化:理解与使用Redis Pipeline
当我们谈论Redis数据处理和存储的优化方法时, Redis Pipeline 无疑是一个不能忽视的重要技术。
847 0
Redis性能优化:理解与使用Redis Pipeline
|
NoSQL Redis Anolis
性能优化特性之:Redis批处理pipeline模式
本文介绍了一种更贴近实际使用的redis验测方法:多pipline模式,并从原理、使用方法进行详细阐述。
|
8月前
|
存储 jenkins Shell
Jenkins Pipeline 流水线任务 补充篇
Jenkins Pipeline 流水线任务 补充篇
254 1
|
8月前
|
存储 NoSQL 关系型数据库
Redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
Redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
225 0
|
NoSQL Java Redis
Redis 从入门到精通之Redis Pipeline
使用Redis Pipeline可以大大提高Redis的性能和吞吐量,但需要注意命令的顺序和语义,以保证数据的正确性和一致性。同时,使用Jedis和RedisTemplate实现Redis Pipeline时,需要遵循最佳实践,避免出现错误和异常。 2. 在使用Jedis实现Redis Pipeline时,需要使用Pipeline对象添加多个命令并执行,然后通过`syncAndReturnAll`方法获取所有命令的执行结果。 3. 在使用RedisTemplate实现Redis Pipeline时,需要使用`executePipelined`方法添加多个命令并执行,然后通过返回的结果列表获取
709 13
Redis 从入门到精通之Redis Pipeline
|
8月前
|
Java jenkins 持续交付
Jenkins Pipeline 流水线方式部署 SpringBoot 项目2
Jenkins Pipeline 流水线方式部署 SpringBoot 项目
491 0
|
8月前
|
jenkins Java 持续交付
Jenkins Pipeline 流水线方式部署 SpringBoot 项目1
Jenkins Pipeline 流水线方式部署 SpringBoot 项目
578 0
|
存储 NoSQL 关系型数据库
redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
redis协议与异步方式(redis网络层、pipeline、事务、lua脚本、ACID特性、发布订阅、hiredis实现同步连接与异步连接)
232 0