2.2 单线程架构

  Redis内部使用单线程架构。Redis一个瞬间只能执行一条命令,不能执行两条命令

  Redis单线程速度这么快的原因可大致归结三个:

  1. 纯内存

Redis把所有的数据都保存在内存中,而内存的响应速度是非常快的

  1. 非阻塞IO

Redis使用epoll异步非阻塞模型 ,Redis自身实现了事件处理

  1. 避免线程切换和竞态消耗

Redis使用epoll异步非阻塞模型 ,Redis自身实现了事件处理

  主要原因是纯内存。

  不过第二条和第三条倒是面试中经常会问到,尤其是第二条。为了便于大家,理解更深刻,我们这里探讨一下操作系统的IO

  用户程序进行IO的读写,依赖于底层的IO读写,基本上会用到底层的read&write两大系统调用。

  read系统调用,并不是直接从物理设备把数据读取到内存中;write系统调用,也不是直接把数据写入到物理设备。上层应用无论是调用操作系统的read,还是调用操作系统的write,都会涉及缓冲区。具体来说,调用操作系统的read,是把数据从内核缓冲区复制到进程缓冲区;而write系统调用,是把数据从进程缓冲区复制到内核缓冲区

  缓冲区的目的,是为了减少频繁地与设备之间的物理交换。外部设备的直接读写,涉及操作系统的中断。发生系统中断时,需要保存之前的进程数据和状态等信息,而结束中断之后,还需要恢复之前的进程数据和状态等信息。为了减少这种底层系统的时间损耗、性能损耗,于是出现了内存缓冲区。

  有了内存缓冲区,上层应用使用read系统调用时,仅仅把数据从内核缓冲区复制到上层应用的缓冲区(进程缓冲区);上层应用使用write系统调用时,仅仅把数据从进程缓冲区复制到内核缓冲区中。底层操作会对内核缓冲区进行监控,等待缓冲区达到一定数量的时候,再进行IO设备的中断处理,集中执行物理设备的实际IO操作,这种机制提升了系统的性能。至于什么时候中断(读中断、写中断),由操作系统的内核来决定,用户程序则不需要关心。

  从数量上来说,在Linux系统中,操作系统内核只有一个内核缓冲区。而每个用户程序(进程),有自己独立的缓冲区,叫作进程缓冲区。所以,用户程序的IO读写程序,在大多数情况下,并没有进行实际的IO操作,而是在进程缓冲区和内核缓冲区之间直接进行数据的交换。

  有了对操作系统IO的基本认识之后,还要提一下操作系统四种主要的IO模型

  1. 同步阻塞IO(Blocking IO)
  2. 同步非阻塞IO(Non-blocking IO)
  3. IO多路复用(IO Multiplexing)
  4. 异步IO(Asynchronous IO)

  Redis的IO模型是IO多路复用,有意思的是Java的NIO模型,也是IO多路复用(不是同步非阻塞IO)

  有兴趣的可以查阅相关的资料,或者不着急的可以等我接下来的博文(过段日子会有网络编程详解的博文,对IO作深入探究)

  这里还要强调一下,由于Redis单线程一次只运行一条命令,我们要拒绝长(慢)命令

    keys 
    flushall
    flushdb
    slow lua script
    mutil/exec
    operate
版权声明: 本文为智客工坊「沉晓」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

results matching ""

    No results matching ""