//file:src/networking.cint writeToClient(int fd, client *c, int handler_installed) {while(clientHasPendingReplies(c)) {// 先发送固定缓冲区if (c->bufpos > 0) {nwritten = write(fd,c->buf+c->sentlen,c->bufpos-c->sentlen);if (nwritten <= 0) break;......// 再发送回复链表中数据} else {o = listNodeValue(listFirst(c->reply));nwritten = write(fd, o->buf + c->sentlen, objlen - c->sentlen);......}}}writeToClient 中的主要逻辑就是调用 write 系统调用让内核帮其把数据发送出去即可 。由于每个命令的处理结果大小是不固定的 。所以 Redis 采用的做法用固定的 buf + 可变链表来储存结果字符串 。这里自然发送的时候就需要分别对固定缓存区和链表来进行发送了 。
四、高性能 Redis 网络原理总结Redis 服务器端只需要单线程可以达到非常高的处理能力 , 每秒可以达到数万 QPS 的高处理能力 。如此高性能的程序其实就是对 Linux 提供的多路复用机制 epoll 的一个较为完美的运用而已 。
在 Redis 源码中 , 核心逻辑其实就是两个 , 一个是 initServer 启动服务 , 另外一个就是 aeMain 事件循环 。把这两个函数弄懂了 , Redis 就吃透一大半了 。
//file: src/server.cint main(int argc, char **argv) {......// 启动初始化initServer();// 运行事件处理循环 , 一直到服务器关闭为止aeMain(server.el);}在 initServer 这个函数内 , Redis 做了这么三件重要的事情 。
- 创建一个 epoll 对象
- 对配置的监听端口进行 listen
- 把 listen socket 让 epoll 给管理起来

文章插图
- 通过 epoll_wait 发现 listen socket 以及其它连接上的可读、可写事件
- 若发现 listen socket 上有新连接到达 , 则接收新连接 , 并追加到 epoll 中进行管理
- 若发现其它 socket 上有命令请求到达 , 则读取和处理命令 , 把命令结果写到缓存中 , 加入写任务队列
- 每一次进入 epoll_wait 前都调用 beforesleep 来将写任务队列中的数据实际进行发送
整个 Redis 的网络核心模块就在咱们这一篇文章中都叙述透了(剩下的 Redis 就是对各种数据结构的建立和处理了) 。相信吃透这一篇对于你对网络编程的理解会有极大的帮助!
还等什么 , 快把这篇文章也分享给你身边和你一样爱好深度技术的好友吧!
推荐阅读
- |3款网红“卸妆油”深度测评:MAC温和不刺激,植村秀虽贵但真好用
- 红茶喝上火吗,秋天上火喝红茶好吗
- 对联谜语答案及解析?对联猜谜大全及答案简单的
- 《亚瑟王的荣耀》铭文解析
- 冬天喝祁门红茶,祁门红茶女人喝好吗
- 茶香门第红茶,红茶的产地
- 迪奥香水广告解析
- 解析:书房风水为何不宜向阳
- 详细解析:书房风水挂什么字画好
- 姜文《让子弹飞》深度影评?姜文评价让子弹飞
