Redis-命令处理流程

Redis 命令处理流程

在上一篇redis的文章中,大致解释了redis 网络处理流程。[redis网络模型] (https://github.com/leeqx/leeqx.github.io/wiki/Redis-%E7%BD%91%E7%BB%9C%E4%BA%8B%E4%BB%B6)
本章主要梳理一下redis 受到request的整个处理流程。
在redis.c 上篇中看到了,网络接受完成之后调用processInputBuffer处理业务逻辑。在该方法中掉会对单条命令和多条命令区分处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void processInputBuffer(redisClient *c) {
....
if (c->reqtype == REDIS_REQ_INLINE) {
if (processInlineBuffer(c) != REDIS_OK) break;
} else if (c->reqtype == REDIS_REQ_MULTIBULK) {
if (processMultibulkBuffer(c) != REDIS_OK) break;
} else {
redisPanic("Unknown request type");
}
/* Multibulk processing could see a <= 0 length. */
if (c->argc == 0) {
resetClient(c);
} else { /* Only reset the client when the command was executed. */
if (processCommand(c) == REDIS_OK) {
resetClient(c);
}
}
}
int processCommand(redisClient *c) {
...
c->cmd = c->lastcmd = lookupCommand(c->argv[0]->ptr);
...
/* Exec the command */
if (c->flags & REDIS_MULTI &&
c->cmd->proc != execCommand &&
c->cmd->proc != discardCommand &&
c->cmd->proc != multiCommand &&
c->cmd->proc != watchCommand) {
queueMultiCommand(c);
addReply(c,shared.queued);
} else {
call(c,REDIS_CALL_FULL); //调用命令处理方法
c->woff = server.master_repl_offset;
if (listLength(server.ready_keys))handleClientsBlockedOnLists();
}
}
```
肯定很好奇call 这里调用的是什么方法? 其实稍微简单想一下其实这里就是调用每个redis命令相关的回调方法。比如set 这个命令,我们在 redis.c 可以看到每个命令都配置这一个对应的回调方法,`lookupCommand() ` 就是获取对应命令的回调方法,在call中将会调用 `c->cmd->proc `(即使对应的配置的回调方法) .比如下面的:`getCommand setCommand`。
```c
struct redisCommand redisCommandTable[] = {
{"get",getCommand,2,"rF",0,NULL,1,1,1,0,0},
{"set",setCommand,-3,"wm",0,NULL,1,1,1,0,0},
.....
};

另外在call()方法中不光调用回调方法,还会根据对应的命令是否需要触发写aof、或者是否需要同步到slave等逻辑。

坚持原创技术分享,您的支持奖鼓励我继续创作!