redis的I/O多路复用技术原理解析

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: Redis高性能源于内存存储、单线程模型、I/O多路复用及优化数据结构。其核心通过epoll实现非阻塞多路复用,以事件驱动高效处理高并发连接,结合SDS、跳表等结构,极致提升响应速度与资源利用率。

redis能够达到每秒10万+ QPS(每秒查询率)的极高性能,并非只因为它是“内存数据库”,而是由存储介质、线程模型、网络模型以及数据结构优化共同决定的。
以下是redis快的具体原因:
绝大部分请求在内存中完成

这是 Redis 快的根本原因。相比于传统数据库(如 MySQL)需要从磁盘读取数据,Redis 直接操作RAM(内存)。

存储介质 访问速度(数量级) 延迟说明
内存 (RAM) 纳秒 (ns) 极快,就像从书桌上拿书。
固态硬盘 (SSD) 微秒 (μs) 较快,但比内存慢 1000 倍。
机械硬盘 (HDD) 毫秒 (ms) 慢,就像去图书馆借书。

Redis 避免了磁盘 I/O 产生的巨大开销,数据操作几乎是瞬时的。
纯粹的单线程模型

很多人误以为多线程才快,但 Redis 的核心处理逻辑是单线程的(主要指文件事件分路器处理请求的部分)。

没有上下文切换:多线程在切换执行流时需要保存和加载 CPU 寄存器状态,这会产生明显的性能损耗。
没有锁的竞争:在多线程环境下,为了保证数据安全,必须引入锁(如互斥锁)。Redis 单线程执行,天然避免了死锁和锁竞争带来的开销。
简单即高效:单线程代码逻辑更简单,也更容易维护。
注意: Redis6.0引入了多线程来处理网络I/O,但执行命令的核心逻辑依然是单线程的。

非阻塞I/O多路复用 (I/O Multiplexing)

Redis 使用了I/O多路复用技术(如 Linux 下的 epoll)来处理大量的并发连接。

原理:Redis并不是为一个连接分配一个线程,而是让一个线程监控数千个连接的状态。只有当某个连接真正有数据发过来时,Redis才会去处理。
效果:即使有成千上万个客户端同时连接,Redis 也能像一个老练的服务员同时照顾几十桌客人一样,谁叫就服务谁,而不需要在桌子之间来回空跑。

针对性优化的底层数据结构

Redis的开发者对每种数据类型都进行了极致的底层优化,并没有简单地使用编程语言内置的结构。

SDS (简单动态字符串):相比 C 语言原生字符串,获取长度的时间复杂度从O(N)降到了O(1),且减少了内存分配次数。
跳表 (SkipList):为有序集合 (ZSet) 提供平衡树一般的查找效率,但实现更简单,支持范围查询更高效。
压缩列表 (ZipList) / 整型数组: 在数据量较小时使用紧凑存储,极大节省了内存开销,提高了 CPU 缓存命中率。

总结:

Redis的快可以总结为:基于内存操作 + 单线程 + 多路复用的并发 + 极致优化的底层数据结构。
详细说一下I/O多路复用
I/O多路复用(I/O Multiplexing)是现代高性能网络服务器(如 Nginx, Redis, Node.js)的核心基石。简单来说,它是一种 让单个线程能够同时监控多个网络连接(文件描述符) 的技术。

I/O多路复用解决了“高并发下的线程开销问题”。
在没有这项技术前,我们要支撑 1 万个并发连接,可能需要启动1万个线程,这会导致内存耗尽和CPU频繁的上下文切换。
有了 I/O 多路复用(尤其是 epoll),我们可以用一个线程轻松管理成千上万个连接,极大提升了系统的吞吐量。

举例理解:

假设一家餐厅有 100 桌客人:

阻塞 I/O (Blocking I/O): 一个服务员盯一桌客人。客人不点菜,服务员就死等。要服务 100 桌,就得请 100 个服务员。(开销巨大,线程切换成本高)
非阻塞 I/O (Non-blocking I/O): 一个服务员在 100 桌之间不停轮询:“点菜吗?”“不点。”“点菜吗?”“不点。” (效率低下,CPU 全在跑无意义的询问)
I/O 多路复用: 服务员在前台放一个呼叫器。哪桌客人想点菜了,就按一下呼叫器,呼叫器亮起对应的桌号。服务员只需要盯着这个呼叫器,哪桌亮了去哪桌。 (这就是 I/O 多路复用)

三种核心实现机制

在Linux中,I/O 多路复用经历了从select 到 poll 再到 epoll的演进。
select:select 是最早的实现。它维护一个存放文件描述符(FD)的集合。

工作方式:每次调用都要把整个集合从用户态拷贝到内核态,内核线性扫描所有 FD。
缺点:有1024的数量限制(硬编码)。由于是线性扫描,时间复杂度为 O(n),连接越多越慢。

poll:基本解决了数量限制问题。

工作方式:使用链表存储 FD。
缺点:依然需要遍历整个集合来找出哪个 FD 就绪,性能随连接数增加而线性下降。

epoll (Linux的终极武器)

epoll是目前Linux下处理百万级别并发的首选。它不再像select那样盲目扫描,而是采用事件通知机制。

深入解析epoll的原理

epoll的高效源于它在内核中维护了两个核心数据结构:
    红黑树 (RB-Tree):用于存储所有待监控的 FD。查找、插入、删除的时间复杂度都是O(log n)。
    就绪列表 (Ready List):这是一个双向链表。当某个FD有事件发生时,内核会通过回调机制将其放入这个列表中。
