jizeng / Redis-Note

redis issues
0 stars 0 forks source link

redis网络模型---之---函数调用 #8

Open jizeng opened 5 years ago

jizeng commented 5 years ago

网络模型各函数调用关系

jizeng commented 5 years ago

image image

jizeng commented 5 years ago

http://blog.chinaunix.net/uid-22312037-id-3475414.html http://blog.chinaunix.net/uid-22312037-id-3475414.html http://blog.chinaunix.net/uid-22312037-id-3475414.html

1、 TCP/Unix Socket层(Anet.h(117)、Anet.c(405))

(1)socket创建

anetCreateSocket:创建TCP/Unix socket,设置socket SO_REUSEADDR。

(2)socket属性设置

anetTcpNoDelay:设置是否关闭Nagle算法,Nagle算法作用点这里。

anetNonBlock:设置阻塞还是非阻塞。

anetTcpKeepAlive:设置是否开启协议栈心跳,协议栈心跳作用点这里。

anetSetSendBuffer:设置发送buffer大小。

(3)Connect

anetTcpGenericConnect:TCP Connect原始接口封装,输入IP地址和阻塞/非阻塞参数。

anetTcpConnect:TCP阻塞连接。

anetTcpNonBlockConnect:TCP非阻塞连接。

anetUnixGenericConnect:Unix Connect原始接口封装,输入IP地址和阻塞/非阻塞参数。

anetUnixConnect:Unix阻塞连接。

anetUnixNonBlockConnect:Unix非阻塞连接。

(4)Listen

anetListen:bind和listen(511原因请查Nginx)封装。

anetTcpServer:调用anetCreateSocket和anetListen监听连接到来。

anetUnixServer:调用anetCreateSocket和anetListen监听连接到来。

(5)Accept

anetGenericAccept:accept封装,while直到accept成功或失败才返回。

anetTcpAccept:调用anetGenericAccept,返回fd,带回IP和Port(函数参数)或错误。    

anetUnixAccept:调用anetGenericAccept,返回fd,或带回错误(函数参数)。

(6)IP和host互转

anetPeerToString:由IPAddress->Host。

anetResolve:由Host->IPAddresss。

(7)格式化error

anetSetError:变长参数格式化,函数参数带回格式化后error信息。

2、 I/O模型层(Ae_select.c(72)、Ae_epoll.c(101)、Ae_kqueue.c(105))

三者都有统一的接口,功能大体类似,但也有细节差别,以epoll(参看这里)为蓝本解析如下:

aeApiState:包含epoll fd句柄和Event指针的struct,epoll和kqueue基本一致,而select是rfds和wfds集合及副本,具体见Ae_select.c代码第7~12行。

aeApiCreate:创建aeApiState,并以此初始化aeEventLoop(作用见后文)。epoll_create参数采用Linux kernel的hint值1024。

aeApiFree:close epoll fd句柄,释放malloc的aeApiState和aeEventLoop。

aeApiAddEvent:通过mask修改或者添加fd对应Event的EPOLLIN或EPOLLOUT(epoll_ctl)。

aeApiDelEvent:通过mask修改或者删除fd对应Event的EPOLLIN或EPOLLOUT(epoll_ctl)。

aeApiPoll:epoll_wait等待内核返回事件集合,填写fire事件集合用于回调AE_READABLE和AE_WRITABLE对应函数。

aeApiName:取得I/O模型字符串名称("select"、"epoll"、"kqueue")。

3、 EventLoop层(Ae.h(117)、Ae.c(405))

(1)回调函数指针

typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);

typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);

typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);

typedef void aeBeforeSleepProc(struct aeEventLoop *eventLoop);

(2)Event Struct

aeFileEvent:读写事件回调。

aeTimeEvent:定时器事件回调。

aeFiredEvent:触发事件回调。

aeEventLoop:主事件,包含读写事件、定时器事件、触发事件列表。

(3)Event接口API

aeCreateEventLoop:创建EventLoop。

aeDeleteEventLoop:删除EventLoop。

aeStop:置EventLoop stop标志。

aeCreateFileEvent:添加关注事件。

aeDeleteFileEvent:删除关注事件。

aeGetFileEvents:获取事件mask

aeGetTime:获取当前时间。

aeAddMillisecondsToNow:增加毫秒数当前时间的秒和毫秒上。

aeCreateTimeEvent:添加定时器事件。

aeDeleteTimeEvent:删除定时器事件。

SearchNearestTimer:搜索最近的定时器。

processTimeEvents:处理定时器事件,回调函数返回AE_NOMORE(-1)则删除定时器,否则更新定时器时间为回调函数返回的时间。

aeProcessEvents:处理各种事件,用最近定时器即将到来的时间作为epoll_wait的超时间,非常巧妙,如果马上到就立即返回,否则超时间到再返回。

aeMain:主main,while循环直到eventLoop->stop不为0,在调用aeProcessEvents前,先回调aeBeforeSleepProc。

aeGetApiName:获取I/O模型字符串名称("select"、"epoll"、"kqueue")。

aeSetBeforeSleepProc:设置aeBeforeSleepProc回调函数。

4、 Networking层(Networking.c(1334))

暂不表与网络层无直接关系的接口函数。

createClient:创建redisClient,有连接则设置fd为nonblocking,设置TCP_NODELAY,设置AE_READABLE对应的回调函数readQueryFromClient。

prepareClientToWrite:在发送数据给客户端时的预处理,即可以发送数据时设置AE_WRITABLE对应的回调函数sendReplyToClient;是REDIS_LUA_CLIENT时返回REDIS_OK;是fake client或者slave或者setup write handler failed时返回REDIS_ERR。

acceptCommonHandler:调用createClient,校验是否达到最大客户端数。

acceptTcpHandler:针对TCP依次调用anetTcpAccept、acceptCommonHandler。

acceptUnixHandler:针对Unix,作用同acceptTcpHandler。

freeClient:释放redisClient,删除AE_READABLE、AE_WRITABLE,断开master/slave,清除MULTI/EXEC state等。

sendReplyToClient:发送数据的回调函数,处理write逻辑。

readQueryFromClient:接收数据的回调函数,处理read逻辑。

还有一大票addReply…和get…,在此略去。