iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Redis中事件驱动模型的作用是什么
  • 429
分享到

Redis中事件驱动模型的作用是什么

2024-04-02 19:04:59 429人浏览 薄情痞子
摘要

这篇文章给大家介绍Redis中事件驱动模型的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言Redis 是一个事件驱动的内存数据库,服务器需要处理两种类型的事件。文件事件时

这篇文章给大家介绍Redis中事件驱动模型的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

前言

Redis 是一个事件驱动的内存数据库服务器需要处理两种类型的事件。

  • 文件事件

  • 时间事件

下面就会介绍这两种事件的实现原理。

文件事件

Redis 服务器通过 Socket 实现与客户端(或其他redis服务器)的交互,文件事件就是服务器对 socket 操作的抽象。 Redis 服务器,通过监听这些 socket 产生的文件事件并处理这些事件,实现对客户端调用的响应。

Reactor

Redis 基于 Reactor 模式开发了自己的事件处理器。

这里就先展开讲一讲 Reactor 模式。看下图:

Redis中事件驱动模型的作用是什么

“I/O 多路复用模块”会监听多个 FD ,当这些FD产生,accept,read,write 或 close 的文件事件。会向“文件事件分发器(dispatcher)”传送事件。

文件事件分发器(dispatcher)在收到事件之后,会根据事件的类型将事件分发给对应的 handler。

我们顺着图,从上到下的逐一讲解 Redis 是怎么实现这个 Reactor 模型的。

I/O 多路复用模块

Redis 的 I/O 多路复用模块,其实是封装了操作系统提供的 select,epoll,avport 和 kqueue 这些基础函数。向上层提供了一个统一的接口,屏蔽了底层实现的细节。

一般而言 Redis 都是部署到 linux 系统上,所以我们就看看使用 Redis 是怎么利用 linux 提供的 epoll 实现I/O 多路复用。

首先看看 epoll 提供的三个方法:


int epoll_create(int size);


int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);


int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

再看 Redis 对文件事件,封装epoll向上提供的接口:


typedef struct aeapiState {

 // epoll_event 实例描述符
 int epfd;

 // 事件槽
 struct epoll_event *events;

} aeApiState;


static int aeApiCreate(aeEventLoop *eventLoop)

static int aeApiResize(aeEventLoop *eventLoop, int setsize)

static void aeApiFree(aeEventLoop *eventLoop)

static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)

static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask)

static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)

所以看看这个ae_peoll.c 如何对 epoll 进行封装的:

  • aeApiCreate() 是对 epoll.epoll_create() 的封装。

  • aeApiAddEvent()和aeApiDelEvent() 是对 epoll.epoll_ctl()的封装。

  • aeApiPoll() 是对 epoll_wait()的封装。

这样 Redis 的利用 epoll 实现的 I/O 复用器就比较清晰了。

再往上一层次我们需要看看 ea.c 是怎么封装的?

首先需要关注的是事件处理器的数据结构

typedef struct aeFileEvent {
 // 监听事件类型掩码,
 // 值可以是 AE_READABLE 或 AE_WRITABLE ,
 // 或者 AE_READABLE | AE_WRITABLE
 int mask; 
 // 读事件处理器
 aeFileProc *rfileProc;
 // 写事件处理器
 aeFileProc *wfileProc;
 // 多路复用库的私有数据
 void *clientData;
} aeFileEvent;

mask 就是可以理解为事件的类型。

除了使用 ae_peoll.c 提供的方法外,ae.c 还增加 “增删查” 的几个 API。

  • 增:aeCreateFileEvent

  • 删:aeDeleteFileEvent

  • 查: 查包括两个维度 aeGetFileEvents 获取某个 fd 的监听类型和aeWait等待某个fd 直到超时或者达到某个状态。

事件分发器(dispatcher)

Redis 的事件分发器 ae.c/aeProcessEvents 不但处理文件事件还处理时间事件,所以这里只贴与文件分发相关的出部分代码,dispather 根据 mask 调用不同的事件处理器。

//从 epoll 中获关注的事件
numevents = aeApiPoll(eventLoop, tvp);
for (j = 0; j < numevents; j++) {
 // 从已就绪数组中获取事件
 aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
 int mask = eventLoop->fired[j].mask;
 int fd = eventLoop->fired[j].fd;
 int rfired = 0;
 // 读事件
 if (fe->mask & mask & AE_READABLE) {
  // rfired 确保读/写事件只能执行其中一个
  rfired = 1;
  fe->rfileProc(eventLoop,fd,fe->clientData,mask);
 }
 // 写事件
 if (fe->mask & mask & AE_WRITABLE) {
  if (!rfired || fe->wfileProc != fe->rfileProc)
   fe->wfileProc(eventLoop,fd,fe->clientData,mask);
 }
 processed++;
}

