单线程的 Redis 为什么那么快

Redis 服务器端只需要单线程可以达到非常高的处理能力,每秒可以达到数万 QPS 的高处理能力。如此高性能的程序其实就是对 Linux 提供的多路复用机制 epoll 的一个较为完美的运用而已。

在 Redis 源码中,核心逻辑其实就是两个,一个是 initServer 启动服务,另外一个就是 aeMain 事件循环。把这两个函数弄懂了,Redis 就吃透一大半了。

//file: src/server.c
int main(int argc, char **argv) {
    ......
    // 启动初始化
    initServer();
    // 运行事件处理循环,一直到服务器关闭为止
    aeMain(server.el);
}

在 initServer 这个函数内,Redis 做了这么三件重要的事情。

创建一个 epoll 对象
对配置的监听端口进行 listen
把 listen socket 让 epoll 给管理起来
在 aeMain 函数中,是一个无休止的循环,它是 Redis 中最重要的部分。在每一次的循环中,要做的事情可以总结为如下图。

深度解析单线程的 Redis 如何做到每秒数万 QPS 的超高处理能力!_面试_11

通过 epoll_wait 发现 listen socket 以及其它连接上的可读、可写事件
若发现 listen socket 上有新连接到达,则接收新连接,并追加到 epoll 中进行管理
若发现其它 socket 上有命令请求到达,则读取和处理命令,把命令结果写到缓存中,加入写任务队列
每一次进入 epoll_wait 前都调用 beforesleep 来将写任务队列中的数据实际进行发送

其实事件分发器还处理了一个不明显的逻辑,那就是如果 beforesleep 在将结果写回给客户端的时候,如果由于内核 socket 发送缓存区过小而导致不能一次发送完毕的时候,也会注册一个写事件处理器。等到 epoll_wait 发现对应的 socket 可写的时候,再执行 write 写处理。

详细请转到https://blog.51cto.com/u_13626762/5321467

posted @ 2022-08-22 10:47  剑心空明  阅读(0)  评论(0编辑  收藏  举报  来源