您的位置:首页 > 数据库 > Redis

redis系列-事件

2017-06-27 20:00 148 查看

事件类型

redis有2种事件:时间事件和文件时间。

redis没有使用操作系统的定时器,而是自己时间了一套时间机制,这套机制用时间事件来管理。文件事件则是套接字IO相关的事件。

数据结构



事件核心管理器是aeEventLoop,结构中有时间事件链表头指针、文件事件句柄、事件前处理接口等信息。

redis启动时,会分配这么一个事件管理器,同时分配一个长度为N的文件事件数组,N的值为客户端最大数量(默认为10000)+128(32个位预留的),

文件事件

在事件管理器aeEventLoop中,与文件事件相关的变量如下:

typedef struct aeEventLoop {
int maxfd; /* highest file descriptor currently registered */
int setsize; /* max number of file descriptors tracked */
aeFileEvent *events; /* Registered events */
aeFiredEvent *fired; /* Fired events */
void *apidata; /* This is used for polling API specific data */
} aeEventLoop;maxfd:当前已经使用的最大的文件事件id,也即文件事件数组索引
setsize:events数组大小

events:文件事件数组,所有的文件事件都在这里

fired:文件数据数组,用于保存从epoll/select中返回的实际发生的文件事件

每当创建一个文件事件时,根据事件id从events占据一个元素,并设置该元素的mask、读回调方法、写回调方法等。当epoll等返回已经发生的事件时,通过fired数组返回

这里只分析IO复用使用epoll的情况,epoll_wait超时或者有事件发生时返回,遍历所有epoll_event事件,从中取出文件描述符,并且将事件类型转换为redis的文件事件(例如EPOLLIN对应AE_READABLE,EPOLLOUT、EPOLLERR、EPOLLHUP都对应AE_WRITABLE),保存到fired中对应的事件。

分配events数组时,默认长度是10128,其中10000是客户端最大数量,调用epoll_create创建epoll时,入参是1024,远远低于客户端数量,经过查资料才知道,epoll_create的入参在linux2.4之前用于分配hash保存文件句柄,而linux2.6之后epoll采用红黑树保存句柄,因此不需要明确长度,因此epoll支撑的文件句柄将会非常多

时间事件

时间事件处理比较简单,遍历时间列表,找出距离当前时间最近的定时器,将时间差换算为timeval结构,作为IO复用接口等待的时间。这样设计有2个好处:

1.如果有事件发生在超时之前,则进程不需要继续睡觉就能立刻处理事件。处理完事件也会继续处理时间事件,避免定时器被“饿”着

2.如果在时间超时后依然没有事件发生,redis也可以从容处理定时器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