命令行使用管道(命令以换行符分隔):

(printf "PING\r\nPING\r\nPING\r\n"; sleep 1) | nc localhost 6379

redis server 接收客户端的输入,调用栈如下:

ae.c/aeProcessEvents
networking.c/processInputBuffer

redis 中客户端的结构体:

typedef struct client {
// 输入缓冲区保存客户端发送的命令
sds querybuf;
// 字符串数组,要执行的命令,例如 PING
robj **argv;
// 记录 argv 长度
int argc;
} client;

分析管道命令的执行过程:按换行符 split 命令,分三次执行 PING 命令。

void processInputBuffer(client *c) {
server.current_client = c;
/* Keep processing while there is something in the input buffer */
// querybuf 的初始值是 "PING\r\nPING\r\nPING\r\n"
// 每经过一次 processInlineBuffer(c),减少一个 PING
// "PING\r\nPING\r\nPING\r\n" -> "PING\r\nPING\r\n" -> "PING\r\n" -> ""
while(sdslen(c->querybuf)) {
/* Return if clients are paused. */
if (!(c->flags & CLIENT_SLAVE) && clientsArePaused()) break; /* Immediately abort if the client is in the middle of something. */
if (c->flags & CLIENT_BLOCKED) break; /* CLIENT_CLOSE_AFTER_REPLY closes the connection once the reply is
* written to the client. Make sure to not let the reply grow after
* this flag has been set (i.e. don't process more commands).
*
* The same applies for clients we want to terminate ASAP. */
if (c->flags & (CLIENT_CLOSE_AFTER_REPLY|CLIENT_CLOSE_ASAP)) break; /* Determine request type when unknown. */
// 普通命令以 * 开头,请求类型为 PROTO_REQ_MULTIBULK,管道命令类型为 PROTO_REQ_INLINE
if (!c->reqtype) {
if (c->querybuf[] == '*') {
c->reqtype = PROTO_REQ_MULTIBULK;
} else {
c->reqtype = PROTO_REQ_INLINE;
}
} if (c->reqtype == PROTO_REQ_INLINE) {
if (processInlineBuffer(c) != C_OK) break;
} else if (c->reqtype == PROTO_REQ_MULTIBULK) {
if (processMultibulkBuffer(c) != C_OK) break;
} else {
serverPanic("Unknown request type");
} /* Multibulk processing could see a <= 0 length. */
if (c->argc == ) {
resetClient(c);
} else {
/* Only reset the client when the command was executed. */
if (processCommand(c) == C_OK)
resetClient(c);
/* freeMemoryIfNeeded may flush slave output buffers. This may result
* into a slave, that may be the active client, to be freed. */
if (server.current_client == NULL) break;
}
}
server.current_client = NULL;
}

执行具体命令:

sever.c/processCommand
sever.c/call

redis 管道原理的更多相关文章

  1. Redis管道理解

    Redis管道理解 简介 管道并不是Redis本身提供的功能,通常是客户端提供的功能: 管道就是打包多条无关命令批量执行,以减少多个命令分别执行消耗的网络交互时间(TCP网络交互),可以显著提升Red ...

  2. 使用Redis管道提升性能

    首发于 樊浩柏科学院 Redis 的 管道 (pipelining)是用来打包多条无关命令批量执行,以减少多个命令分别执行带来的网络交互时间.在一些批量操作数据的场景,使用管道可以显著提升 Redis ...

  3. redis管道操作(事务),无回滚

    管道:将数据操作放在内存中,只有成功后,才会一次性全部放入redis #管道(事务),要是都成功则成功,失败一个全部失败 #原理:将数据操作放在内存中,只有成功后,才会一次性全部放入redis pip ...

  4. Redis 管道技术

    Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务.这意味着通常情况下一个请求会遵循以下步骤: 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响 ...

  5. Redis事务原理分析

    Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...

  6. 全面剖析Redis Cluster原理和应用

    全面剖析Redis Cluster原理和应用 1.Redis Cluster总览 1.1 设计原则和初衷 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最 ...

  7. 一、Redis事务原理分析

    一.Redis事务原理分析 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD.通过 ...

  8. Redis管道功能

    Redis管道,Redis存储用户浏览数据 当频繁的存储获取Redis数据库中的数据时,可以使用Redis的pipeline(管道)功能,将多个相互没有依赖关系的读写操作,如:下一步执行的Redis操 ...

  9. Redis核心原理

    Redis系统介绍: Redis的基础介绍与安装使用步骤:https://www.jianshu.com/p/2a23257af57b Redis的基础数据结构与使用:https://www.jian ...

随机推荐

  1. hdu 3864 D_num Pollard_rho算法和Miller_Rabin算法

    D_num Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem De ...

  2. IDEA 的Class not found: "..."Empty test suite

    Junit测试的时候出现  IDEA 的Class not found: "..."Empty test suite问题. 尝试一下解决方法: 第一种方法: 1.modules&g ...

  3. go 多态

    demo1 // Sample program to show how polymorphic behavior with interfaces. package main import ( &quo ...

  4. C++.【转】C++数值类型与string的相互转换

    1.C++数值类型与string的相互转换 - JohnGu - 博客园.html(https://www.cnblogs.com/johngu/p/7878029.html) 2. 1.数值类型转换 ...

  5. windows与linux换行符

    我一次linux上写的脚本,利用vim进行脚本编写,然后下载下来在nodepad++上面打开,在nodepad上面新建了一个文件将原来文件内容复制过去,保存后下载复制文件在linux上面进行运行,发现 ...

  6. 力扣(LeetCode)832. 翻转图像

    给定一个二进制矩阵 A,我们想先水平翻转图像,然后反转图像并返回结果. 水平翻转图片就是将图片的每一行都进行翻转,即逆序.例如,水平翻转 [1, 1, 0] 的结果是 [0, 1, 1]. 反转图片的 ...

  7. leecode第十六题(最接近的三数之和)

    class Solution { public: void quick_order(vector<int>& num, int star, int en)//快排 { int st ...

  8. Linux若干源码编译

    Spark源码编译: dev/目录下执行make-distribution.sh./dev/make-distribution.sh --name 2.6.0-cdh5.7.0 --tgz Pyarn ...

  9. 程序莫名其妙的崩溃,加断点刚进入函数就崩溃,断点不往下走,读取图片数据到程序并保存到一个HBITMAP 中

    HPR_INT32 CCarManageDlg::DrawPic2UIForm(IUIFormObj* pUIForm,string& strPicName){//程序崩溃的地方 HPR_IN ...

  10. json包

    1.官网下载 2.pom文件下载: <dependency> <groupId>net.sf.json-lib</groupId> <artifactId&g ...