redis代码结构之二net,main,event
1. 网络库
anet.c、networking.c:这两个文件主要实现与网络通信以及与client之间的交互处理。
1.1 anet.c
该文件封装了基本的网络socket操作(tcp、unixsock),我们这里通过调用者简单说明一下其中的函数。(有一些函数在当前还没有使用)
Server使用的函数:
int anetTcpServer(char *err, int port, char *bindaddr),该函数在initServer的时候被调用,它本身调用anetCreateSocket来创建一个socket fd(支持SO_REUSEADDR,阻塞IO),然后anetListen监听server指定的端口。
第二个server函数是int anetTcpAccept(char *err, int s, char *ip, int *port),该函数由acceptTcpHandler函数调用,即当前面的监听socket,收到一个client connect之后调用acceptTcpHandler函数来接收,并创建它们之前通信的client socket,并且创建一个redisClient对象createClient(fd),的该函数内部调用另外两个该文件的函数anetNonBlock(NULL,fd); anetTcpNoDelay(NULL,fd);将该socket设置为非阻塞的,并且禁止Nagle算法(即禁止将小报文合并为大报文后转发,而是直接发送小报文)。
另外int anetPeerToString(int fd, char *ip, int *port)用于将一个socket fd对应的ip及port找出来。
Client使用的函数:
int anetTcpConnect(char *err, char *addr, int port),创建一个socket fd并且与指定的server进行连接。并且该socket是阻塞的。
int anetTcpNonBlockConnect(char *err, char *addr, int port),该函数是由replication的slave使用的,它创建的是一个非阻塞的socket fd。|
小结,listen使用的是阻塞io,server connect使用的是非阻塞io;一般的client connect使用的是阻塞io,slave connect使用的是非阻塞io。其中的几个函数是关于unixsocket与tcpsocket一样,在当前版本中没有使用。
1.2 networking.c:见 http://blog.csdn.net/wudongxu/article/details/7005830
2. main
我们把redis的主框架文件及config的相关文件,以及字典操作相应的文件归为该模块。Redis的main函数以及servercron过程,我们已经在前面的文章中介绍过,而db.c及dict.c主要涉及几个重要数据结构的关系,见http://hi.csdn.net/attachment/201111/28/0_13224455853iSZ.gif
3. 事件库
该库包括ae.c,ae_epoll.c,ae_kqueue.c,ae_select.c,syncio.c。其中ae.c是负责整个服务的主要流程ae_epoll.c, ae_kqueue.c,ae_select.c则是三种不同的IO复用方式。默认使用的是epoll;syncio.c是用于阻塞IO的同步操作,该文件主要用于master-slave之间,以及migrate命令。
Redis在处理用户请求时使用的是非阻塞的io,并且使用LT水平触发方式。
这三个库的主要内容在前面的几个文章中都介绍过。这里不再太多描述。