多进程架构
Redis 线程架构
单进程架构
我们在使用 Redis 的时候,通常是多个客户端连接 Redis 服务器,然后各自发送命令请求(例如 Get、Set)到 Redis 服务器,最后 Redis 处理这些请求返回结果。Redis 除了处理客户端的命令请求还有诸如 RDB 持久化、AOF 重写这样的事情要做,而在做这些事情的时候,Redis 会 fork 子进程去完成。但对于 accept 客户端连接、处理客户端请求、返回命令结果等等这些,Redis 是使用主进程及主线程来完成的。
Reactor 架构
Redis 如此高效的原因就是其使用了 IO 多路复用的模式 Reactor。首先,Redis 服务器中有两类事件,文件事件和时间事件:
- 文件事件(file event):Redis 客户端通过 socket 与 Redis 服务器连接,而文件事件就是服务器对套接字操作的抽象。例如,客户端发了一个 GET 命令请求,对于 Redis 服务器来说就是一个文件事件。
- 时间事件(time event):服务器定时或周期性执行的事件。例如,定期执行 RDB 持久化。
在这个模型中,Redis 服务器用主线程执行 IO 多路复用程序、文件事件分派器以及事件处理器。而且,尽管多个文件事件可能会并发出现,Redis 服务器是顺序处理各个文件事件的。Redis 服务器主线程的执行流程在 Redis.c 的 main 函数中体现,而关于处理文件事件的主要的有这几行:
int main(int argc, char **argv) {
...
initServer();
...
aeMain();
...
aeDeleteEventLoop(server.el);
return 0;
}
在 initServer()
中,建立各个事件处理器;在 aeMain()
中,执行事件处理循环;在 aeDeleteEventLoop(server.el)
中关闭停止事件处理循环;最后退出。