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水平觸發方式。
這三個庫的主要內容在前面的幾個文章中都介紹過。這裡不再太多描述。