redis时间和文件事件


what:

  redis是事件驱动的,分为两类事件:文件事件和时间事件。

  

  文件事件(file event)

    Redis服务器通过套接字与客户端(或者其他Redis服务器)进行连接,而文件事件就是服务器对套接字操作的抽象。

    服务器与客户端(或者其他服务器)的通信会产生相应的文件事件,而服务器则通过监听并处理这些事件来完成一系列网络通信操作。文件事件处理器使用I/O多路复用(multiplexing)程序来同时监听多个套接字,并根据套接字目前执行的任务来为套接字关联不同的事件处理器。当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作时,与操作相对应的文件事件就会产生,这时文件事件处理器就会调用套接字之前关联好的事件处理器来处理这些事件。

    参考文档:https://www.cnblogs.com/sfzlstudy/p/16554985.html

 

  时间事件(time event)

    Redis服务器中的一些操作(比如serverCron函数)需要在给定的时间点执行,而时间事件就是服务器对这类定时操作的抽象。时间事件分两类第一类是定时事件(让一段程序在指定的时间之后执行一次);另一类是周期性事件(让一段程序每隔指定时间就执行一次)。

    事件由3部分组成,分别是:{id, when, timeProc}    

      id:全局唯一ID。ID号从小到大顺序递增。
      when:毫秒精确度的UNIX时间戳,记录了时间事件的到达时间。
      timeProc:时间事件处理器的一个函数。当时间事件到达时,服务器就会调用相应的处理器来处理事件。

    一个时间事件是定时事件还是周期性事件,取决于时间事件处理器的返回值,如果事件处理器返回ae.h/AE_NOMORE,那么这个事件为定时事件,该事件在到达一次后就会被删除,之后不再到达。如果事件处理器返回一个非AE_NOMORE的整数值,那么这个事件为周期性事件,当一个时间事件达到后,服务器会根据事件处理器的返回值,对事件的when属性进行更新,让这个事件在一段时间后再次到达,并以这种方式一直更新并运行下去。

 

    事件都放在一个无序链表中,每当时间事件执行器运行时,它就会遍历整个链表。正常模式下Redis服务器只使用serverCron一个时间事件,benchmark模式下,服务器也只使用两个时间事件,所以全遍历对性能影响可以忽略。

 

    serverCron参考:https://www.cnblogs.com/sfzlstudy/p/16554772.html

 

how:

  事件的运行调度过程:

    参考以下代码:

redis时间和文件事件 

  事件的调度和执行规则:
    1)aeApiPoll函数的最大阻塞时间由到达时间最接近当前时间的时间事件决定,这个方法既可以避免服务器对时间事件进行频繁的轮询(忙等待),也可以确保aeApiPoll函数不会阻塞过长时间(同时,有文件事件到,就激活(参考代码))。

    2)因为文件事件是随机出现的,如果等待并处理完一次文件事件之后,仍未有任何时间事件到达,那么服务器将再次等待并处理文件事件。随着文件事件的不断执行,时间会逐渐向时间事件所设置的到达时间逼近,并最终来到到达时间,这时服务器就可以开始处理到达的时间事件了。

    3)对文件事件和时间事件的处理都是同步、有序、原子地执行的,服务器不会中途中断事件处理,也不会对事件进行抢占,因此,不管是文件事件的处理器,还是时间事件的处理器,它们都会尽可地减少程序的阻塞时间,并在有需要时主动让出执行权,从而降低造成事件饥饿的可能性。比如说,在命令回复处理器将一个命令回复写人到客户端套接字时,如果写人字节数超过了一个预设常量的话,命令回复处理器就会主动用break跳出写入循环,将余下的数据留到下次再写;另外,时间事件也会将非常耗时的持久化操作放到子线程或者子进程执行。

    4)因为时间事件在文件事件之后执行,并且事件之间不会出现抢占,所以时间事件的实际处理时间,通常会比时间事件设定的到达时间稍晚一些。

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/281337.html

(0)
上一篇 2022年8月21日
下一篇 2022年8月21日

相关推荐

发表回复

登录后才能评论