Redis设计与实现:第十二章 - 事件

参考:《Redis设计与实现》

1、文件事件

Redis基于Reactor模式开发自己的网络事件处理器,也称为文件事件。

  • 文件事件处理器使用I/O多路复用程序同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。
  • 被监听的套接字准备好执行操作时,与操作对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理对应事件

1、文件事件处理器的组成

       文件事件处理器的四个组成部分图示:
在这里插入图片描述

文件事件
       对套接字的抽象,每当一个套接字准备好执行连接应答、写入、读取、关闭等操作时,就会产生一个文件事件,多个文件事件可能并发的出现。
       
I/O多路复用程序
       负责监听多个套接字,并向文件事件分派器传送产生这些事件的套接字。通过有序队列,同步、每次发送一个套接字的方式向文件事件分派器发送套接字,等上一个套接字处理完毕才会继续发送下一个套接字。
       
文件事件分派器
       接收I/O多路复用程序传来的套接字,根据套接字的类型,调用对应的事件处理器。
       

事件处理器
       定义了某个事件发生时,服务器应该执行的动作的函数集。

       

2、I/O多路复用程序的实现

       所有功能都是通过包装常见的select,epoll,evport和kqueue这些I/O多路复用函数库来实现的。Redis为每个I/O多路复用函数库实现了相同的API,所以I/O多路复用的底层实现是可以互换的。程序在编译的时候会自动选择系统中性能最高的I/O多路复用函数库来作为Redis的底层实现。

       

3、事件的类型

       事件类型分为两种,一个是可读事件,一种是可写事件,如果一个套接字同时产生这两种事件,那么服务器按照先读套接字,后写套接字的方式进行处理。
       

4、文件事件处理器

1.连接应答处理器

       用于对连接服务器监听套接字的客户端进行应答,当redis服务器进行初始化的时候,程序会将这个连接应答处理器和服务器监听套接字的可读事件关联起来。
       

2.命令请求处理器

       负责从套接字中读入客户端发送的命令的请求内容,当客户端向服务器发送命令的时候,套接字产生可读事件,会引发命令请求处理器执行,执行相应的套接字读入操作。
       

3.命令回复处理器

       当服务器有命令回复需要传送给客户端,当客户端准备好接收命令回复时,会产生可写事件,将命令回复处理器关联起来,执行相应的套接字写入操作。
       

4、总体通信过程

在这里插入图片描述
       

2、时间事件

1、时间事件分类

Redis时间事件分成下面两类:

  • 定时事件:让一段程序在指定的时间之后执行一次。
  • 周期性事件:让一段程序每个一段时间执行一次。

       

2、时间事件要素

一个时间事件由下面三个属性组成:

  • id:服务器为时间事件创建的全局唯一ID。
  • when:毫秒精度的UNIX时间戳,记录时间时间到达的时间。
  • timeProc:时间事件处理器,一个函数。当时间事件到达的时候,服务器会调用相应的处理器来处理事件。
           

3、实现方式

       服务器把所有的时间事件都放到一个无序链表中,每当时间事件执行器运行时,他就会遍历整个链表,查找所有的时间事件,并调用相应的事件处理器。

       

3、事件的调度与执行

事件调度和执行规则:

  • 最大阻塞时间由到达时间最接近当前时间的时间事件决定,这个方法既可以避免服务器对时间进行频繁轮询,也可以确保事件处理函数不会阻塞很长时间。
  • 文件事件是随机出现的,如果等待处理完一次文件事件以后,仍然没有时间事件到来,那么服务器会再次等待处理文件事件,随着文件事件的出现时间也逐渐向时间事件设置的到达事件逼近,最终开始处理时间事件。
  • 对文件事件和时间事件的处理都是同步、有序原子的执行,服务器不会中断事件处理,也不会对事件进行处理。事件在处理的时候都会尽量减少程序的阻塞时间,在有需要的时候让出执行权,从而降低事件饥饿的可能性。
  • 因为时间事件在文件事件之后处理,不会发生抢占操作,所以时间事件实际处理时间会比到达的时间晚一点。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章