第12章 事件

Huan Lee Lv5

redis服务器是一个事件驱动程序, 包括:

  • 文件事件, 服务器与客户端的连接socket被抽象为文件事件, 通过一系列IO实现通信
  • 时间事件, 要求在给定时间执行目标操作的事件.

12.1 文件(socket)事件

Redis网络事件处理特点:

  • Reactor多线程并发模式: 父进程负责监听, 当有新连接或新数据到来时通过消息队列告知子进程, 子进程负责应答, 读写数据
  • 通过IO多路复用: 同时处理多个socket的IO事件

文件事件处理器包含四个部分:

  1. 套接字(socket): 对网络IO的封装

  2. IO多路复用程序: 一个进程(线程)同时监听多个连接(socket)的文件(socket)事件

  3. 文件事件分派器: 将就绪的文件事件以队列的形式进行分派

  4. 事件处理器

通常分派器和事件处理器都是阻塞的, 即只有分派的事件被对应处理器完成后才会分派下一个事件.

Untitled

Redis包装了多种IO复用底层实现, 编译时自动选择系统中性能最高的底层实现(evport>epoll>kqueue>select)

Untitled

事件类型与处理器:

  • 连接应答处理器(accept): 应答新客户端连接
  • 命令请求处理器(readable): 接收和处理新的请求
  • 命令回复处理器(writable): 将命令执行结果回复给客户端

12.2 时间事件

分为两类 定时事件周期性事件

一个时间事件包括 id, 事件到达时间when和时间事件处理器timeProc

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

正常情况下, Redis服务器只使用serverCron一个时间事件, 即使是benchmark模式下, 也只使用两个时间事件. 所以无序列表不影响性能(采用惰性删除策略处理过期键, 只需要定期处理即可)

serverCron的工作内容:

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

12.3 事件的调度与执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def aeProcessEvents():
# 获取到达时间离当前时间最接近的时间事件
time_event = aeSearchNearestTimer()

# 计算最接近的时间事件距离到达还有多少毫秒
remaind_ms = time_event.when - unix_ts_now()

# 如果事件已到达,那么remaind ms的值可能为负数,将它设定为O
if remaind_ms < 0:
remaind_ms = 0

# 根据remaind ms的值,创建timeval结构
timeval = create_timeval_with_ms(remaind_ms)

# 阻塞并等待文件事件产生,最大阻塞时间由传入的timeval结构决定
# 如果remaind_ms的值为O,那么aeApiPol1调用之后马上返回,不阻塞
aeApiPoll(timeval)

# 处理所有已产生的文件事件
processFileEvents()

# 处理所有已到达的时间事件
processTimeEvents()
  • aeApilPoll(timeval)为阻塞式的IO复用, 会返回事件队列

    • 如果统一事件源, 可以在一个队列中同时处理文件事件, 时间事件(甚至信号等)
  • Title: 第12章 事件
  • Author: Huan Lee
  • Created at : 2023-08-27 15:16:25
  • Updated at : 2024-02-26 04:53:15
  • Link: https://www.mirthfullee.com/2023/08/27/notion-第12章 事件-dae64edf/
  • License: This work is licensed under CC BY-NC-SA 4.0.