从零开始Redis(六):事件处理机制

简介

本节介绍下redis的事件处理机制
Redis服务器是典型的事件驱动系统。
MVC : java 上层调下层
事件驱动: js
Redis将事件分为两大类:文件事件和时间事件。

文件事件

文件事件即Socket的读写事件,也就是IO事件。
客户端的连接、命令请求、数据回复、连接断开

socket

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据。

Reactor

Redis事件处理机制采用单线程的Reactor模式,属于I/O多路复用的一种常见模式。

IO多路复用( I/O multiplexing )指的通过单个线程管理多个Socket

Reactor pattern(反应器设计模式)是一种为处理并发服务请求,并将请求提交到 一个或者多个服务处理程序的事件设计模式。

Reactor模式是事件驱动的
有一个或多个并发输入源(文件事件)
有一个Service Handler
有多个Request Handlers
这个Service Handler会同步的将输入的请求(Event)多路复用的分发给相应的Request Handler
在这里插入图片描述
在这里插入图片描述

  • Handle:I/O操作的基本文件句柄,在linux下就是fd(文件描述符)
  • Synchronous Event Demultiplexer :同步事件分离器,阻塞等待Handles中的事件发生。(系统)
  • Reactor: 事件分派器,负责事件的注册,删除以及对所有注册到事件分派器的事件进行监控, 当事件发生时会调用Event Handler接口来处理事件。
  • Event Handler: 事件处理器接口,这里需要Concrete Event Handler来实现该接口
  • Concrete Event Handler:真实的事件处理器,通常都是绑定了一个handle,实现对可读事件 进行读取或对可写事件进行写入的操作。
    在这里插入图片描述
    主程序向事件分派器(Reactor)注册要监听的事件
    Reactor调用OS提供的事件处理分离器,监听事件(wait)
    当有事件产生时,Reactor将事件派给相应的处理器来处理 handle_event()

4种IO多路复用模型与选择

select,poll,epoll、kqueue都是IO多路复用的机制
I/O多路复用就是通过一种机制,一个进程可以监视多个描述符(socket),一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。

select

调用后select函数会阻塞,直到有描述符就绪(有数据 可读、可写、或者有except),或者超时(timeout指定等待时间,如果立即返回设为null即可),函数返回。当select函数返回后,可以 通过遍历fd列表,来找到就绪的描述符。

优点
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点。
windows linux …多平台

缺点
单个进程打开的文件描述是有一定限制的,它由FD_SETSIZE设置,默认值是1024,采用数组存储另外在检查数组中是否有文件描述需要读写时,采用的是线性扫描的方法,即不管这些socket是不是活跃的,都轮询一遍,所以效率比较低

poll

poll使用一个 pollfd的指针实现,pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。
优点:
采样链表的形式存储,它监听的描述符数量没有限制,可以超过select默认限制的1024大小
缺点:
另外在检查链表中是否有文件描述需要读写时,采用的是线性扫描的方法,即不管这些socket是不是活跃的,都轮询一遍,所以效率比较低。

epoll

epoll是在linux2.6内核中提出的,是之前的select和poll的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。

优点:

  • epoll 没有最大并发连接的限制,上限是最大可以打开文件的数目,举个例子,在1GB内存的机器上大约是10万左 右
  • 效率提升, epoll 最大的优点就在于它只管你“活跃”的连接 ,而跟连接总数无关,因此在实际的网络环境 中, epoll 的效率就会远远高于 select 和 poll 。
  • epoll使用了共享内存,不用做内存拷贝
kqueue

kqueue 是 unix 下的一个IO多路复用库。最初是2000年Jonathan Lemon在FreeBSD系统上开发的一个高性能的事件通知接口。注册一批socket描述符到 kqueue 以后,当其中的描述符状态发生变化时,kqueue 将一次性通知应用程序哪些描述符可读、可写或出错了。
优点:
能处理大量数据,性能较高

文件事件分派器

在redis中,对于文件事件的处理采用了Reactor模型。采用的是epoll的实现方式。
在这里插入图片描述
Redis在主循环中统一处理文件事件和时间事件,信号事件则由专门的handler来处理。

事件处理器

  • 连接处理函数 acceptTCPHandler
    当客户端向 Redis 建立 socket时,aeEventLoop 会调用 acceptTcpHandler 处理函数,服务器会为每个链接创建一个 Client 对象,并创建相应文件事件来监听socket的可读事件,并指定事件处理函数
// 当客户端建立链接时进行的eventloop处理函数 networking.c
void acceptTcpHandler(aeEventLoop *el, int fd, void *<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值