redis服务器是一个事件驱动程序,主要处理两类事件:文件事件和时间事件。
文件事件处理器使用I/O多路复用的程序来同时监听多个套接字,虽然redis的文件事件处理器以单线程方式运行,但通过io多路复用监听多个套接字,这样实现了高性能的网络通讯模型,又可以很好地让redis以单线程的方式运行,保持了单线程设计的简单性。(这是redis单线程还能那么快的原因之一)
由四个组成部分:套接字,io多路复用程序,文件事件分派器以及事件处理器。
image-20200825161924824
当套接字变得可读(客户端对套接字执行write操作或者执行close操作)的时候,或者有新的可应答套接字出现时,套接字产生AE_READABLE事件。
当套接字变得可写时(客户端对套接字执行read操作),套接字产生AE_WRITABLE事件。
假设一个redis服务器正在运作,这个时候服务器的监听套接字的AE_READABLE事件处于监听情况下。
这时有个redis客户端向服务器发起连接,那么监听套接字将产生AE_READABLE事件,触发连接应答处理器执行。
连接处理器应答之后会创建客户端套接字,客户端状态,并将客户端套接字的AE_READABLE事件与命令请求处理器进行关联。
然后假设客户端向主服务器发送一个命令请求,那么客户端套接字将产生AE_READABLE事件,引发命令请求处理器执行,处理器读取相关的命令内容,传给相关的程序执行。
之后命令会产生相关的恢复,为了将这个回复给客户端,服务器会将客户端套接字的AE_WRITABLE事件与命令回复处理器关联。当客户端尝试读取命令回复的时候,客户端套接字会产生AE_WRITABLE事件,触发命令回复处理器执行,当命令回复处理器将命令回复全部写入到套接字后,服务器就会解除客户端 套接字的事件和关联。
image-20200825182326976
redis的时间事件是用周期性事件(让一个程序每隔指定时间就执行一次)
主要有三个属性组成,id(唯一标识号),when(时间事件的到达时间),timeProc(时间事件处理函数)
redis服务器将所有的时间事件都放在一个无序列表中,事件执行器会去遍历这些节点,如果发现时间到达,就会执行对应的时间事件。
不会 ,因为redis的时间事件很少,正常模式下只有serverCron一个事件。
主要工作有:
很简单,ae.c/aeProcessEvents负责,如果有时间事件要处理,就不阻塞去处理时间事件,如果没有时间时间,会阻塞一下,来等待文件事件,然后执行文件事件,执行时间事件,然后不停死循环执行。
redis保存了客户端当前的状态信息,以及执行相关功能时需要用到的数据结构,其中包括:
是通过链表把多个客户端状态记录到服务器中。
命令执行器是如何工作的?
命令执行器首先根据argv[0]的值,在命令表中找到对应的redisCommand对象。
这个对象记录了命令相关的细节,比如允许参数多少,实现函数指针,对该命令的标识符,以及一些统计信息。
image-20200826114220363
服务器先利用这些对命令进行检查,如果检查失败了,则返回一个错误,如果打开了监视器,就会把要执行的命令和参数等消息发给监视器。
检查完毕之后,就调用执行命令的相关函数,得到回复之后会保存在客户端状态的输出缓冲区里面。
执行结束之后还有一些特殊任务,有统计慢查询,修改链接的统计信息,aof写入到AOF缓冲区里面,复制命令到其它从服务器。
最后套接字变为可写状态的时候,把输出缓冲区里面的数据返回给客户端。