Redis为什么那么快那?

67 阅读6分钟

Redis为什么这么快?

大纲

画板

备注:xmind中图片来源blog.bytebytego.com/p/why-is-re…

对话解析

为什么Redis那么快?

主要从三个方面分析:

  1. redis是基于内存的,内存的读取速度要比磁盘快很多

  2. redis使用的I/O多路复用模型,提高了并发处理能力

  3. redis具有多种高效的数据结构,里面大多数数据结构的操作复杂度为O(1)

为什么内存中的处理速度比磁盘的快?

画板

下面从多个角度展开解释:

  • 访问延迟(1ms=1000us,1us=1000ns,即:1ms=100万ns

    • 内存:

      • 级别:访问延迟特别低,通常在纳秒(ns)级别。

      • 原因:内存的数据存储单元通过电信号快速读取和写入

    • 磁盘:

      • 级别:访问延迟要高的多

        • 机械硬盘HDD, 通常在毫秒(ms)级别

        • 固态硬盘SSD, 在微秒(us)级别。

      • 原因:

        • 机械硬盘:涉及到更多的机械运动,并且需要定位数据的物理位置

        • 固态硬盘:更多的电子信号传输,并且需要定位数据的物理位置

  • 寻道时间

    • 内存:

      • 随机存取,几乎可以立即访问到任何位置的数据,没有寻道时间的概念
    • 磁盘:

      • 机械硬盘:通过旋转磁盘和移动磁头来读取或写入数据,导致显著延迟

      • 固态磁盘:也需要一定时间定位数据的闪存单元

  • 传输速率

    • 内存:带宽达到数百GB/s,甚至更高

    • 磁盘:

      • 机械硬盘:100-200MB/s

      • 固态硬盘:几千MB/s

  • 并行性

    • 内存:可以同时处理多个请求,因为基于电信号的随机存取设备

    • 磁盘:

      • 机械硬盘:一个磁头同一时刻只能访问一个磁道

      • 固态硬盘:由于架构限制,仅支持一定程度的并行访问

IO模型是什么?

IO模型:操作系统或应用程序,处理IO操作的方式

IO操作,通常涉及与外部设备进行数据交换。而这些操作往往是阻塞的。

(阻塞:可以理解为,这个事没干完,后面的事都别想干,就像是一个车停在了收费站收费的地方,这个车没走之前,这个通道谁也别想走,都得等着。)

有问题,就要想办法解决,于是为了提高系统的并发性和性能,不同的IO模型就诞生了。

常见的IO模型,包括一下几种:

一次I/O操作大概流程

在开始学习IO模型之前,我们先简单看一下,一次普通的I/O操作的大概过程,如下

画板

下面的IO模型讲解中,我们只针对用户程序和系统内核之间的交互进行简略讲述。

同步阻塞I/O(Blocking I/O)

  • 描述:最传统的IO模型,一个阻塞,后面都不能执行

  • 优点:简单

  • 缺点:浪费资源

画板

同步非阻塞I/O(NIO,No Blocking I/O)

  • 描述:在内核有数据之前,不阻塞,只有从内核拷贝数据到应用程序中时才阻塞

  • 优点:在内核有数据前,线程可以先去干别的,提高线程利用率

  • 缺点:需要进行线程上下文切换,耗费资源

画板

I/O多路复用

  • 描述:在内核有数据前,只用一个线程查看数据是否准备好,把所有需要监听的连接,都注册到select线程里,由这一个线程来监管所有连接,等到连接对应的数据准备好了,通知对应的线程来取即可。

  • 优点:减少了线程的上下文切换,减少资源消耗

  • 缺点:最后处理数据时还是阻塞的

画板

信号驱动式I/O

  • 描述:不需要查询,由内核准备好数据后,通知你来取即可

  • 优点:减少了线程上下文切换,提高了线程利用率

  • 缺点:因为通常通讯协议用的TCP,但是TCP中可以产生信号的事件有七种,而数据准备好的时候,发送信号,我们不能确定是哪个数据准备好了,因为别的事件用的是同一个信号,所以用不了,UDP可以,因为UDP没那么多事件。

画板

异步I/O(AIO,Asynchronous I/O)

  • 描述:从接受到IO请求到把数据拷贝到用户空间,通通由内核执行,用户程序全程不阻塞

  • 优点:完全非阻塞

  • 缺点:linux对异步I/O支持不足,所以用不了

画板