redis 管道原理
命令行使用管道(命令以换行符分隔):
(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 管道原理的更多相关文章
- Redis管道理解
Redis管道理解 简介 管道并不是Redis本身提供的功能,通常是客户端提供的功能: 管道就是打包多条无关命令批量执行,以减少多个命令分别执行消耗的网络交互时间(TCP网络交互),可以显著提升Red ...
- 使用Redis管道提升性能
首发于 樊浩柏科学院 Redis 的 管道 (pipelining)是用来打包多条无关命令批量执行,以减少多个命令分别执行带来的网络交互时间.在一些批量操作数据的场景,使用管道可以显著提升 Redis ...
- redis管道操作(事务),无回滚
管道:将数据操作放在内存中,只有成功后,才会一次性全部放入redis #管道(事务),要是都成功则成功,失败一个全部失败 #原理:将数据操作放在内存中,只有成功后,才会一次性全部放入redis pip ...
- Redis 管道技术
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务.这意味着通常情况下一个请求会遵循以下步骤: 客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响 ...
- Redis事务原理分析
Redis事务原理分析 基本应用 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD ...
- 全面剖析Redis Cluster原理和应用
全面剖析Redis Cluster原理和应用 1.Redis Cluster总览 1.1 设计原则和初衷 在官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子.最 ...
- 一、Redis事务原理分析
一.Redis事务原理分析 在Redis的事务里面,采用的是乐观锁,主要是为了提高性能,减少客户端的等待.由几个命令构成:WATCH, UNWATCH, MULTI, EXEC, DISCARD.通过 ...
- Redis管道功能
Redis管道,Redis存储用户浏览数据 当频繁的存储获取Redis数据库中的数据时,可以使用Redis的pipeline(管道)功能,将多个相互没有依赖关系的读写操作,如:下一步执行的Redis操 ...
- Redis核心原理
Redis系统介绍: Redis的基础介绍与安装使用步骤:https://www.jianshu.com/p/2a23257af57b Redis的基础数据结构与使用:https://www.jian ...
随机推荐
- json扩展
using Newtonsoft.Json.Linq; namespace Utility { public static class JsonExt { /// <summary> // ...
- 小程序之根据参数更改title
是这样的,今天呢在写中英文切换功能,哇 从psd图里面去复制英文在去对应,真的是太难受了 okok 切回正题 当用户选择英文的时候 我的title也要是英文怎么办呢 wx.setNaviga ...
- 冒烟测试(smoke testing)
冒烟测试(smoke testing),就是开发人员在个人版本的软件上执行目前的冒烟测试项目,确定新的程序代码不出故障.冒烟测试的对象是每一个新编译的需要正式测试的软件版本,目的是确认软件基本功能正常 ...
- python 删除文件夹
只能删除空文件夹,删除非空文件夹会报错 >>> import os >>> os.rmdir("/tmp/ssh-GyoPWOFZ47") Tr ...
- Android IPC 结篇
一.概述 Android 的 IPC 方式有 Bundle .共享文件.AIDL .Messenger .ContentProvider .Socket ,我们在实现进程间通信时要选择哪一种方式来实现 ...
- java 数据导入xls
@RequestMapping("admin/doorDesign/getexcel.do") public void getExcel(String name,String ph ...
- Python Appium 开启Android测试之路
1.获取 Android app的Activity 打开终端cmd,先cd进入到刚才下载的“新浪.apk”目录下,然后使用aapt dump badging xxx.apk命令获取包内信息.注意,启动 ...
- 不会 tsconfig | tslint 常遇到的问题
1. require('xx-xx') 不能用时 https://stackoverflow.com/questions/31173738/typescript-getting-error-ts230 ...
- 关于ascii码的一些内容
1.通过C#程序输出tab(制表符)内容. 1.1常用方式我们可以是 //测试输出\t到文件 File.WriteAllText("test.txt", "a\tb\tc ...
- Netty实现简易http_server
Netty可以通过一些handler实现简单的http服务器.具体有三个类,分别是HttpServer.java.ServerHandlerInit.java.BusiHandler.java. 具体 ...