前言
相关介绍主要围绕着 redis 里面的 pipeline 相关特性
如下常用的命令来自于我们常见的教程 : Redis 管道技术 | 菜鸟教程
本文的相关代码 拷贝自 redis-6.2.0
代码来自于 https://redis.io/
以下测试用例基于 jedis 3.5.2
redis pipeline 机制
这是基于 redis 的交互协议, 也就是一次 tcp 请求 和 响应的过程中传递 多个请求/响应
redis-server 这边获取客户端这边的输入序列, 每次以 命令为单位 获取 当前命令 以及 参数然后进行处理
redis-client 这边在一个请求中传递 多个命令 以及参数
减少了 多个单独的命令的 tcp 协议交互的开销
测试用例
package com.hx.test11;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import java.util.List;
/**
* Test19JedisPipeline
*
* @author Jerry.X.He
* @version 1.0
* @date 2021-03-22 09:58
*/
public class Test19JedisPipeline {
// Test19JedisPipeline
public static void main(String[] args) {
Jedis jedis = new Jedis("127.0.0.1", 6379);
// pipeline
Pipeline pipeline = jedis.pipelined();
pipeline.set("name1", "jerry1");
pipeline.set("name2", "jerry2");
pipeline.get("name2");
List<Object> list = pipeline.syncAndReturnAll();
int x = 0;
}
}
pipeline 的请求
我们来观察一下这里的 data 部分
我们这里业务上传递了 三个命令 : "set name1 jerry1", "set name2 jerry2", "get name2" 这三条命令
data 中看到的也是这三条命令符合 multibulk 的格式依次排列
pipeline 的响应
我们来观察一下这里的 data 部分
data 中看到的也是这三条响应符合 multibulk 的格式依次排列
三条响应依次为 : "+OK", "+OK", "\$6\r\njerry2\r\n" [字符串的 "jerry2" ]
redis-server 这边 pipeline 请求的处理
processInputBuffer 里面本身的处理就是以 command 为单位循环处理 query_buf 里面里面的 command, 然后进行处理, 响应数据给客户端
比如我这里断点的位置, 是处理了第一条命令 "set name1 jerry1", 正准备处理第二条命令, 接下来会处理 第三条命令
redis-client 这边 pipeline 请求的处理
redis-client 这边 "set name1 jerry1", "set name2 jerry2", "get name2" 三条 set 命令的处理, 注意这里没有 flush
在 pipeline.set, pipeline.get 的时候写出了 命令, 参数 的相关数据, 并没有 flush
在调用 syncAndReturnAll 的时候, flush 了 connection, 给 redis-server 发送了请求, 三个 command 的相关参数一次性传递给了 redis-server
redis-client 这边 pipeline 响应的处理
下面 readProtocolWithCheckingBroken 就是读取服务端返回来的数据
最终解析 服务端返回的数据解析为 字节序列
格式化之后, 结果为 [OK, OK, jerry2]
完