基于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)
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的东西,待我上传给大家看看。
版权声明:本文博主原创文章。博客,未经同意不得转载。