情景复现

面试官:Redis为什么这么快?

我:1. 基于内存 2. 高效数据结构 3. 单线程 4. IO多路复用

面试官:那你讲讲Redis的IO多路复用模型是什么。

我:哦,嗯,啊,呀...IO多路复用、文件描述符、用户态,内核态、哦。

前置内容

Scoket



来源:http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/schedule.html

FD

内核对应已打开文件的索引

IO模型

阻塞IO、非阻塞IO、IO多路复用、信号驱动模型、异步IO

可以看看我的另一篇笔记:https://www.cnblogs.com/handsometaoa/p/17379850.html

Redis的IO多路复用模型是什么

I/O多路复用模型是什么?就是很多网络连接(多路),共(复)用少数几个(甚至是一个)线程。(来源:I/O多路复用技术(multiplexing)是什么?

Redis采用I/O多路复用机制,使得Redis在单线程模式下依然可以高效的处理多个I/O流。

其核心思想是,先通过 select / poll / epoll 等系统调用查询监听的文件描述符是否准备就绪,这个操作可阻塞也可立即返回(具体看参数和对应规则),当其中一个或者多个文件描述符IO事件准备就绪才开始下一步,即 read 或者 write 等系统调用,这里才是真正的读或者写。(来源:redis 的 IO 多路复用如何?

首先Redis IO多路复用采用 epoll 的实现方案,但是在了解 epoll 前先了解一下 selectpoll ,对后面理解更有帮助。

select

  1. 一个客户端与服务端连接时,会生成对应一个套接字描述符(fd)
  2. 进程会将fd加入进程维护的fd列表中,每次调用 select 都需要将 fd列表从用户态进程拷贝到内核,(当fd列表较大时,拷贝开销不可忽略,所以限制其大小为1024)
  3. 内核轮询fd列表,当无fd就绪时,进程阻塞。
  4. 当网络数据到达内核缓冲区时,网卡发出中断信号通知CPU,CPU收到中断信号,执行对应中断程序
  5. 中断程序将内核缓冲数据拷贝到对应文件描述符的接收缓冲区
  6. socket接收数据完毕后,中断程序将进程重新添加至工作队列,并将进程从等待队列中移除
  7. 进程重新进入工作队列,从阻塞处继续执行。

poll

  1. 创建pollfd数组,向其中添加关注的fd信息,数组大小自定义
  2. 调用poll函数,将pollfd数组拷贝到内核空间,转链表存储,无上限
  3. 内核遍历fd,判断是否就绪
  4. 数据就绪或超时后,拷贝pollfd数组到用户空间,返回就绪fd数量n
  5. 用户进程判断n是否大于0
  6. 大于0则遍历pollfd数组,找到就绪的fd

select与poll原理类似,结合一起看。

epoll

/**
* @param size epoll 要监听文件描述符个数
* @return 返回创建eventpoll对象文件描述符
*/
int epoll_create(int size); /**
* 事件注册
* @param epdf epoll_create()返回的文件描述符
* @param op 操作类型 1.新增 2.删除 3.更新
* @param fd 本次要操作文件描述符
* @param epoll_event 需要监听的事件:读事件、写事件
* @return 调用成功返回0,不成功返回-1
*/
int epoll_ctl(int epdf,int op,int fd,struct epoll_event *event ); /**
* 获取就绪事件
* @param epdf epoll_create()返回的文件描述符
* @param events 回传就绪事件
* @param maxevents 每次能处理最大事件数
* @param timeout 等待IO事件发生的超时时间 -1 阻塞 0 非阻塞
* @return 大于0 已就绪文件描述符数
*/
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
  1. 应用程序通过epoll_create系统调用创建一个epoll实例,得到一个文件描述符,用于后续的操作。
  2. 应用程序使用epoll_ctl系统调用将需要监听的文件描述符(socket、文件等)添加到epoll实例中,并关联相应的事件(读、写、异常)。
  3. 当应用程序调用epoll_wait系统调用时,操作系统会阻塞程序,等待任何一个注册的事件就绪。
  4. 当有事件就绪时,epoll_wait会返回,告诉应用程序哪些事件已经就绪。
  5. 应用程序可以通过遍历返回的事件列表,检查哪些事件已经就绪。
  6. 应用程序可以对就绪的事件进行处理,如读取数据、写入数据等。
  7. 应用程序可以再次调用epoll_wait来等待下一轮的事件就绪。

视频推荐:小白也看得懂的 I/O 多路复用解析(超详细案例)

推荐内容

Redis网络模型-IO多路复用

Linux IO模式及 select、poll、epoll详解

Redis为什么这么快之IO多路复用的更多相关文章

  1. 最快理解 - IO多路复用:select / poll / epoll 的区别.

    目录 第一个解决方案(多线程) 第二个解决方案(select) 第三个解决方案(poll) 最终解决方案(epoll) 客栈遇到的问题 从开始学习编程后,我就想开一个 Hello World 餐厅,由 ...

  2. IO多路复用?我所理解的IO模式

    1:IO的过程 当我们调用系统函数read时,一般会经历两个阶段: 1:等待数据准备(waiting for the data be ready) 2:将数组从内核拷贝到进程(从内核态到用户态)(co ...

  3. ⾼性能IO模型:为什么单线程Redis能那么快

      Redis是单线程,主要是指Redis的⽹络IO和键值对读写是由⼀个线程来完成的,这也是Redis对外提供键值存储服务的主要流程.但Redis的其他功能,⽐如持久化.异步删除.集群数据同步等,其实 ...

  4. 聊聊redis单线程为什么能做到高性能和io多路复用到底是个什么鬼

    1:io多路复用epoll  io多路复用简单来说就是一个线程处理多个网络请求 我们知道epoll in 的事件触发是可读了,这个比较好理解,比如一个连接过来,或者一个数据发送过来了,那么in事件就触 ...

  5. 为什么说Redis是单线程的以及Redis为什么这么快!

    参考文章:https://blog.csdn.net/xlgen157387/article/details/79470556 redis简介 Redis是一个开源的内存中的数据结构存储系统,它可以用 ...

  6. 为什么说Redis是单线程的以及Redis为什么这么快!(转)

    文章转自https://blog.csdn.net/chenyao1994/article/details/79491337 一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到 ...

  7. Redis性能解析--Redis为什么那么快?

    echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! Red ...

  8. 《为什么说Redis是单线程的以及Redis为什么这么快!》

    为什么说Redis是单线程的以及Redis为什么这么快!   一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓 ...

  9. [转帖]Redis性能解析--Redis为什么那么快?

    Redis性能解析--Redis为什么那么快? https://www.cnblogs.com/xlecho/p/11832118.html echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加e ...

  10. 为什么说Redis是单线程的以及Redis为什么这么快!(转)

    一.前言 近乎所有与Java相关的面试都会问到缓存的问题,基础一点的会问到什么是“二八定律”.什么是“热数据和冷数据”,复杂一点的会问到缓存雪崩.缓存穿透.缓存预热.缓存更新.缓存降级等问题,这些看似 ...

随机推荐

  1. canvas图片旋转扩展出原生JS实现移动端横竖屏手写签名示例

    前提知识 canvas是提供了各种各样的接口去控制画布,比如旋转rotate方法. 这里的旋转并不是真的把这个画布旋转了,例如ctx.rotate(90 * Math.PI / 180)顺时针旋转90 ...

  2. Angular 18+ 高级教程 – Component 组件 の @let Template Local Variables

    前言 Angular 在 v18.1 推出了 Template 新语法 @let. 这个 @let 和上一篇教的 Control Flow @if, @for, @swtich, @defer 语法上 ...

  3. mongo 副本集rs 理解和使用小结

    转载请注明出处: 在MongoDB中,rs(通常指的是"replica set"的缩写)是复制集(Replica Set)的标识符或在使用时的一种常见前缀,尤其是在命令行工具和脚本 ...

  4. CSP-J 2024游记

    CSP-J 2024游记 题目难度 总体来说,这次考试题目对于我这个初一牲难度不高.前面的选择题出现了少量难题(格蕾码). 选择题 选择题出现了一个搞人心态的BYD题目--格蕾码.这道题我蒙的, 阅读 ...

  5. 高通ADSP USB流程

    在高通平台上,ADSP(Audio Digital Signal Processor,音频数字信号处理器)可以通过 USB 接口与主机进行数据传输,以下是大致的 ADSP USB 流程: 主机发起 U ...

  6. pstore

    简介 pstore文件系统(是的,这是个文件系统)是Persistent Storage的缩写,最早在2010年由 Tony Luck 设计并合入Linux主分支,设计的初衷是在内核Panic/Oop ...

  7. C# 的运算符和作用域

    // C# 运算符 // 表达式 表达式有操作数(operand)和运算符(operator)构成: // 常见的运算符 + - * / 和 new // x ?? y 如果x为null, 则计算机过 ...

  8. ADO.NET 和 ORM的区别

    ADO: 1 大量的Sql语句-业务不同,Sql语句不同 2 需要根据不同的场景编写不同Sql语句-灵活去编写Sql语句-提前优化Sql 语句-提供高性能的Sql语句 3 不适合快速开发 4 可编程性 ...

  9. 图菱科技 SaaS 系统容器化最佳实践

    大家好,我是龚承明,在图菱(成都)科技有限公司任职,主要负责公司的产品系统研发以及公司IT基础设施的建设工作.本篇文章将为大家介绍下我司在采用 KubeSphere 平台实现公司业务系统容器化过程中的 ...

  10. 初探AI之got-ocr2.0大模型本地部署与遇到的各种坑处理

    一.环境搭建 1.安装cuda,本人使用的是12.1版本,下载地址:https://developer.nvidia.com/cuda-12-1-1-download-archive 2.安装cond ...