Redis 命令解析流程:以 SET 命令为例
Redis 对命令的解析和执行是其核心功能之一,涉及协议解析、参数处理、命令路由等多个环节。本文以 SET 命令为例,详细解析 Redis 如何接收、解析并执行命令。
命令解析的整体流程
Redis 处理客户端命令的流程可概括为:
接收命令数据 → 协议解析 → 填充 client 结构体 → 路由到对应命令函数 → 执行命令 → 返回结果
其中,client 结构体是贯穿全程的核心载体,记录了命令的参数、客户端状态、连接信息等关键数据。
client 结构体:命令解析的核心载体
client 结构体是 Redis 描述客户端连接和命令请求的核心数据结构,与命令解析相关的关键字段如下:
| 字段名 |
作用 |
argc |
命令参数的数量(包含命令名本身)。例如 SET key value 中,argc=3。 |
argv |
命令参数数组(robj* 类型,robj 是 Redis 通用对象结构)。argv[0] 为命令名(如 "SET"),argv[1...] 为命令参数(如 "key"、"value")。 |
querybuf |
接收客户端命令的缓冲区(sds 类型,动态字符串),存储未解析的原始命令数据。 |
qb_pos |
querybuf 中已解析的位置,用于增量解析命令。 |
cmd |
指向当前执行的命令结构体(redisCommand 类型),包含命令的处理函数、参数个数限制等元信息。 |
SET 命令解析:从代码看细节
setCommand 函数为例,解析 Redis 如何处理 SET 命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void setCommand(client *c) { robj *expire = NULL; int unit = UNIT_SECONDS; int flags = OBJ_NO_FLAGS;
if (parseExtendedStringArgumentsOrReply(c,&flags,&unit,&expire,COMMAND_SET) != C_OK) { return; }
c->argv[2] = tryObjectEncoding(c->argv[2]);
setGenericCommand(c,flags,c->argv[1],c->argv[2],expire,unit,NULL,NULL); }
|
步骤 1:解析扩展参数(parseExtendedStringArgumentsOrReply)
SET 命令支持丰富的扩展选项(如 SET key value EX 30 NX),该函数的作用是解析这些选项: