Redis -- 10 -- IO多路复用模型

相关文章:


Redis 的性能十分高效,根据官方文档 (How fast is Redis?),当客户端连接较少时,Redis 的查询效率能高达 110000 QPS;当客户端连接较多时 (如:60000 个连接),Redis 仍能够维持 50000 QPS

在这里插入图片描述

Redis 的性能之所以如此高效,主要是因为以下几点

  • 完全基于内存,绝大部分请求是纯粹的内存操作,效率高效

  • 数据结构简单,对数据的操作也简单

  • 采用单线程,避免了不必要的上下文切换和竞争条件

    • 所谓单线程,是指 Redis 在处理客户端请求时,只有一个线程来处理,而非整个 Redis 服务只有一个线程

    • 在 6.0 的版本中,Redis 引入了多线程,默认为禁用状态,如需开启,需要修改 redis.conf 配置文件 io-threads-do-reads yes;开启多线程后,同时还需要设置线程数 io-threads 4,否则多线程不会生效

  • 使用 IO 多路复用模型,非阻塞 IO


一、文件描述符

  • 在了解 I/O 多路复用模型之前,我们先来了解下 FD (File Descriptor,文件描述符)

    • 当程序打开一个现有文件或创建一个新文件时,内核会向进程返回一个文件描述符

    • 文件描述符在形式上是一个非负整数,是内核为了高效管理已被打开的文件所创建的索引,用于指向被打开的文件

    • 在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开,不过文件描述符这一概念往往仅适用于 UNIX、Linux 这样的操作系统


二、传统的 I/O 阻塞模型

  • 如果使用传统的 I/O 阻塞模型,当对某个文件描述符 FD 进行读写时,如果当前 FD 不可读或不可写,那么整个 Redis 服务就不能对其他操作做出相应,进而导致整个服务不可用

  • 传统的 I/O 阻塞模型是平常编程中使用最多的阻塞模型

    在这里插入图片描述


三、I/O 多路复用模型

  • I/O 多路复用模型

    • 是指使用 I/O 多路复用函数同时监听多个 FD 的读写情况,当空闲时,当前线程会被阻塞;当其中某些 FD 可读或可写时,当前线程会被唤醒,并去轮询所有的 FD (epoll 只会去轮询活跃可用的 FD),避免了大量的无用操作

      • 多路:指的是多个网络连接

      • 复用:指的是复用同一个线程,采用 I/O 多路复用模型可以让单个线程高效地处理多个连接请求

    • Redis 采用了 I/O 多路复用模型来提高效率

      在这里插入图片描述

  • I/O 多路复用函数

    函数 作用
    select 采用轮询方式来检测就绪事件,时间复杂度为 O(n)
    poll 采用轮询方式来检测就绪事件,时间复杂度为 O(n)
    epoll 采用回调方式来检测就绪事件,时间复杂度为 O(1)

四、Reactor 模式

  • Redis 基于 Reactor 模式实开发了自己的网络事件处理器,这个处理器被称为文件事件处理器 (file event handler)

  • 文件处理器采用 I/O 多路复用模型来同时监听多个 FD,当应答 (accept)、读取 (read)、写入 (write)、关 闭 (close) 等文件事件发生时,文件事件处理器就会回调 FD 绑定的事件处理器

  • 虽然文件事件处理器以单线程的方式运行,但是通过使用 I/O 多路复用模型,实现了同时对多个 FD 读写的监控,提高了网络通信模型的性能,同时也保证了整个 Redis 服务实现的简单


三、参考资料