Redis设计与实现——Redis 事件

文件事件

概念

Redis服务器通过套接字与客户端(或者其他Redis服务器)进行链接,而文件事件就是服务器对套接字操作的抽象。服务器与客户端(或其他Redis服务器)的通信会产生相应的文件事件,而服务器则通过监听并处理这些事来完成一系列网络通信操作。

文件事件处理器

用于处理网络事件,以单线程方式运行。
组成部分:套接字 + I/O多路复用程序 + 文件事件分派器 + 事件处理器。

I/O多路复用程序可同时监听多个套接字,并通过文件分派器根据套接字执行的任务类型来关联不同的时间处理器。文件事件处理器既实现了高性能的网络通信模型,又可以很好地与Redis服务器中的其他同样以单线程方式运行的模块进行对接,保持了Redis内部单线程设计的简单性。

在这里插入图片描述
如果所示: I/O多路复用程序会将所有产生的事件都放到一个队列里,然后通过这个队列,以有序、同步、每次一个套接字的方式向文件事件分派器传送套接字。当上一个套接字产生的事件被事件处理器执行完毕之后,才会继续向文件事件分派器传送下一个套接字。

文件事件的类型

  1. AE_WRITABLE:套接字可写(客户端对套接字执行read操作)
  2. AE_READABLE: 套接字可读(客户端对套接字执行write操作,或者执行close操作,或者有新的可应答acceptable套接字,即客户端对服务器执行connect操作)

文件事件处理器

  1. 连接应答处理器
    服务器初始化时,程序会将连接应答处理器与服务器监听套接字的AE_READABLE事件连关联起来。当客户端有connect连接服务器监听套接字时,就会产生AE_READABLE事件,引发连接应答处理器执行。
  2. 命令请求处理器
    命令请求处理器负责从套接字中读入客户端发送的请求命令的内容。
    当客户端通过连接应答处理器成功连接服务器之后,服务器会将AE_READABLE事件与请求命令处理器关联起来。当客户端放请求命令的时候,服务器就会产生AE_READABLE事件,引发命令请求处理器执行。
  3. 命令回复处理器
    负责将服务器执行命令后得到的命令回复通过套接字返回给客户端。
    当服务器有命令需要传送给客户端时,服务器会将客户端套接字的AE_WRITABLE时间和命令回复处理器关联起来,当客户端准备好接收服务器传回的命令回复时,就会产生AE_WRITABLE时间,引发命令回复处理器执行。
  4. 客户端与服务器连接事件示例
    在这里插入图片描述

时间事件

分类

  1. 定时事件
    让程序在指定时间之后执行一次
  2. 周期性事件
    让程序每隔指定时间就执行一次

组成

属性名定义
id服务器为时间事件创建全局唯一ID,ID按从小到大顺序递增,即新的时间事件的ID大于旧的时间事件的ID
when毫秒精度的UNIX时间戳,记录事件的到达时间
timeProc时间事件处理器,当时间到达时,会调用相应的处理器处理事件。如果处理结果返回AE_NOMORE,则该事件到达一次后就会被删除;否则这个事件就是周期性事件,根据返回结果更新when属性

实例:serverCon函数

redis 2.6 默认每秒运行10次,平均间隔100ms运行一次;
redis 2.8 用户可自定义修改

执行内容
更新服务器的各类统计信息,如时间、内存占用、数据库占用
清理数据库中的过期键
关闭和清理连接失效的客户端
尝试进行AOF或RDB持久化操作
如果服务器是主服务器,那么对从服务器进行定期同步
如果处于集群模式,对集群进行定期同步和连接测试

事件的调度与执行

在这里插入图片描述

事件调度伪代码:

def aeProcessEvents():

	#获取到达时间离当前时间最接近的时间事件
	time_event = aeSearchNearestTimer()
	
	#计算最接近的时间事件距离到达还有多少毫秒
	remain_ms = time_event.when - unix_ts_now()
	
	#如果事件已到达,那么remain_ms 值可能为负数,置为0
	if remain_ms < 0:
		remain_ms = 0
	#根据remain_ms值,创建timeval结构
	timeval = create_timeval_with_ms(remain_ms)
	
	#阻塞并等待文件事件产生,最大阻塞时间由传入的timeval结构决定
	#如果remaind_ms值为0,那么aeApiPoll调用之后马上返回,不阻塞
	aeApiPoll(timeval)
	
	#处理所有已产生的文件事件
	processFileEvents()
	
	#处理所有已到达的时间事件
	processTimeEvents()

说明:
aeApiPoll() 的最大阻塞事件由到达时间最接近当前时间的时间事件决定,这个方法既可以避免服务器对时间事件进行频繁的轮询,也可以确保该函数不会阻塞过长时间。

文件事件的随机的,处理完之后如果时间事件仍未到达,则继续等待处理文件事件,知道时间事件到达,则服务器开始执行时间事件。

文件事件和时间事件的处理是同步、有序、原子地进行的,服务器不会中断事件,也不会对事件进行抢占。两者都尽可能减少程序的阻塞时间,在有需要时,会主动让出执行权,从而降低造成事件饥饿的可能性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值