基于redis AE异步网络架构

最近的研究已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);
}


     /* server监听redisclient的连接 */
     aeCreateFileEvent(proxy.eventLoop, proxy.server_fd, AE_READABLE, on_client_connected, NULL);

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



以上就是一个简单的演示样例。

我写了一个类redisprox的东西,待我上传给大家看看。









版权声明:本文博主原创文章。博客,未经同意不得转载。

posted @ 2015-09-29 20:45  hrhguanli  阅读(348)  评论(0编辑  收藏  举报