Redis源码剖析(一)服务器与客户端交互流程

Redis中的C/S模型

Redis底层还是基于网络请求的,对于单机数据库而言,网络请求仅仅是在一台机器上交互,即服务器客户端都在一台计算机上

当在终端输入redis-serve时,便启动了一个Redis服务器,随后开始初始化内部数据,对于Redis而言包括

  • 读取配置文件初始化内部参数
  • 创建默认数据库(默认为16个)
  • 创建监听套接字并绑定回调函数(接收客户端连接请求)
  • 执行事件驱动循环,开始响应客户端请求

当在终端输入redis-cli时,遍启动了一个客户端

到这里可以简单的猜测一下,Redis的命令交互流程大致为

  • 启动一个客户端,请求连接到服务器
  • 服务器接收客户端请求,建立连接成功,服务器开始监听客户端文件描述符并绑定回调函数
  • 客户端输入命令,导致服务器端监听的文件描述符变为可读,服务器开始读取命令
  • 服务器解析命令,并调用对应的命令处理函数
  • 服务器将处理结果反馈给客户端
  • 客户端文件描述符变为可读,读取反馈信息,输出在终端

上述是一个常见的C/S模型,Redis采用Reactor模式处理连接,Reactor模式就是常说的使用io多路复用函数监听客户端的方法。不过Redis是单线程下的Reactor,在常见的高并发服务器设计模型中可以使用Reactor+线程池的方法提高并发性(也叫one loop per thread,muduo网络库采用的设计模型)

下面就从源代码的角度体会服务器和客户端交互的流程(只截取关键部分)

服务器与客户端的交互流程

服务器监听客户端连接

当服务器启动时,首先执行的是server.c/main函数,如上所述,main函数进行了大量初始化工作,其中有一项就是创建监听套接字

//server.c
int main(int argc, char **argv) {
    ...
    /* 初始化服务器,创建监听套接字 */
    initServer();
    ...
}

initServer函数中同样进行了大量初始化工作,其中的一部分是创建监听套接字

//server.c
/* 服务器启动时调用,初始化服务器 */
void initServer(void) {
    ...
    /* 创建监听套接字 */
    /* ipfd_count是监听套接字的数量 */
    for (j = 0; j < server.ipfd_count; j++) {
        if (aeCreateFileEvent(server.el, server.ipfd[j], AE_READABLE,
            acceptTcpHandler,NULL) == AE_ERR)
            {
                serverPanic(
                    "Unrecoverable error creating server.ipfd file event.");
            }
    }
    ...
}

创建监听套接字由函数aeCreateFileEvent函数实现

//ae.c
/* 
 * 创建文件事件(事件驱动) 
 * eventLoop : 服务器的事件驱动循环数组
 * fd        : 文件描述符
 * mask      : 需要监听的事件
 * proc      : 回调函数
 * clientData: 传给回调函数的参数
 */
int
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值