Redis原理解析

Redis是单线程程序。单线程的Redis为何还能这么快?

1、所有的数据都在内存中,所有的运算都是内存级别的运算(因此时间复杂度为O(n)的指令要谨慎使用)

2、多路复用,NIO来处理客户端的并发连接

非阻塞IO,Non-block IO, NIO,非阻塞模式,使一个线程从某通道发送请求数据读取数据,如果目前没有数据可读时,就什么都

    不会获取,而不是保持线程阻塞,直到有数据可读之前,该线程可以继续做别的事情,非阻塞写也是如此,能写多少取决

    于内核为套接字分配的写缓冲区的空闲字节数,不必等到完全写入这个线程可以去做别的事情。线程通常将非阻塞IO的空

    闲时间用于在其他通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。

阻塞IO,BIO,如Java IO中的各种流都是BIO,阻塞的。当一个线程调用read或者write方法时,该线程会被阻塞,知道有一些数据

    被读取,或数据完全写入。该线程在此期间不能再干别的事情了。

事件轮询(多路复用)

    非阻塞IO有个问题,那就是线程要读数据,结果读了一部分后返回了,那么当数据到来时,如何通知线程继续读呢?写也是一

  样,如果缓冲区写满了没有写完,剩下的数据何时继续写,线程也应该得到通知。

    事件轮询API就是用来解决这个问题的。最简单的时间轮询API是select函数。它是操作系统提供给用户程序的API。输入是读

  写描述符列表,read_fds&write_fds,输出是与之对应的可读可写事件。同时还提供了一个timeout参数,如果没有任务事件到来,

  那么就最多等待timeout的值的时间,线程处于阻塞状态。一旦期间没有任务事件到来,就可以立即返回。时间过了之后没有任务

  事件到来,也会立即返回。拿到事件后,线程就可以挨个处理相应的事件。处理完了继续过来轮询。于是线程就进入了一个死循环

  ,这个死循环称为事件循环,一个循环为一个周期。

  通过select系统调用同时处理多个通道描述符的读写事件,因此将这类调用称为多路复用API。

指令队列:Redis会将每个客户端套接字都关联一个指令队列。客户端的指令通过队列来排队进行顺序处理,先到先服务。

响应队列:Redis会为每个客户端套接字都关联一个响应队列。Redis服务器通过响应队列来将指令的返回结果回复给客户端。如果队列

    为空,那么意味着连接暂时处于空闲状态,不需要去获取写事件。

猜你喜欢

转载自www.cnblogs.com/yangyongjie/p/10833479.html
今日推荐