谈谈Redis中的多路复用

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 谈谈Redis中的多路复用

前言

redis是单线程的(不严谨的讲法的哈),为什么还这么快,很多人相信会回答因为redis是基于内存操作的, 内存的读写速度是非常快的。答到这,逼格还是不够高的,基于内存是一方面,但还有一个关键点是:redis采用了多路复用技术,今天我们就来聊聊这个点。

什么是多路服用

  • 多路:多个客户端连接
  • 复用:使用单进程就能够实现同时处理多个客户端的连接

它的基本原理就是不再由应用程序自己监视连接,而是由内核替应用程序监视文件描述符。客户端在操作的时候,会产生具有不同事件类型的 socket。在服务端,I/O 多路复用程序(I/O Multiplexing Module)会把消息放入队列中,然后通过文件事件分派器(Fileevent Dispatcher),转发到不同的事件处理器中。

可以想象一条高速公路,车辆在不同的车道上行驶,但它们共用同一条路。

I/O多路复用的本质是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符, 一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作

在Unix/Linux系统中,常用的IO多路复用机制有以下几种:

  • select:是最早引入的IO多路复用机制,通过select函数来监视多个文件描述符的状态变化,但其缺点是性能不高,同时对文件描述符的数量有一定的限制。
  • poll:是select的改进版本,没有了描述符数量的限制,但其性能仍然不是很高。
  • epoll:是Linux特有的IO多路复用机制,是目前性能最好的IO多路复用技术。它使用了事件驱动的方式,通过epoll_ctl函数注册文件描述符的事件,然后通过epoll_wait函数等待IO事件的发生。epoll在处理大量连接时具有更好的扩展性和性能。

epoll 最大的优点就在于它只管你“活跃”的连接 ,而跟连接总数无关,因此在实际的网络环境

中, epoll 的效率就会远远高于 select 和 poll 。 (redis 的iO模型默认采用epoll实现的。)

IO多路复用的主要优点包括:

  • 节省了线程/进程的创建和销毁开销,降低了系统资源的占用。
  • 可以实现高并发处理,提高系统的性能和吞吐量。
  • 编程模型相对简单,代码量较少,易于维护和管理。
select poll epoll
操作方式 遍历 遍历 回调
数据结构 bitmap 数组 红黑树
最大连接数 1024(x86)或者2048(x64) 无上限 无上限
最大支持文件描述符数 有最大值限制 65535 65535
fd拷贝 每次调用,都需要把fd结合从用户态拷贝到内核态 每次调用,都需要把fd结合从用户态拷贝到内核态 只有首次调用的时候拷贝
工作效率 每次都要遍历所有文件描述符,时间复杂度O(n) 每次都要遍历所有文件描述符,时间复杂度O(n) 每次只用遍历需要遍历的文件描述符,时间复杂度O(1)

Redis中的多路复用

Redis 是跑在单线程中,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以IO操作一般情况下往往不能直接返回,这会导致某一文件的I/O 阻塞导致整个进程无法对其他客户提供服务,I/O多路复用是为了解决这个问题而出现的。

Redis中的IO多路复用模式:

  • (1)一个 socket 客户端与服务端连接时,会生成对应一个套接字描述符(套接字描述符是文件描述符的一种),每一个 socket 网络连接其实都对应一个文件描述符。
  • (2)多个客户端与服务端连接时,Redis 使用 「I/O 多路复用程序」 将客户端 socket 对应的 FD 注册到监听列表(一个队列)中。当客服端执行 read、write 等操作命令时,I/O 多路复用程序会将命令封装成一个事件,并绑定到对应的 FD 上。
  • (3)「文件事件处理器」使用 I/O 多路复用模块同时监控多个文件描述符(fd)的读写情况,当 acceptreadwriteclose 文件事件产生时,文件事件处理器就会回调 FD 绑定的事件处理器进行处理相关命令操作。
  • (4)整个文件事件处理器是在单线程上运行的,但是通过 I/O 多路复用模块的引入,实现了同时对多个 FD 读写的监控,当其中一个 client 端达到写或读的状态,文件事件处理器就马上执行,从而就不会出现 I/O 堵塞的问题,提高了网络通信的性能。

