• Redis 的 IO 多路复用,学习研究


    自己做个记录,也希望能帮助想要了解的人
    最终能理解这个,得益于网络上很多前辈的博客和自己粗看过《深入理解计算机系统》
    涉及一些计算机基础知识,会先提及,用一种简单的方式让大家有个基本的概念,以帮助理解最后需要讨论的东西
     
     

    基础知识

     

    操作系统

     
    操作系统本身可以看做一个特殊的软件,只有操作系统能直接接触计算机硬件,其他软件要访问硬件都必须通过操作系统
    操作系统对硬件做抽象,封装接口给软件调用
     
    程序员
    软件
    操作系统(在内存中)
    IO设备(网卡、磁盘、键盘、鼠标等)
     
    常见的操作系统有:
    Windows、Linux、Mac
     

    内核和用户空间

     
    首先,内核和用户空间都在内存中
    内核:
    只要计算机处于开启状态,操作系统(记住它是一种特殊的软件)就会把它的程序和数据放入内存中,由于操作系统的重要性,它会独占内存中的一块区域,这块区域就称之为内核
    即,内核就是操作系统常驻内存的区域
    用户空间:
    而用户空间,就是某个进程启动后,被分配到的一块内存区域
    注:
    具体的涉及到虚拟地址空间的概念,想要详细了解的童鞋可以看下《深入理解计算机系统》第三版的第十章“虚拟存储器”
     
     

    IO 

     
    具体到 IO,操作系统提供了一些 IO 操作,用于操作 IO 设备的数据,然后应用软件对其进行封装
    数据流转:
    网络IO:网卡 → 内核 → 用户空间(用户内存)
    磁盘IO:磁盘 → 内核 → 用户空间(用户内存) 
     
     
    各个操作系统分别提供了哪些 IO 操作?有哪几种 IO 模型?
    IO 操作:
    select、poll、epoll、kqueue、evport
    IO 模型:
    以 Linux 为例,它有五种 IO 模型:
    阻塞IO模型、非阻塞IO模型、IO复用模型、信号驱动IO模型以及异步IO模型
    可参考此链接中的内容,讲的很细:
     
     
     

    Redis

     

    Redis 是怎么对操作系统提供的 IO 操作进行封装的?

    可参考:
     
     

    为什么 Redis 使用了单线程 IO 多路复用?为什么那么快?

    1、cpu 处理相比于 IO 可以忽略

    每个客户端建立连接时,都需要服务端为其 创建 socket 套接字,建立连接
    然后该客户端的每个请求都要经历以下几步:
    (1)等待请求数据数据从客户端发送过来
    (2)将请求数据从内核复制到用户进程的缓冲区(buffer)
    (3)对请求数据进行处理(对于 redis 而言,一般就是简单的 get/set)
    由于操作简单+只涉及内存,所以第(3)步的处理很简单、很快,主要时间耗在(1)步,所以,如果采用普通 BIO 模式,每个请求都要经历这几步,那么处理十万条数据,就要在(1)步花费大量的时间,这样的话,qps 一定很低。所以就采用了更高效的 IO 多路复用模式,即,将(1)步统一交给第三方(也就是操作系统,操作系统提供了 select、poll、epoll、kqueue、iocp等系统调用函数),结合 redis 的单线程,现在整个处理流程是这样的:
    一下子来了一堆请求,线程将这些请求都交给操作系统去处理,让操作系统帮忙完成第(1)步,等到这些请求里的一个或多个走完了第(1)步,就将一个集合交给这个线程,并说,我这里收集到了几个走完第一步的请求,你去走(2)、(3)步吧,于是线程拿着这个集合去遍历,等遍历结束之后。又去检查操作系统那儿有没有(这个线程自己维护了一个 while 循环)走完第(1)步的请求,发现又有一些了,拿到后继续遍历进行(2)、(3)步,如此循环往复。
    注:有些 IO 模式是将(1)(2)步都交给操作系统处理了,线程本身只需处理第(3)步
     

    2、瓶颈在带宽,而不在 cpu

    由于 数据存放在内存中+处理逻辑简单,导致即使是单线程,Redis 可支持的 qps 也相当大,而当 qps 相当大的时候,首先限制性能的是带宽,即不需要把 cpu 的性能挖掘出来,因为在这之前,带宽就不够用了。所以没有必要为了提高 cpu 利用率而使用多线程处理业务逻辑。

    参考资料

    1、https://mp.weixin.qq.com/s/XzLHy41JrCV_y3BZpeTgwQ

    2、https://draveness.me/redis-io-multiplexing/

    3、https://mp.weixin.qq.com/s/vrUiKnwjWb3esk8lfiiOfw

    4、《深入理解计算机系统》第三版

  • 相关阅读:
    CUDA内存介绍
    CUDA10.0 官方手册 阅读笔记 章三 CUDA编程接口
    Texture Gather 讲解
    cuda学习--纹理内存
    计算机缓存Cache以及Cache Line详解
    nvidia的cuda编程api
    将ORBSLAM往ANDROID STUDIO 移植的时候一些坑
    解决Android10读取不到/sdcard/、/storage/emulated/0/文件的问题
    Android NDK 从入门到精通(汇总篇)
    好好说说c++内存序--以单例模式为例子
  • 原文地址:https://www.cnblogs.com/stone94/p/12830879.html
Copyright © 2020-2023  润新知