复制
clusterNode *getNodeByQuery(redisClient *c, struct redisCommand *cmd, robj **argv, int argc, int *hashslot, int *error_code) {
//......
//如果是exec命令则用客户端的multiState封装这些命令
if (cmd->proc == execCommand) {
/* If REDIS_MULTI flag is not set EXEC is just going to return an
* error. */
if (!(c->flags & REDIS_MULTI)) return myself;
ms = &c->mstate;
} else {
//如果不是exec则自己创建一个multiState封装这单条指令保证后续逻辑一致
ms = &_ms;
_ms.commands = &mc;
//命令个数1
_ms.count = 1;
//命令参数
mc.argv = argv;
//命令参数个数
mc.argc = argc;
//对应的命令
mc.cmd = cmd;
}
//遍历multiState中的命令
for (i = 0; i < ms->count; i++) {
struct redisCommand *mcmd;
robj **margv;
int margc, *keyindex, numkeys, j;
//解析出命令、参数个数、参数
mcmd = ms->commands.cmd;
margc = ms->commands.argc;
margv = ms->commands.argv;
//解析出key以及个数
keyindex = getKeysFromCommand(mcmd,margv,margc,&numkeys);
for (j = 0; j < numkeys; j++) {
//拿到key
robj *thiskey = margv[keyindex[j]];
//计算slot
int thisslot = keyHashSlot((char*)thiskey->ptr,
sdslen(thiskey->ptr));
if (firstkey == NULL) {
firstkey = thiskey;
slot = thisslot;
//拿着计算的slot定位到对应的节点
n = server.cluster->slots[slot];