情景复现

面试官: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. springboot 前端访问服务器上的图片及附件

    一.需求 后端是springboot,附件上传到服务器上,前端访问服务器上的附件,如:显示图片.视频.文件等 二.解决方法 springboot 中进行资源映射,根据路径将磁盘上的文件映射为资源返回到 ...

  2. 云上分布式SQL Server,你值得拥有

    云上分布式SQL Server,你值得拥有 介绍Microsoft SQL Azure 是微软的云关系型数据库,后端存储又称为云 SQL Server(Cloud SQL Server).它构建在 S ...

  3. DQL—查询操作

    一.查询语法 select 字段列表 from 表名列表 where 条件列表 group by 分组列表 having 分组后条件 order by 排序字段 limit 分页限定 (提供一个表来操 ...

  4. Cookie——基本使用

    Cookie 基本使用      Cookie 原理 Cookie 使用细节 Cookie jsp中获取Cookie

  5. AE cc 2017 和 2018 中英文切换的方法

    AE cc 2017中文切换英文的方法 找到AE的安装文件目录下的"Support Files"文件夹,路径为 C:\Program Files\Adobe\Adobe After ...

  6. C++中指针和数组相关的运算符优先级

    概述 本文深入介绍了与指针和数组相关的运算符优先级,利用代码示例展示了当左结合和右结合运算符同时存在时的结合方式,同时也演示了如何使用()来强制人为指定结合顺序. 指针.数组相关的运算符优先级 下表展 ...

  7. 树莓派2 CentOS7.9 环境下编译 ZLMediaKit 备忘录

    查询系统架构 getconf LONG_BIT 查看是32 或 64位 arch uname -m 输出"x86_64"则为64位,输出"i686"或" ...

  8. Excel488个函数一览

    目录: 常用函数 Web 函数 财务函数 查找和引用函数 多维数据集函数 工程函数 兼容性函数 逻辑函数 日期和时间函数 数据库函数 数学和三角函数 统计函数 文本函数 信息函数 与加载项一起安装的用 ...

  9. springboot admin 整合nacos,context-path问题

    1.在使用springboot admin 整合nacos时发现问题,springboot admin server访问admin client的默认地址为http://ip:port/actuato ...

  10. DRF-Version组件源码分析

    1. 版本管理组件源码分析 注意点: 不同的versioning_class区别:实例化后得到的对象versioning_scheme里面的方法不同(函数同名,但是处理逻辑不同) def determ ...