有没有人和我一样, 自打知道了redis, 就一直听说什么redis单线程, 使用了多路复用等等. 天真的我以为多路复用是redis实现的技术. 今天才发现, 我被自己骗了, 多路复用是系统来实现的. 对不起自己的专业了.

为了引出多路复用, 我来大胆设想一下技术的发展路程.

前提

一个应用程序, 想对外提供服务, 一般都是通过建立套接字监听端口来实现, 也就是socket. 在这个时候, 应用对外提供服务的过程大概是这样.

  1. 创建套接字
  2. 绑定端口号
  3. 开始监听
  4. 当监听到连接时, 调用系统read去读取内容, 但是读取操作是阻塞的(也就是说,如果主线程处理read,就不能接收其他连接了, 所以只能开新的线程去处理这个事情)

画个丑丑的流程图:

问题分析

这个流程的问题很明显, 会不停的创建线程, 当然, 可以维护一个线程池. 但是线程之间的不停切换也是消耗资源的. 而且也不可能无限的创建线程. 那我如果想一个线程处理呢? 从上面流程图能看的出来, 问题出在阻塞上面. 如果read操作可以立刻返回结果, 如果没有读到数据, 就可以继续处理后边的事情了.

简版

整个简单版本. 主线程维护一个所有连接的列表, 每次循环读取所有列表, 有数据就处理, 没有就跳过.

  1. 创建套接字
  2. 绑定端口号
  3. 开始监听
  4. 监听到连接, 将连接加到连接列表中, 循环读取连接列表中的所有连接, 对有数据的进行处理

画个丑图:

问题分析

现在这样处理貌似是比开线程要好一些了, 但是事实是这样么? 众所周知, 其中的read操作是调用系统函数, 简单说就是要进行进程的切换, 从用户进程切换到系统进程. 连接少还好, 如果有十万个连接, 甚至更多呢? 每次循环都会频繁的调用系统函数, 可能十万次调用, 甚至其中有数据的只有一次, 其余调用都白掉了. 这无疑降低了性能.

其实解决方法说起来也很容易想到. 问题出在系统调用上, 频繁的系统调用导致了问题的出现. 如果能够一次性将需要查询的所有数据都发给系统, 让系统进行查询, 那不就只需要一次切换就可以了么?.

select版本

为了解决上面的问题. 可以批量将待查询的连接发给系统. 出现了select, 这就是说的 多路复用 了. 在系统 中, 无论是监听端口还是建立了连接, 程序拿到的都是一个文件描述符, 将这些文件描述符批量查询就是了.

直接上丑图:

这里和上一个版本相比, 将循环检查交到了系统去做, 只发生一次进程的切换. select 简单说, 就是你告诉系统, 你需要哪些数据, 你同帮你遍历找找, 然后将结果返回给你.

问题分析

这样确实要好上一些, 但是上面的问题还没有完全解决. 比如有10万个连接, 其中有数据的只有一个, 那就回有9999次无效的操作, 虽然这些无效的操作是由系统做的, 但不一样么, 系统做的无效操作, 你应用程序也得等着啊. 而且每次查询都要把所有的需要的都传过去, 10万个就要传10万了, 蓝瘦.

问题出在哪呢? 需要循环遍历, 是因为不知道哪些连接是有数据的, 所以只能一个一个的看. 如果可以不 需要遍历, 直接知道哪些连接是有数据的, 然后直接拿到数据返回就好了.

epoll

跟上一个版本相比, 现在不通过批量查询的方式了, 而是通过回调的方式. 简单说, 建立一个需要回调的连接, 将需要监听的文件描述符都扔给他, 当有新数据到达时, 会返回给你.

上丑图:

看着是不是有点晕了? 其实它和select版本的区别简单来说, epoll是将你需要监听的列表交给系统维护, 这样当有新数据来的时候, 系统知道这是你要的, 等你下次来拿的时候, 直接给你了, 少去了上面的系统遍历. 同时, 也没有select查询时那一大堆参数, 每次都只调用一次进行绑定即可.

那系统是怎么知道新数据的到来呢? 这里靠的是事件中断, 忘得差不多了, 回头再看看.

epoll 简单说就是, 你告诉系统, 你需要哪些数据, 然后等着, 有数据了系统就通知你, 然后你去读.


以上select, epoll是两种多路复用的技术, 当然, 还有多路复用还有其他的.

