redis 分析

监听和接收

 

1        创建监听的socket

调用anetTcpServer函数完成,在这个函数中,

 A  通过anetCreateSocket创建一个socket , 并设置so_reuseaddr

 B  设置需要绑定的地址和端口

 C  调用anetListen 进行地址的绑定并且开始监听

 

 

2        socket 放入epoll 监听事件

这个通过调用aeCreateFileEvent 函数来实现的,这里需要传递监听的socket, 监听的事件(可读、可写),事件发生后的处理函数。

下面详细介绍下:

A  根据socket ,我们得到文件事件fileEvent

B  调用aeApiAddEvent把socket 放入epoll中

1        根据fileevent 的mask ,来决定是进行add 还是mod操作

2        当前mask 和fileevent中得mask 进行合并

3        根据mask 类型,来设置epoll中监听事件的类型

4        调用epoll_ctl 添加或者修改事件

   C  设置事件发生后,对应的处理函数,以及clientData

  

通过上面的处理,当epoll中事件发生的时候,可以根据事件的类型,分别调用不同的处理函数。

 

 

3        在2中设置了listen socket 处理函数是 acceptTcpHandler(src/networking.c) ,我们看看这个函数

这个函数主要调用两个函数

 A   anetTcpAccept 来完成接收操作

B   aceptCommonHandler

1          创建一个客户端的链接,通过调用createClient(src/networking.c)函数来实现。  

   在这个函数中,主要创建一个链接对象,并把对应的socket 通过aeCreateFileEvent 函数放入epoll , 在这里设置的可读时候处理函数为

readQueryFromClient

    还有就是通过调用listAddNodeTail把这个链接放到server.clients的末尾

2          校验下client 数目是不是超过了系统的设置。

 

 

处理请求:

         从上面的分析,我们知道了,请求进来的入口函数是readQueryFromClient函数:

1        通过read函数,读取请求的数据,并放入到 connect->querybuf 中

2        调用processInputBuffer

这里的querybuf 数据是如下格式:

参数个数  第一个参数长度  第一个参数 第二个参数长度 第二个参数 第三个参数长度 第三个参数 。。。。。。。

首先会通过第一个参数,调用lookupCommand 来查找对应的cmd,

接着调用call函数,以cmd为参数,在call函数中,调用cmd的proc函数.\

 

那么lookupCommand 是什么东西,它是如何工作的呢?

1        initServerConf 函数中,我们可以看到这个:

server.commands =dictCreate(&commandTableDictType,NULL);

       也就是一个dict(两个hash)

 

2        这个里面放了哪些东西?

在redis.c文件中有一个函数是populateCommandTable,这个函数就是往dict中插入指令,这些指令是在readonlyCommandTable中获取的,那么就赖看看这个:

在redis.c 71行,很长,就不在这里贴了,注意这个结构的第二个成员是处理函数(cmd->proc) ,这个就是最后调用的函数,这下把真个逻辑理清了。

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(redis 分析)