可以看到这个分发器,根据 mask 的不同将事件分别分发给了读事件和写事件。

文件事件处理器的类型

Redis 有大量的事件处理器类型,我们就讲解处理一个简单命令涉及到的三个处理器:

  • accepttcpHandler 连接应答处理器,负责处理连接相关的事件,当有client 连接到Redis的时候们就会产生 AE_READABLE 事件。引发它执行。

  • readQueryFromClinet 命令请求处理器,负责读取通过 sokect 发送来的命令。

  • sendReplyToClient 命令回复处理器,当Redis处理完命令,就会产生 AE_WRITEABLE 事件,将数据回复给 client。

文件事件实现总结

我们按照开始给出的 Reactor 模型,从上到下讲解了文件事件处理器的实现,下面将会介绍时间时间的实现。

时间事件

Reids 有很多操作需要在给定的时间点进行处理,时间事件就是对这类定时任务的抽象。

先看时间事件的数据结构:


typedef struct aeTimeEvent {
 // 时间事件的唯一标识符
 long long id; 
 // 事件的到达时间
 long when_sec; 
 long when_ms; 
 // 事件处理函数
 aeTimeProc *timeProc;
 // 事件释放函数
 aeEventFinalizerProc *finalizerProc;
 // 多路复用库的私有数据
 void *clientData;
 // 指向下个时间事件结构,形成链表
 struct aeTimeEvent *next;
} aeTimeEvent;

看见 next 我们就知道这个 aeTimeEvent 是一个链表结构。看图:

Redis中事件驱动模型的作用是什么

注意:这是一个按照id倒序排列的链表,并没有按照事件顺序排序

processTimeEvent

Redis 使用这个函数处理所有的时间事件,我们整理一下执行思路:

  • 记录最新一次执行这个函数的时间,用于处理系统时间被修改产生的问题。

  • 遍历链表找出所有 when_sec 和 when_ms 小于现在时间的事件。

  • 执行事件对应的处理函数。

  • 检查事件类型,如果是周期事件则刷新该事件下一次的执行事件。

  • 否则从列表中删除事件。

综合调度器(aeProcessEvents)

综合调度器是 Redis 统一处理所有事件的地方。我们梳理一下这个函数的简单逻辑:

// 1. 获取离当前时间最近的时间事件
shortest = aeSearchNearestTimer(eventLoop);

// 2. 获取间隔时间
timeval = shortest - nowTime;

// 如果timeval 小于 0,说明已经有需要执行的时间事件了。
if(timeval < 0){
 timeval = 0
}

// 3. 在 timeval 时间内,取出文件事件。
numevents = aeApiPoll(eventLoop, timeval);

// 4.根据文件事件的类型指定不同的文件处理器
if (AE_READABLE) {
 // 读事件
 rfileProc(eventLoop,fd,fe->clientData,mask);
}
 // 写事件
if (AE_WRITABLE) {
 wfileProc(eventLoop,fd,fe->clientData,mask);
}

以上的伪代码就是整个 Redis 事件处理器的逻辑。

我们可以再看看谁执行了这个 aeProcessEvents:

void aeMain(aeEventLoop *eventLoop) {
 eventLoop->stop = 0;
 while (!eventLoop->stop) {
  // 如果有需要在事件处理前执行的函数,那么运行它
  if (eventLoop->beforesleep != NULL)
   eventLoop->beforesleep(eventLoop);
  // 开始处理事件
  aeProcessEvents(eventLoop, AE_ALL_EVENTS);
 }
}

然后我们再看看是谁调用了 eaMain:

int main(int arGC, char **argv) {
 //一些配置和准备
 ...
 aeMain(server.el);
 
 //结束后的回收工作
 ...
}

我们在 Redis 的 main 方法中找个了它。

这个时候我们整理出的思路就是:

  • Redis 的 main() 方法执行了一些配置和准备以后就调用 eaMain() 方法。

  • eaMain() while(true) 的调用 aeProcessEvents()。

所以我们说 Redis 是一个事件驱动的程序,期间我们发现,Redis 没有 fork 过任何线程。所以也可以说 Redis 是一个基于事件驱动的单线程应用。

关于Redis中事件驱动模型的作用是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: Redis中事件驱动模型的作用是什么

