redis源码:整体框架
redis是一个独立的进程,通过socket链接为其他进程提供内存存储服务,类似的memcached。
redis的几个特点:
- 独立进程,其他进程通过socket链接访问,相对的是sqlite数据库。
- 数据全部存放在内存中,相对的是mysql,ssdb。
- 单线程异步io,相对memcached多线程。
各种初始化
一个全局的 server 对象表示整个server。
struct redisServer server;
事件循环
typedef struct aeEventLoop {
int maxfd; /* highest file descriptor currently registered */
int setsize; /* max number of file descriptors tracked */
long long timeEventNextId;
aeFileEvent *events; /* Registered events */
aeFiredEvent *fired; /* Fired events */
aeTimeEvent *timeEventHead;
int stop;
void *apidata; /* This is used for polling API specific data */
aeBeforeSleepProc *beforesleep;
aeBeforeSleepProc *aftersleep;
int flags;
} aeEventLoop;
具体的实现在 ae_epoll.c ae_evport.c ae_kqueue.c ae_select.c 中。
/* Include the best multiplexing layer supported by this system.
* The following should be ordered by performances, descending. */
#ifdef HAVE_EVPORT
#include "ae_evport.c"
#else
#ifdef HAVE_EPOLL
#include "ae_epoll.c"
#else
#ifdef HAVE_KQUEUE
#include "ae_kqueue.c"
#else
#include "ae_select.c"
#endif
#endif
#endif
提供以下几个接口:
int aeApiCreate(aeEventLoop *eventLoop)
int aeApiResize(aeEventLoop *eventLoop, int setsize)
void aeApiFree(aeEventLoop *eventLoop)
int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)
void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask)
int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)
IO多路复用的需求是,服务器进程监听多个事件源(文件描述符,socket套接字,定时器等), 进程本身一直在while循环poll事件。
- 事件源都是非阻塞的,所以这个poll过程是阻塞的,还是非阻塞的,如果是非阻塞的,为什么要timeout。
- select,poll,epoll等各种IO多路复用的的核心点就在于poll的效率。
aeMain 开始while循环,监听客户端的连接。
void aeMain(aeEventLoop *eventLoop) {
eventLoop->stop = 0;
while (!eventLoop->stop) {
aeProcessEvents(eventLoop, AE_ALL_EVENTS|
AE_CALL_BEFORE_SLEEP|
AE_CALL_AFTER_SLEEP);
}
}
开始事件循环:接受新的连接和处理已有连接的事件。
目录
2019/11/16