Redis-12Redis 流水线( pipeline )

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
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
相关文章
|
机器人 jenkins Java
jenkins pipeline流水线集成jacoco,sonar,robot framework,jmeter,fortify
jenkins pipeline流水线集成jacoco,sonar,robot framework,jmeter,fortify
jenkins pipeline流水线集成jacoco,sonar,robot framework,jmeter,fortify
|
6月前
|
存储 jenkins Shell
Jenkins Pipeline 流水线任务 补充篇
Jenkins Pipeline 流水线任务 补充篇
236 1
|
6月前
|
Java jenkins 持续交付
Jenkins Pipeline 流水线方式部署 SpringBoot 项目2
Jenkins Pipeline 流水线方式部署 SpringBoot 项目
446 0
|
6月前
|
jenkins Java 持续交付
Jenkins Pipeline 流水线方式部署 SpringBoot 项目1
Jenkins Pipeline 流水线方式部署 SpringBoot 项目
521 0
|
JavaScript Java Go
Pipeline as Code 轻松管理你的流水线
云效 Flow 基于 Pipeline as Code 支持以 YAML 方式编排流水线,帮助客户解决多条流水线快速创建、批量管理等问题,满足跳过/分支等复杂流程编排场景。今天我们跟着云效流水线产品经理一起体验和感受云效流水线 YAML 化的最新能力。
580 0
|
存储
gitlab--运行流水线、设置 tags、设置 pipeline 状态、添加徽章
gitlab--运行流水线、设置 tags、设置 pipeline 状态、添加徽章
|
jenkins Shell 持续交付
Jenkins设置流水线Pipeline定时任务
Jenkins设置流水线Pipeline定时任务
1099 0
Jenkins设置流水线Pipeline定时任务
|
jenkins Java 测试技术
基于 Rainbond 的 Pipeline(流水线)插件
Rainbond 本身具有基于源码构建组件的能力,可以将多种编程语言的代码编译成 Docker 镜像,但是在持续集成的过程中,往往会需要对提交的代码进行静态检查、构建打包以及单元测试。之前由于 Rainbond 并没有 Pipeline 这种可编排的机制,所以用户往往只能通过集成外部的 CI ,如 Jenkins、Gitlab CI 等。这给开发者的使用增加了门槛。
|
Kubernetes jenkins Java
jenkins-CICD系列之-jenkins使用pipeline流水线k8s发布
jenkins使用pipeline流水线k8s一键发布
1094 1
|
数据可视化 Ubuntu jenkins
Jenkins流水线(pipeline)实战之:从部署到体验
部署和体验Jenkins流水线(pipeline)
535 0
Jenkins流水线(pipeline)实战之:从部署到体验

热门文章

最新文章