文件事件处理器Redis基于Reactor模式开发了一个称为文件事件处理器file event handler的网络事件处理器。 因为该文件事件处理器是单线程的,所以Redis被称为单线程模型,使用I/o复用机制同时接收多个套接字,并根据套接字上的事件类型选择对应的事件处理器
当监听到的套接字准备执行accept、read、write、close等操作时,将发生与该操作对应的文件事件,此时文件事件处理器将调用以前关联的事件处理器
事件处理器以单线程模式运行,但通过IO复用机制监听多个套接字,实现了高性能的网络通信模型,可以与内部其他单线程的模块对接,保证了Redis内部线程模型的简单性
文件事件处理器的结构由多个套接字、I/o复用器、文件事件调度器、事件处理器(命令请求处理器、命令响应处理器、连接响应处理器等)四个部分组成
多个套接字可能同时生成与不同文件事件对应的不同操作,但I/o复用器接收多个套接字,对套接字进行排队,然后从队列中逐个取出套接字,传递给事件调度程序,并
在处理套接字事件之前,I/o复用器不会将队列中的下一个套接字分配给事件调度程序。 文件事件调度程序根据每个套接字上当前生成的事件选择相应的事件处理器进行处理。
当套接字变为可读(例如,客户端对redis执行write操作或执行close操作)或出现可响应的新Sccket时,或客户端执行redis操作
套接字可写时,如果客户端对redis执行read操作,套接字将生成AE_WRITABLE事件。
IO复用器既可以接收AE_REABLE事件,也可以接收AE_WRITABLE事件。 如果在一个套接字上同时发生两个事件,则文件事件调度程序将优先处理AE_READABLE事件,然后变为AE_WRITABLE事件。
如果客户端连接到redis,文件处理器将连接套接字相关的响应处理器。 如果客户端将数据写入redis,则会请求处理器套接字相关命令。 如果客户端从redis读取数据,它将返回到套接字相关命令的处理器。
客户端与redis通信的过程是:当redis启动初始化时,redis将连接响应处理器与AE_READABLE事件相关联;当客户端启动与redis的连接时,redis生成AE_READABLE事件
当客户端向Redis发起请求时,读请求和写请求都是一样的。 首先在套接字中生成AE_READABLE事件,并由相应的命令请求处理器进行处理。 该命令请求处理器从套接字读取请求相关数据,执行和处理。
接下来,在Redis端准备好对客户端的响应数据后,将Socket的AE_WRITABLE事件与命令回复处理器相关联,在客户端准备好读取响应数据时,向Socket发送AE_WRITABLE事件也就是说,将准备好的响应数据写入Socket,客户机接收它
命令回复处理器编写完毕后,删除此套接字的AE_WRITABLE事件与命令回复处理器之间的关联。
为什么Redis单线程模型也这么高效? 1 )纯内存操作
Redis将所有数据放入内存中,内存响应时间约为100纳秒,这是redis QPS超过万的重要基础。
2 )核心是基于无阻塞的IO复用机制
有无阻塞IO意味着线程在读写IO时不再需要阻塞,读写可以瞬间完成,线程可以继续做其他事情。
redis必须处理多个IO请求,并将每个请求的结果返回给客户端。 因为redis是单线程模型,所以一次只能处理一个IO事件。 因此,redis必须在适当的时间暂停处理一个IO事件,并处理另一个IO事件。 这需要IO复用技术。 例如,一个管理员可以管理一个套接字的IO事件,选择哪个套接字以及处理哪个套接字的IO事件
3 )单线程避免了多线程频繁上下文切换带来的性能问题。 (百度多线程上下文切换() ) ) ) )。
第一,单线程可以简化数据结构和算法的实现。 同时数据结构不仅难以实现,而且开发测试也很麻烦
第二,单线程避免了线程切换和冲突状态的消耗,对于服务端开发来说,锁和线程切换通常是性能杀手。