Redis 与 I/O 多路复用模型

常说 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 在单线程架构的基础上同时为多个客户端提供服务。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值