简述
Redis是一个事件驱动的程序,Redis基于Reactor模式开发了自己的网络事件处理器,通过IO多路复用程序来同时监听多个套接字,并通过队列排队传输给事件分派器进行处理,事件分派器通过套接字准备执行的操作(accept、read、write、close)关联对应的事件处理器来处理这些事件。
事件分派器只有处理完一个事件之后,才会处理队列中的下一个数据。
客户端
客户端连接到服务器之后,服务器对象redisServer中的list *clients
链表会加入一个新的代表客户端的redisClient对象,该对象保存着客户端的状态信息,包括客户端使用的数据库指针、输入缓冲区、输出缓冲区等。
命令执行的简单流程
- 客户端将命令SER KEY VALUE发送给服务器。
- 服务器通过命令指示对数据库进行操作,并产生回复。
- 服务器将回复发送给客户端。
- 客户端展示回复。
事件处理器处理命令的具体流程
客户端发送命令
在客户端键入一条命令,客户端会对该命令进行协议的转换,然后通过套接字发送给服务器。
读取命令
此时套接字为可读状态,分派器将使用对应的处理器来处理命令,处理会将读取到的命令放到redisClient的输入缓冲区中。然后对输入缓冲区中的命令进行分析,将命令解析之后保存在redisClient的argV和argC属性中,前者保存具体参数,或者保存参数数量。
查找命令的实现对象
处理器读取argV[0](本例子中为set),并找到这个命令对应的命令实现对象,用redisClient中的cmd指针指向该对象,命令实现对象包含命令的执行逻辑以及参数的要求等。
执行预备操作
在处理器执行命令的逻辑之前,会进行预备的操作,主要作用如下:
- 如果cmd指针指向null,表示用户键入的命令有误,报错。
- 根据cmd检查参数是否正确。
- 检查用户是通过了账号验证。
- 如果开启了maxmemory,并且命令涉及内存更新,要先检查内存是否足够。
- 其他操作。
调用命令实现
调用cmd指针指向的命令实现对象,执行命令的逻辑,并将结果存到redisClient对象的输出缓冲区中。之后会关联命令回复处理器,由该处理器来回复给客户端。
执行后续操作
- 如果开启了慢查询日志,会计算这个命令执行的情况是否需要添加一条日志。
- 判断是否需要进行AOF持久化。
- 在主从模式下,要通知所有的从服务器。
命令回复处理器
将输出缓冲区的命令回复发送给客户端,然后清空输出缓冲区,为处理下一个命令做准备。
客户端打印命令执行结果。
客户端将回复打印成人类可读的字符串。