前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Redis设计与实现》读书笔记(十六) ——Redis文件事件 (原创内容,转载请注明来源,谢谢)

《Redis设计与实现》读书笔记(十六) ——Redis文件事件 (原创内容,转载请注明来源,谢谢)

作者头像
用户1327360
发布2018-03-07 15:59:32
7990
发布2018-03-07 15:59:32
举报
文章被收录于专栏:决胜机器学习决胜机器学习

《Redis设计与实现》读书笔记(十六) ——Redis文件事件

(原创内容,转载请注明来源,谢谢)

一、概述

redis服务器是一个事件驱动程序,服务器需要处理以下两类事件:

1)文件事件(fileevent),redis服务器与客户端通过socket连接,文件事件是对socket的抽象,服务器与客户端通信会产生文件事件,服务器通过监听文件事件产生一系列操作。

2)时间事件(timeevent),redis的部分操作需要定时执行,主要是serverCron函数,例如定时清理过期键、定时aof写入等,时间事件是服务器对此类的抽象。

二、文件事件

1、reactor模式

redis基于reactor模式开发网络事件处理器,将其称之为文件时间处理器。该处理器通过I/O多路复用,同时监听多个socket,并根据socket当前处理的任务来关联不同的事件处理器。

reactor模式如下图所示:

其是处理并发I/O比较常见的一种模式,用于同步I/O。中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上。一旦有I/O事件到来或是准备就绪(区别在于多路复用器是边沿触发还是水平触发),多路复用器返回并将相应I/O事件分发到对应的处理器中。

reactor中文称为反应器,即其不是等套接字来调用,而是提前建立好,并主动去调用到来或就绪的套接字。

当被监听的套接字准备好执行连接应答(accept)、读取(read)、写入(write)、关闭(close)等操作,会产生相应的文件事件。此时,文件事件处理器(即reactor)会调用之前关联好的处理器来处理事件。

I/O多路复用的reactor模式,使得redis虽然是单线程处理,但是仍然具有高效率。

2、文件事件处理器的构成

文件事件处理器由四部分组成——套接字、I/O多路复用程序、文件事件分派器、事件处理器,如下图所示:

通常,一个服务器需要同时处理多个套接字,因此文件事件可能并发出现。I/O多路复用程序是通过监听多个套接字,并将准备好的套接字按准备好的时间顺序转发给文件时间分派器。由文件时间分派器根据具体的事件类型,分派给不同的事件处理器。

I/O多路复用程序将并发出现的多个套接字加入到队列中,以有序、同步、每次一个的方式,将事件发送给文件事件分派器,并且当事件处理完毕后,才会将下一个事件发送过去。如下图所示:

I/O多路复用程序会监听多个套接字的读(ae.h/AE_READABLE)和写事件(ae.h/AE_WRITEABLE),当套接字可读或有新的可应答的套接字出现,产生读事件;当套接字可写,产生写事件。如果同时可读可写,则会先读再写。如果没有任何事件,返回的是ae.h/AE_NONE。

3、I/O多路复用程序

redis的I/O多路复用程序是通过包装操作系统原生的如select、epoll、evport、kqueue等I/O多路复用函数库,来实现I/O多路复用。由于redis底层对每种I/O多路复用都实现了相同的api接口,因此可以根据实际情况互换。每种复用方式,在redis里面是分别保存在一个.c的文件内。

1)select

select是较早的unix多路复用方式,其提供三种流——读、写、异常,调用时需要传入感兴趣的流,select将其拷贝到内核。select会使程序阻塞,让后其轮询每个流,当某个监听的流有操作时,其调用相关函数,返回结果。

由于select会将传入的流修改,并且需要全量传入、全量返回,对于大量的请求下,效率较低。

2)epoll与kqueue

epoll是linux内核的,kqueue是BSD内核的,其原理基本一致。其是通过创建一个句柄,并注册事件函数。即其是提前将有可能的事件都先注册好,当具体事件发生时去调用,而不是select的每次发生时在注册。

4、文件事件处理器

redis针对不同的文件事件,编写了多个文件事件处理器,包括处理各个客户端连接的应答处理器、接收客户端请求的命令请求处理器、向客户端返回命令结果的命令回复处理器、主从复制情况下的复制处理器。

1)应答处理器

名称是networking.c/acceptTcpHandler,用于对连接服务器监听套接字的客户端进行应答。redis初始化的时候,会将此应答处理器和套接字的读事件联系起来。当客户端发送连接请求,就会产生读事件(AE_READABLE)。

2)命令请求处理器

名称是networking.c/readQueryFromClient,用于处理读入客户端发送过来的套接字,当应答处理器连接到套接字的时候,命令请求处理器就会将读事件与其关联起来。当客户端发送请求时,就会产生读事件,命令请求处理器读入套接字中客户端发送的命令事件。

3)命令回复处理器

名称是networking.c/sendReplyToClient,用于将服务器执行命令后得到的回复返回给客户端。当有命令要返回给客户端,redis会将写事件与命令回复处理器关联起来,当客户端准备好接受服务器的回复,就会产生写事件,引发命令处理器将相关要返回给客户端的实际写入套接字。命令发送完毕后,会解除写事件和该客户端的关联。

4)示例

下面讲述一次完整的客户端与服务器连接事件。

当redis服务器正常运作时,监听套接字的事件AE_READABLE处于监听状态,且相应处理该事件的是应答处理器。

当有客户端向redis服务器发送连接请求,会产生AE_READABLE,触发应答处理器执行。处理器会进行连接并回复客户端,并创建客户端套接字,将套接字的AE_READABLE与命令请求处理器关联。

当客户端向redis服务器发送命令,会产生AE_READABLE事件,命令请求处理器会读入套接字中的命令,并传给相关执行程序去执行。

redis服务器执行完毕命令后,将产生相应的回复,服务器会将套接字的AE_WRITEABLE与命令回复处理器关联,当客户端尝试读取回复,客户端套接字将产生AE_WRITEABLE,命令回复处理器将执行,把要返回的内容写入套接字。

整个过程如下图:

——written by linhxx 2017.09.06

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 决胜机器学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档