本文链接: https://www.lsjlt.com/news/56631.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Redis中事件驱动模型的作用是什么
    这篇文章给大家介绍Redis中事件驱动模型的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言Redis 是一个事件驱动的内存数据库,服务器需要处理两种类型的事件。文件事件时...
    99+
    2024-04-02
  • Redis的事件驱动模型是什么
    这篇文章主要讲解了“Redis的事件驱动模型是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis的事件驱动模型是什么”吧!为什么 Redis 不使用基本的 Socket 编程模型?...
    99+
    2023-06-30
  • 浅谈Redis的事件驱动模型
    Redis 作为一个 Client-Server 架构的数据库,其源码中少不了用来实现网络通信的部分。而你应该也清楚,通常系统实现网络通信的基本方法是使用Socket编程模型,,包括...
    99+
    2024-04-02
  • javascript的事件驱动是什么
    本篇文章为大家展示了javascript的事件驱动是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。javascript的事件驱动有:1、鼠标单击事件“oncli...
    99+
    2024-04-02
  • javascript中的事件模型是什么
    本篇内容主要讲解“javascript中的事件模型是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript中的事件模型是什么”吧! ...
    99+
    2024-04-02
  • Javascript中事件驱动的原理是什么
    本篇文章为大家展示了Javascript中事件驱动的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。首先来看看这样一个应用场景,网页上有个链接,比如说高级搜...
    99+
    2024-04-02
  • web前端中事件驱动指的是什么
    这篇“web前端中事件驱动指的是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“web前...
    99+
    2024-04-02
  • javascript的事件驱动机制是什么
    这篇文章主要介绍“javascript的事件驱动机制是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“javascript的事件驱动机制是什么”文章能帮助大家解决...
    99+
    2024-04-02
  • java中的事件处理模型是什么
    java中的事件处理模型是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java有哪些集合类Java中的集合主要分为四类:1、List列表:有序的,可重复的;2、Queue...
    99+
    2023-06-14
  • redis中间件的作用是什么
    Redis中间件是一个高性能的内存数据库,用于缓存数据和加速数据访问。它的作用包括但不限于: 缓存数据:Redis可以将常用的数...
    99+
    2024-04-26
    redis
  • C#中流模型的作用是什么
    C#中流模型的作用是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。访问的两种模型:在程序中访问进而操作XML文件一般有两种模型,分别是使用DOM(文档对象模型)和流模型,使...
    99+
    2023-06-17
  • windows显卡驱动的作用是什么
    本篇内容主要讲解“windows显卡驱动的作用是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“windows显卡驱动的作用是什么”吧!显卡驱动的作用显卡是电脑图形的核心显示部分,关乎着电脑的...
    99+
    2023-07-01
  • Redis中线程IO模型是什么
    这篇文章将为大家详细讲解有关Redis中线程IO模型是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Redis是一个单线程的应用程序,NodeJs、Nginx都是单线...
    99+
    2024-04-02
  • Linux平台总线驱动设备模型是什么
    这篇文章主要介绍“Linux平台总线驱动设备模型是什么”,在日常操作中,相信很多人在Linux平台总线驱动设备模型是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux平台总线驱动设备模型是什么”的疑...
    99+
    2023-06-16
  • springmvc注解驱动的作用是什么
    Spring MVC注解驱动的作用是简化和加速开发过程,提高代码的可读性和可维护性。通过使用注解,可以避免繁琐的配置文件,减少开发人...
    99+
    2024-02-29
    springmvc
  • JavaScript中作用域工作模型是什么
    这篇文章主要介绍了JavaScript中作用域工作模型是什么 ,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。JavaScript内功系列:this指向详解,思维脑图与代码的结...
    99+
    2023-06-14
  • Node中的异步实现与事件驱动方法是什么
    这篇“Node中的异步实现与事件驱动方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Node中的异步实现与事件驱动方...
    99+
    2023-07-04
  • java中内存模型的作用是什么
    java中内存模型的作用是什么?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java基本数据类型有哪些Java的基本数据类型分为:1、整数类型,用来表示整数的数据类型。2、...
    99+
    2023-06-14
  • JS中onbeforeunload事件的作用是什么
    onbeforeunload事件是指在页面即将被卸载(关闭或刷新)之前触发的事件。它的作用是允许开发人员在页面被卸载之前执行一些操作...
    99+
    2023-10-11
    JS
  • C# 中Page_Error事件的作用是什么
    这篇文章给大家介绍C# 中Page_Error事件的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。ASP.NET 在处理和响应错误的方式上进行了若干改进。在传统的 ASP 中,是用"On Error...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作