https://zhuanlan.zhihu.com/p/58608323

mq消息合并:由于mq请求发出到响应的时间,即往返时间, RTT(Round Time Trip),每次提交都要消耗RTT,不支持类似redis的pipeline机制。

Redis pipeline

百度 高级研发工程师
5 人赞同了该文章

关于 Redis pipeline

为什么需要 pipeline ?

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

实现思路

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

实现原理

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

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; /**
* <h1>Redis Pipeline 功能测试用例</h1>
* 参考: 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<Object> 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<Object> sessionCallback = new SessionCallback<Object>() {
@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 分别执行。
发布于 2019-03-07
 
 
 

等待 Redis 应答的更多相关文章

  1. 等待 Redis 应答 Redis pipeline It's not just a matter of RTT

    小结: 1.When pipelining is used, many commands are usually read with a single read() system call, and ...

  2. Redis Pipeline原理分析

    转载请注明出处:http://www.cnblogs.com/jabnih/ 1. 基本原理 1.1 为什么会出现Pipeline Redis本身是基于Request/Response协议的,正常情况 ...

  3. Redis基础用法、高级特性与性能调优以及缓存穿透等分析

     一.Redis介绍 Redis是一个开源的,基于内存的结构化数据存储媒介,可以作为数据库.缓存服务或消息服务使用.Redis支持多种数据结构,包括字符串.哈希表.链表.集合.有序集合.位图.Hype ...

  4. Redis快速入门详解

    Redis入门详解 Redis简介 Redis安装 Redis配置 Redis数据类型 Redis功能 持久化 主从复制 事务支持 发布订阅 管道 虚拟内存 Redis性能 Redis部署 Redis ...

  5. Redis学习之路(008)- Redis C语言客户端库hiredis文档翻译

    Hiredis是Redis数据库一个轻量的C语言客户端库. 之所以轻量是由于它只是简单的提供了对redis操作语句支持的接口,并没有实现具体的操作语句的功能.但正是由于这种设计使我们只要熟悉了通用的r ...

  6. Redis实战篇

    Redis实战篇 1 Redis 客户端 1.1 客户端通信 原理 客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 . 客户端和服务器发送的命令或数据一律以 \r\n ...

  7. 如何用好redis pipeline

    编者注:pipeline是Redis的一个提高吞吐量的机制,适用于多key读写场景,比如同时读取多个key的value,或者更新多个key的value.工作过程中发现挺多小伙伴都对pipeline多少 ...

  8. Redis 管道pipeline

    Redis是一个cs模式的tcp server,使用和http类似的请求响应协议. 一个client可以通过一个socket连接发起多个请求命令. 每个请求命令发出后client通常会阻塞并等待red ...

  9. 【9k字+】第二篇:进阶:掌握 Redis 的一些进阶操作(Linux环境)

    九 Redis 常用配置文件详解 能够合理的查看,以及理解修改配置文件,能帮助我们更好的使用 Redis,下面按照 Redis 配置文件的顺序依次往下讲 1k 和 1kb,1m 和 1mb .1g 和 ...

随机推荐

  1. 【SpringMVC】拦截器

    一.概述 1.1 拦截器的异常场合 1.2 拦截器中的方法 二.示例 2.1 定义两个拦截器 2.2 配置拦截器 2.3 执行顺序 三.拦截器应用 3.1 需求 3.2 用户登陆及退出功能开发 3.3 ...

  2. Oracle数据的导入与导出

    本文针对window操作系统与oracle12C的版本. 1.sqlplus执行单个sql文件 1.执行sqlplus登陆命令:sqlplus username/password@host:port/ ...

  3. javascript_02-变量

    变量 var number = 5; number = 5; //与上面一样的效果,语法没错误,但是不规范 var:关键字,变量的意思. 变量可以立即赋值,也可以稍后赋值. 堆和栈 内存中有两个区域, ...

  4. 第十八篇:简易版web服务器开发

    在上篇有实现了一个静态的web服务器,可以接收web浏览器的请求,随后对请求消息进行解析,获取客户想要文件的文件名,随后根据文件名返回响应消息:那么这篇我们对该web服务器进行改善,通过多任务.非阻塞 ...

  5. Vue框架之vuex的使用

    1.首先需要在你的项目目录下安装vuex 终端命令: 2.在全局组件中导入与声明vuex 3.创建store实例对象 let store = new Vuex.store({ state:{ }, m ...

  6. 牛客练习赛50 D tokitsukaze and Event (最短路,思维)

    牛客练习赛50 D tokitsukaze and Event 链接:https://ac.nowcoder.com/acm/contest/1080/D来源:牛客网 时间限制:C/C++ 1秒,其他 ...

  7. 轻院校赛-zzuli 2266: number【用每位的二进制的幂的和来进行hash(映射)处理】

    zzuli 2266: number 大致题意:   给定n,问有多少数对<x, y>满足: x, y∈[1, n], x < y            x, y中出现的[0, 9] ...

  8. 0015SpringBoot结合thymeleaf实现点击菜单高亮显示

    1.点击菜单,经过Controller层处理,正常定位到视图页面 2.编写抽象出公共片段的html,根据参数判断是否加高亮样式 3.多个目标页面引用步骤2中抽象出的公共片段,传不同的参数 具体实现如下 ...

  9. unordered_map初用

    unordered_map,顾名思义,就是无序map,STL内部实现了Hash 所以使用时可以当做STL的Hash表使用,时间复杂度可做到O(1)查询 在C++11前,使用unordered_map要 ...

  10. [NOI2019]序列(模拟费用流)

    题意: 有两个长度为n的序列,要求从每个序列中选k个,并且满足至少有l个位置都被选,问总和最大是多少. \(1\leq l\leq k\leq n\leq 2*10^5\). 首先,记录当前考虑到的位 ...