基於redis AE的非同步網路架構

來源:互聯網
上載者:User

標籤:des   style   blog   使用   strong   資料   

最近一直在研究redis的源碼,redis的高效率令人佩服。

在我們的linux機器上,cpu型號為, 

Intel(R) Pentium(R) CPU G630 @ 2.70GHz
 Intel(R) Pentium(R) CPU G630 @ 2.70GHz


上 set,get 都能達到每秒鐘15W的請求處理量,真是佩服這代碼的效率。

前幾篇文章,主要是介紹了基本的代碼,比如字串處理,鏈表處理,hash等。這篇文章介紹網路的核心,基於事件反映的非同步網路架構。


非同步網路處理,是基於epoll的。epoll的分為兩種模式,水平觸發和邊緣觸發。ae使用了水平觸發,就是一旦有資料,epoll會一直通知,直到就讀取完成。而邊緣觸發則只通知一次。等到狀態改變才會去通知。具體可以到網上查閱。

1.結構體源碼解析

1.1讀寫事件結構體

/* File event structure */typedef struct aeFileEvent {    int mask; /* one of AE_(READABLE|WRITABLE) */    aeFileProc *rfileProc;    aeFileProc *wfileProc;    void *clientData;} aeFileEvent;

該結構體表示一個fd對應的事件處理函數和私人資料。當我們要註冊一個fd時間時,就會填充該結構體。

1.2 時間事件狗狗提

/* Time event structure */typedef struct aeTimeEvent {    long long id; /* time event identifier. */    long when_sec; /* seconds */    long when_ms; /* milliseconds */    aeTimeProc *timeProc;    aeEventFinalizerProc *finalizerProc;    void *clientData;    struct aeTimeEvent *next;} aeTimeEvent;

當我們註冊定時處理事件,會填充相應結構體,添加到數組裡

1.3 觸發的fd

/* A fired event */typedef struct aeFiredEvent {    int fd;    int mask;} aeFiredEvent;

該結構體表示一個fd對應的可讀可寫事件

1.4 ae事件的總結構體

/* State of an event based program */typedef struct aeEventLoop {    int maxfd;   /* highest file descriptor currently registered */    int setsize; /* max number of file descriptors tracked */    long long timeEventNextId;    time_t lastTime;     /* Used to detect system clock skew */    aeFileEvent *events; /* Registered events */    aeFiredEvent *fired; /* Fired events */    aeTimeEvent *timeEventHead;    int stop;    void *apidata; /* This is used for polling API specific data */    aeBeforeSleepProc *beforesleep;} aeEventLoop;


該結構體儲存了ae非同步事件的基本資料,比如fd大小,時間事件id,註冊的時間指標等。


2.ae_epoll 介面

2.1 epoll 結構體

typedef struct aeApiState {    int epfd;    struct epoll_event *events;} aeApiState;

提供epoll的變數定義,

epfd是通過epoll_create 建立。events表示epoll_wait允許監聽的數量。

填充aeApiState結構體。

static int aeApiCreate(aeEventLoop *eventLoop)


調用epoll_wait ,擷取我們關心的事件,

static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) 



2、api介面


1,建立eventloop

aeEventLoop *aeCreateEventLoop(int setsize)

2.添加事件

int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,        aeFileProc *proc, void *clientData)

3。刪除事件,

void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)

4。建立時間事件

long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,        aeTimeProc *proc, void *clientData,        aeEventFinalizerProc *finalizerProc)

5.刪除時間事件

int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id)




使用樣本


  //建立loop
    proxy.eventLoop = aeCreateEventLoop(DEFAULT_LOOP_SIZE);

//建立事件事件

if(aeCreateTimeEvent(proxy.eventLoop, 1, serverCron, NULL, NULL) == AE_ERR) 
{
printf("Can‘t create the serverCron time event\n");
exit(1);
}


     /* 伺服器監聽redis用戶端的串連 */
     aeCreateFileEvent(proxy.eventLoop, proxy.server_fd, AE_READABLE, on_client_connected, NULL);

   aeCreateFileEvent(proxy.eventLoop, proxy.evfd, AE_READABLE, reconnect_redis, NULL);



以上就是一個簡單的樣本。

我寫了一個類redisprox的東西,待我上傳給大家看看。









相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.