据说redis的多路复用对系统方法进行了封装, 不过我还没看, 再议!!!

redis的多路复用是什么鬼相关推荐

  1. Redis的多路复用机制

    Redis是单线程还是多线程? 通常我们所说的Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程.但 Red ...

  2. redis的多路复用原理

    redis服务端对于命令的处理是单线程的,但是在I/O层面却可以同时面对多个客户端并发的提供服务,并发到内部单线程的转化通过多路复用框架实现 一个IO操作的完整流程是数据请求先从用户态到内核态,也就是 ...

  3. Redis IO 多路复用机制

    Redis IO 多路复用机制 基于linux select/epoll select:最大支持1024个文件描述符,在描述符较多情况下性能较差,水平触发 poll:poll与select基本相同,只 ...

  4. Redis底层多路复用

    Redis6:第十二篇-多路复用相关问题 Redis的多路复用 什么是IO多路复用 文本事件 同步异步阻塞非阻塞 同步 异步 阻塞 非阻塞 四种组合方式 Unix操作系统底层的五种最重要的IO模型 B ...

  5. redis的多路复用

    腾讯面试被问得不知所措的一个问题 redis是一个单进程单线程的内存数据库,主要用来作为缓存系统.采用了网络io多路复用技术来保证在多连接的时候的系统的吞吐量 为什么redis使用io多路复用技术? ...

  6. Redis IO多路复用理解

    IO多路复用在Redis中的应用 Redis 服务器是一个事件驱动程序, 服务器处理的事件分为时间事件和文件事件两类. 文件事件:Redis主进程中,主要处理客户端的连接请求与相应. 时间事件:for ...

  7. redis nio 多路复用

    IO多路复用程序 socket进入队列 文件事件分发器 处理器

  8. Redis中的I/O 多路复用(I/O Multiplexing)

    I/O 指的是网络I/O. 多路指的是多个TCP 连接(Socket 或Channel). 复用指的是复用一个或多个线程. 它的基本原理就是不再由应用程序自己监视连接,而是由内核替应用程序监视文件描述 ...

  9. redis 十一. IO 多路复用

    目录 一. 基础 select poll epoll 二. redis 与多路复用 一. 基础 首先知道一下五种io模型有个概念 Blocking IO: 阻塞IO NoneBlockin IO: 非 ...

最新文章

  1. python sched_python事件调度库sched
  2. 『原创』再谈用 php 实现域名 whois 信息查询
  3. 给jdk写注释系列之jdk1.6容器(1):ArrayList源码解析
  4. HashSet/HashMap 存取值的过程
  5. GitLab远程仓库迁移
  6. SQL Stored Procedure Generator
  7. 大数据WEB阶段Spring框架(四)Spring-MVC
  8. 如何设置Fiddler来拦截Java代码发送的HTTP请求,进行各种问题排查
  9. 02-继承的本质-Objective-C基础
  10. 签约沈腾,易车开启三年品牌计划,穿越车市寒冬
  11. 用触发器实现表的同步操作
  12. 语言 泰克示波器程序_示波器再升级,EMI测试不求人
  13. Nuxt3 服务端渲染 、elementplus多皮肤黑暗模式
  14. 动态仙人掌 系列题解之二——3465: 动态仙人掌 II
  15. 支持5G WIFI的串口服务器
  16. 170915 逆向-问鼎杯题库(小磊生病了)
  17. 希捷推出数条战略有意对抗充氦硬盘
  18. 新老域名更替时的页面跳转
  19. 苹果数据泄漏:内鬼频出,这是库克的错吗?
  20. CSS css选择器 jquery jQuery选择器的优先级 XXX XX X xxx xx x

热门文章

  1. iOS中的MVC设计模式
  2. 宽量程电压电流 stm32_电压、电阻知识点汇总
  3. Linux的实际操作:用户管理(查看用户和组的配置文件/etc/passwd /etc/group /etc/shadow)
  4. python修复不了_如何修复Python代码?
  5. python异步asy_Python 异步编程之asyncio【转载】
  6. 单片机c语言怎样添加自定义头文件,单片机C语言编程与或|头文件常见问题
  7. python实现xmind_Python xmind库(生成框架图)
  8. 小学计算机课程评价,小学信息技术课堂评价浅谈
  9. java 根据圆心计算圆弧上点的经纬度_【控制测量学】-高斯投影正算公式以及java代码
  10. 【学习记录】网络层——IP数据报(格式与分片)