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. Web编程规范之三层架构设计规范

    本篇是我对Web开发规范中关于三层架构设计规范的一些浅见.虽然三层架构是比较普通,也比较简单的架构设计模式.但是随着业务的增长,涉及到的对象越来越多,处理的逻辑越来越复杂.这其中难免会出现设计不当,从 ...

  2. VS代码自动排版

    1, ctrl+a 2, ctrl+k 3, ctrl+f

  3. CentOS7.x安装nginx

    1.安装先决条件 yum install yum-utils 2.设置yum存储库和创建/etc/yum.repos.d/nginx.repo 使用以下内容命名的文件 :稳定版 [nginx-stab ...

  4. MySQL运行机制原理&架构

    1.MySQL知识普及: MySQL是一个开放源代码的关系数据库管理系统. MySQL架构可以在多种不同场景中应用并发挥良好作用.主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统 ...

  5. HDU-5728-PowMod-求phi(i*n)前缀和+指数循环节

    HDU-5728-PowMod-求phi(i*n)前缀和+指数循环节 [Problem Description] 令\(k=\sum_{i=1}^m \varphi(i\cdot n)\ mod \ ...

  6. JDBC_通过DriverManager获得数据库连接

    package day_18; import org.junit.Test; import java.io.InputStream; import java.sql.*; import java.sq ...

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

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

  8. springboot+支付宝完成秒杀项目的初体验

    springboot+支付宝完成秒杀项目的初体验 思考的问题: 首先是秒杀的商品查询,考虑到是热点数据,所以写一个接口读取当日批次的秒杀商品到redis中(那么接下来对商品的操作都放入redis中). ...

  9. Java中String、StringBuffer、StringBuilder、StringTokenizer的区别

    Java语言中,有4个类可以对字符或字符串进行操作,它们是Character.String.StringBuffer.StringTokenizer,其中Character用于单个字符操作,Strin ...

  10. idea中关闭当前文件快捷键

    一.idea中关闭当前文件快捷键 1.一般编辑器中关闭当前文件快捷键为ctrl+w 2.而idea中默认为Ctrl+F4 3.可以将其改为自己熟悉的键位. 4.settings——>keymap ...