epoll的工作流程:
    epoll_create:在内核开辟一块空间,建立红黑树和就绪列表。
    epoll_ctl:向红黑树中添加或删除需要监控的连接。
    epoll_wait:线程只需检查就绪列表。如果列表为空,线程睡眠;如果有数据,直接处理列表里的FD。
    结论:无论你有100个还是100万个连接,epoll只关注活跃的连接,时间复杂度近似O(1)。

两种触发模式:LTvsET

在使用epoll时,有两个非常重要的触发模式,这直接影响代码逻辑:

模式 名称 表现
LT(Level Triggered) 水平触发(默认) 只要缓冲区里还有数据没读完,内核就会不断通知你。比较安全,不容易漏掉数据。
ET(Edge Triggered) 边缘触发 只有状态发生变化(数据从无到有)时才通知一次。极其高效,但要求开发者必须一次性读完所有数据,否则剩下的数据可能永远不会被处理。

相关文章
|
2月前
|
搜索推荐 关系型数据库 MySQL
PageAdmin CMS如何配置全文检索功能
全文检索是很多站点刚需,行业中全文检索的搜索引擎主要采用lucene或Elasticsearch ,数据推送到搜索引擎中是比较麻烦的事情,很多用Elasticsearch的用户会采用Binlog同步方式同步,但是现在推国产化,你用mysql还好,你用了国产数据库就噩梦,你让厂商给你配置一个同步那是不可能的,pageadmin内置的同步功能很好解决这个痛点,下面演示pageadmin的后台如何配置全文检索并推送数据到全文搜索引擎中。
|
监控 网络协议 Unix
go程序报错Unix syslog delivery error
记录一下问题出错原因
3316 0
|
16天前
|
安全 Linux 数据库
什么是CMS(网站管理系统),哪款 CMS适合你
本文阐述 CMS 定义及选择的六大核心考量,结合 PageAdmin、阿里云SaaS 建站实例给出实践建议,强调 CMS 选择无最优,唯有贴合实际需求才最合适。
|
22天前
|
数据可视化 数据管理 容器
PageAdmin CMS企业建站系统如何配置智能触发器功能
企业常需实现自动下线新闻、合同提成、服务续费提醒等自动化功能。传统开发成本高、维护难,而PageAdmin CMS的智能触发器通过可视化配置,无需代码即可高效实现各类自动任务,大幅提升运营效率。
|
1月前
|
数据可视化 前端开发 数据管理
PageAdmin cms内容管理系统智能表单使用说明
PageAdmin CMS 提供可视化表单与流程配置,支持自定义功能及数据管理,实现业务系统统一管理。
116 3
|
18天前
|
开发框架 弹性计算 运维
建站系统哪个好?2025年建站系统深度推荐与避坑指南
建站系统分传统CMS(如PageAdmin)、SaaS平台(如阿里云速成美站)和开发框架三类。选择时需权衡控制权、成本与效率,根据业务需求、技术能力和长期规划理性选型,优先验证可行性再迭代升级。
170 0
|
缓存 关系型数据库 MySQL
一文彻底弄懂MySQL优化之深度分页
【10月更文挑战第24天】本文深入探讨了 MySQL 深度分页的原理、常见问题及优化策略。首先解释了深度分页的概念及其带来的性能和资源问题。接着介绍了基于偏移量(OFFSET)和限制(LIMIT)以及基于游标的分页方法,并分析了它们的优缺点。最后,提出了多种优化策略,包括合理创建索引、优化查询语句和使用数据缓存,帮助提升分页查询的性能和系统稳定性。
1787 1
|
6月前
|
存储 前端开发 JavaScript
Cookie、Session、Token、JWT 是什么?万字图解带你一次搞懂!看完这篇,你连老奶奶都能教
HTTP 协议是无状态的,就像一个“健忘”的银行柜员,每次请求都像第一次见面。为解决这一问题,常用的技术包括 Cookie、Session 和 Token。Cookie 是浏览器存储的小数据,Session 将数据存在服务器,Token(如 JWT)则是自包含的无状态令牌,适合分布式和移动端。三者各有优劣,适用于不同场景。
598 0
Cookie、Session、Token、JWT 是什么?万字图解带你一次搞懂!看完这篇,你连老奶奶都能教
|
8月前
|
SQL 存储 缓存
海量数据分页查询效率低?一文解析阿里云AnalyticDB深分页优化方案
本文介绍了AnalyticDB(简称ADB)针对深分页问题的优化方案。深分页是指从海量数据中获取靠后页码的数据,常导致性能下降。ADB通过快照缓存技术解决此问题:首次查询生成结果集快照并缓存,后续分页请求直接读取缓存数据。该方案在数据导出、全量结果分页展示及业务报表并发控制等场景下表现出色。测试结果显示,相比普通分页查询,开启深分页优化后查询RT提升102倍,CPU使用率显著降低,峰值内存减少至原方案的几分之一。实际应用中,某互联网金融客户典型慢查询从30秒优化至0.5秒,性能提升60+倍。
652 1
|
Java Maven Spring
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)
这篇文章介绍了在IntelliJ IDEA社区版中创建Spring Boot项目的三种方法,特别强调了第三种方法的详细步骤。
13168 0
springboot学习一:idea社区版本创建springboot项目的三种方式(第三种为主)