写点什么

Redis 与 I/O 多路复用模型

用户头像
学个球
关注
发布于: 2021 年 03 月 06 日

常说 Redis 利用 I/O 多路复用,单线程处理来自许多客户端的网络请求。本文简单的从网络通信、I/O 模型、Redis 大致如何利用 I/O 多路复用模型了解下相关知识。

什么是 socket ?

socket 网络模型的基本函数

  • socket(),为了进行网络 I/O 通信,进程必须做的第一件事情就是调用 socket() 函数,指定期望的通信协议类型等。socket() 调用成功会返回一个非负整数值,称为 sockfd,一般称作特指 socket 的文件描述符

  • connect(),客户端通过调用 connect() 函数来请求连接。

  • bind(),绑定 socket 和给定的地址和端口。如果服务端或者客户端没有调用 bind() 进行绑定,当调用 connect() 或 listen() 时,内核会为相应的 socket 选择一个临时端口。对于服务端来说,因为需要对外提供服务,所以服务端一般会主动调用 bind() 指定特定的端口和 socket 绑定来对外提供服务。

  • listen(),当通过 socket() 创建一个新的 socket 时,一般这个 socket 被称为主动套接字,也就是说该套接字被看作可能调用 connect() 函数发起连接请求的。在向一个未连接的套接字调用 listen() 函数后,套接字转换为被动套接字,内核就知道应该接受指向该套接字的连接请求。

int listen(int sockfd, int backlog);
复制代码

其中的第二个参数 backlog 定义了可以为当前套接字进行连接的最大队列数。也就是说,如果客户端连接请求到达时,该套接字的处理队列长度达到 backlog 时,返回 error。

 

  • accept(),accept() 会从待处理连接队列头中取出连接请求,并在传入的第一个参数 sockfd 指向的监听套接字(或者说被动套接字)上创建一个新的已连接套接字,返回的 int 就是指向生成新套接字的 sockfd。原本的监听套接字不受影响。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
复制代码

 

内核会为服务器对每个客户端的连接创建一个已连接套接字,且当服务结束后,相应的已连接套接字会被关闭(服务端的监听套接字一般持续存在)。

5 种 I/O 模型

https://notes.shichao.io/unp/ch6/#io-models

  • 阻塞 I/O

  • 非阻塞 I/O

  • I/O 复用

  • 信号驱动 I/O

  • 异步 I/O

阻塞 I/O 模型



I/O 多路复用模型


在这个模型里,程序会阻塞在 select 调用上。select 函数允许程序同时监听多个 fd 的就绪状态。

select/poll/epoll, kqueue 等调用

Redis 与 I/O 多路复用模型

通常我们说 Redis 采用单线程架构且提供高并发访问。这里说的单线程其实是指 Redis 对于命令执行和网络 I/O 处理采用单个主线程。但是像 bgsave 等功能其实会使用到其他进程。

在 Redis 6.0 中,Redis 对网络请求模块采用了多线程处理

 

Redis 采用 Client/Server 访问架构,需要同时处理许多来自外部客户端的请求, Redis Server 会为每个客户端在本地维护一个对应的 socket。Redis 通过统一封装不同支持 I/O 多路复用的系统函数供上层使用,比如 select/epoll,kqueue 等系统调用,在不同平台上提供服务。即 Redis 不阻塞在单一的 sockfd 读写等待上,而是同时监听多个 sockfd 的就绪状态,不断处理就绪可处理的 sockfd。

Redis - file event handler

具体来说,Redis 通过自己的文件事件处理器来实现相关的功能。

  • I/O 多路复用程序同时监听多个 sockfd,当其中有 sockfd 准备就绪(产生对应的事件),I/O 多路复用程序将就绪的 sockfd 放入准备好的队列,同步有序地一个一个将套接字给 file event dispatcher。

  • file event dispatcher 根据传来的对应事件分配给对应的事件处理器进行处理。

 


总结

Redis 通过利用 I/O 多路复用模型,结合简洁的模块设置,让 Redis 在单线程架构的基础上同时为多个客户端提供服务。

 

发布于: 2021 年 03 月 06 日阅读数: 27
用户头像

学个球

关注

还未添加个人签名 2017.11.15 加入

还未添加个人简介

评论

发布
暂无评论
Redis 与 I/O 多路复用模型