这种IO多路复用机制能够有效地减少系统调用和上下文切换的开销,提高了Redis的性能和并发能力。同时,由于采用了非阻塞IO模型,Redis能够处理大量的连接而不会造成线程堵塞,提高了系统的可伸缩性。

Redis单线程?多线程

Redis 在处理客户端的请求时,包括获取 (socket 读)、解析、执⾏、内容返回 (socket 写) 等都由⼀个顺序串⾏的主线程处理,这就是所谓的「单线程」

Redis是单线程来执行命令的,每一条到达读服务端的命令并不会立即执行,所有的命令都会进入一个 socket 任务队列中,当 socket 可读则交给单线程事件分发器逐个被执行,即一个线程处理所有网络请求

Redis 采⽤多个 IO 线程来处理⽹络请求,提⾼⽹络请求处理的并⾏度。Redis 多 IO 线程模型只⽤来处理处理网络数据的读写和协议解析,对于 Redis 的读写命令,依然是单线程处理。

因为网络 I/O 在 Redis 执行期间占用了大部分 CPU 时间, 所以把网络 I/O 部分单独抽离出来, 做成多线程的方式。这里所说的多线程, 其实就是将 Redis 单线程中做的这两件事情"从客户端读取数据、回写数据给客户端"(也可以称为网络 I/O), 处理成多线程的方式, 但是"执行 Redis 命令"还是在主线程中串行执行, 这个逻辑保持不变


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 缓存 NoSQL
Redis常见面试题(二):redis分布式锁、redisson、主从一致性、Redlock红锁;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
redis分布式锁、redisson、可重入、主从一致性、WatchDog、Redlock红锁、zookeeper;Redis集群、主从复制,全量同步、增量同步;哨兵,分片集群,Redis为什么这么快,I/O多路复用模型——用户空间和内核空间、阻塞IO、非阻塞IO、IO多路复用,Redis网络模型
Redis常见面试题(二):redis分布式锁、redisson、主从一致性、Redlock红锁;Redis集群、主从复制,哨兵模式,分片集群;Redis为什么这么快,I/O多路复用模型
|
5月前
|
存储 NoSQL Linux
Redis入门到通关之多路复用详解
Redis入门到通关之多路复用详解
55 1
|
5月前
|
NoSQL 架构师 网络协议
Redis系列-15.Redis的IO多路复用原理解析(上)
Redis系列-15.Redis的IO多路复用原理解析
268 1
|
5月前
|
NoSQL Linux 应用服务中间件
Redis系列-15.Redis的IO多路复用原理解析(下)
Redis系列-15.Redis的IO多路复用原理解析
125 0
|
存储 设计模式 监控
【Redis原理机制 一】Redis高性能原因、单线程模型及多路复用技术
【Redis原理机制 一】Redis高性能原因、单线程模型及多路复用技术
229 0
|
NoSQL Java Linux
大话Redis系列--深入探讨多路复用(上)
大话Redis系列--深入探讨多路复用(上)
346 0
|
NoSQL Linux API
一文搞懂 Redis高性能之IO多路复用
相信大家在面试过程中经常会被问到:“单线程的Redis为啥这么快?” 哈哈,反正我在面试时候经常会问候选人这个问题,这个问题其实是对redis内部机制的一个考察,可以牵扯出好多涉及底层深入原理的一些列问题。
一文搞懂 Redis高性能之IO多路复用
|
NoSQL 安全 大数据
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(三)
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(三)
157 0
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(三)
|
设计模式 NoSQL Unix
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(二)
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(二)
159 0
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(二)
|
NoSQL Redis
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(一)
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(一)
145 0
REDIS01_单线程的概述、多线程的引入、概述IO多路复用、如何开启多线程(一)
下一篇
无影云桌面