关于redis:redis客户端发送键消息流程

redis客户端启动流程

  1. 用户键入shell命令启动redis客户端:./redis-cli -h …
  2. shell fork一个子过程来运行这个程序
  3. 内核将redis客户端程序src/redis-cli可执行文件从磁盘载入内存
  4. 子过程通过execvp零碎函数来执行与父过程不同的程序,即src/redis-cli程序。

    execvp()会从可执行程序中加载代码和静态数据,并用它覆写本人(子过程)的代码段(以及静态数据),堆、栈及其他内存空间也会被从新初始化。而后操作系统就执行该程序,将参数通过 argv 传递给该过程。因而,它并谁有创立新过程,而是间接将以后运行的程序(以前的 shell)替换为不同的运行程序(redis-cli)

  5. 调用redis-cli.c中的main函数程序在子过程中运行直到完结

构建RESP格局音讯

redis命令行应用的是第三方代码库linenoise,期待命令行输出。
linenoise是代替readline 性能的命令行工具,其源代码在deps\linenoise目录下。它能够独立于 Redis src 目录下的性能源码进行编译。

main()函数首先与向服务器发送connect(),申请建设tcp连贯:

int main(int argc, char **argv) {
    ......
    cliConnect(0);
    repl();
    ...... 
}

等到tcp通过三次握手建好连贯后,客户端通过linenoise()函数期待命令行输出:

static void repl(void) {
    while((line = linenoise(context ? config.prompt : "not connected> ")) != NULL) {
        ......
    }
}

(5) repl()中调用hiredis接口redisAppendCommandArgv()依据命令行参数构建RESP格局音讯

#0  redisAppendCommandArgv () at hiredis.c:965
#1  cliSendCommand () at redis-cli.c:1148
#2  issueCommandRepeat () at redis-cli.c:1583
#3  repl () at redis-cli.c:1764
#4  main () at redis-cli.c:7158
// 依据命令行构建resp音讯
int redisFormatSdsCommandArgv(){   
    sds cmd;     
    cmd = sdsempty();      
    cmd = sdsMakeRoomFor(cmd, totlen);
  
    /* Construct command */  
    cmd = sdscatfmt(cmd, "*%i\r\n", argc);  

    for (j=0; j < argc; j++) {      
        len = argvlen ? argvlen[j] : strlen(argv[j]);      
        cmd = sdscatfmt(cmd, "$%u\r\n", len);       
        cmd = sdscatlen(cmd, argv[j], len);       
        cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);   
    }   
}

发送redis键命令音讯给服务器

发送接口:
调用cliReadReply函数发送数据到服务端并读取服务端的返回数据
cliReadReply() —> redisGetReply() —> redisBufferWrite() —> write()

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理