300分钟吃透分布式缓存-20讲:Redis如何处理文件事件和时间事件?

news2025/1/22 14:45:35

Redis 事件驱动模型

事件驱动模型
Redis 是一个事件驱动程序,但和 Memcached 不同的是,Redis 并没有采用 libevent 或 libev 这些开源库,而是直接开发了一个新的事件循环组件。Redis 作者给出的理由是,尽量减少外部依赖,而自己开发的事件模型也足够简洁、轻便、高效,也更易控制。Redis 的事件驱动模型机制封装在 aeEventLoop 等相关的结构体中,网络连接、命令读取执行回复,数据的持久化、淘汰回收 key 等,几乎所有的核心操作都通过 ae 事件模型进行处理。
在这里插入图片描述
Redis 的事件驱动模型处理 2 类事件:

& 文件事件,如连接建立、接受请求命令、发送响应等;

& 时间事件,如 Redis 中定期要执行的统计、key 淘汰、缓冲数据写出、rehash等。

文件事件处理
在这里插入图片描述
Redis 的文件事件采用典型的 Reactor 模式进行处理。Redis 文件事件处理机制分为 4 部分:

& 连接 socket

& IO 多路复用程序

& 文件事件分派器

& 事件处理器

文件事件是对连接 socket 操作的一个抽象。当端口监听 socket 准备 accept 新连接,或者连接 socket 准备好读取请求、写入响应、关闭时,就会产生一个文件事件。IO 多路复用程序负责同时监听多个 socket,当这些 socket 产生文件事件时,就会触发事件通知,文件分派器就会感知并获取到这些事件。

虽然多个文件事件可能会并发出现,但 IO 多路复用程序总会将所有产生事件的 socket 放入一个队列中,通过这个队列,有序的把这些文件事件通知给文件分派器。

IO多路复用
Redis 封装了 4 种多路复用程序,每种封装实现都提供了相同的 API 实现。编译时,会按照性能和系统平台,选择最佳的 IO 多路复用函数作为底层实现,选择顺序是,首先尝试选择 Solaries 中的 evport,如果没有,就尝试选择 Linux 中的 epoll,否则就选择大多 UNIX 系统都支持的 kqueue,这 3 个多路复用函数都直接使用系统内核内部的结构,可以服务数十万的文件描述符。

如果当前编译环境没有上述函数,就会选择 select 作为底层实现方案。select 方案的性能较差,事件发生时,会扫描全部监听的描述符,事件复杂度是 O(n),并且只能同时服务有限个文件描述符,32 位机默认是 1024 个,64 位机默认是 2048 个,所以一般情况下,并不会选择 select 作为线上运行方案。Redis 的这 4 种实现,分别在 ae_evport、ae_epoll、ae_kqueue 和 ae_select 这 4 个代码文件中。

文件事件收集及派发器
Redis 中的文件事件分派器是 aeProcessEvents 函数。它会首先计算最大可以等待的时间,然后利用 aeApiPoll 等待文件事件的发生。如果在等待时间内,一旦 IO 多路复用程序产生了事件通知,则会立即轮询所有已产生的文件事件,并将文件事件放入 aeEventLoop 中的 aeFiredEvents 结构数组中。每个 fired event 会记录 socket 及 Redis 读写事件类型。

这里会涉及将多路复用中的事件类型,转换为 Redis 的 ae 事件驱动模型中的事件类型。以采用 Linux 中的 epoll 为例,会将 epoll 中的 EPOLLIN 转为 AE_READABLE 类型,将 epoll 中的 EPOLLOUT、EPOLLERR 和 EPOLLHUP 转为 AE_WRITABLE 事件。

aeProcessEvents 在获取到触发的事件后,会根据事件类型,将文件事件 dispatch 派发给对应事件处理函数。如果同一个 socket,同时有读事件和写事件,Redis 派发器会首先派发处理读事件,然后再派发处理写事件。

文件事件处理函数分类
Redis 中文件事件函数的注册和处理主要分为 3 种。

& 连接处理函数 acceptTcpHandler

Redis 在启动时,在 initServer 中对监听的 socket 注册读事件,事件处理器为 acceptTcpHandler,该函数在有新连接进入时,会被派发器派发读任务。在处理该读任务时,会 accept 新连接,获取调用方的 IP 及端口,并对新连接创建一个 client 结构。如果同时有大量连接同时进入,Redis 一次最多处理 1000 个连接请求。

& readQueryFromClient 请求处理函数

连接函数在创建 client 时,会对新连接 socket 注册一个读事件,该读事件的事件处理器就是 readQueryFromClient。在连接 socket 有请求命令到达时,IO 多路复用程序会获取并触发文件事件,然后这个读事件被派发器派发给本请求的处理函数。readQueryFromClient 会从连接 socket 读取数据,存入 client 的 query 缓冲,然后进行解析命令,按照 Redis 当前支持的 2 种请求格式,及 inline 内联格式和 multibulk 字符块数组格式进行尝试解析。解析完毕后,client 会根据请求命令从命令表中获取到对应的 redisCommand,如果对应 cmd 存在。则开始校验请求的参数,以及当前 server 的内存、磁盘及其他状态,完成校验后,然后真正开始执行 redisCommand 的处理函数,进行具体命令的执行,最后将执行结果作为响应写入 client 的写缓冲中。

& 命令回复处理器 sendReplyToClient

当 redis需要发送响应给client时,Redis 事件循环中会对client的连接socket注册写事件,这个写事件的处理函数就是sendReplyToClient。通过注册写事件,将 client 的socket与 AE_WRITABLE 进行间接关联。当 Client fd 可进行写操作时,就会触发写事件,该函数就会将写缓冲中的数据发送给调用方。
在这里插入图片描述
Redis 中的时间事件是指需要在特定时间执行的事件。多个 Redis 中的时间事件构成 aeEventLoop 中的一个链表,供 Redis 在 ae 事件循环中轮询执行。

Redis 当前的主要时间事件处理函数有 2 个:

& serverCron

& moduleTimerHandler

Redis 中的时间事件分为 2 类:

& 单次时间,即执行完毕后,该时间事件就结束了。

& 周期性事件,在事件执行完毕后,会继续设置下一次执行的事件,从而在时间到达后继续执行,并不断重复。

时间事件主要有 5 个属性组成。

& 事件 ID:Redis 为时间事件创建全局唯一 ID,该 ID 按从小到大的顺序进行递增。

& 执行时间 when_sec 和 when_ms:精确到毫秒,记录该事件的到达可执行时间。

& 时间事件处理器 timeProc:在时间事件到达时,Redis 会调用相应的 timeProc 处理事件。

& 关联数据 clientData:在调用 timeProc 时,需要使用该关联数据作为参数。

& 链表指针 prev 和 next:它用来将时间事件维护为双向链表,便于插入及查找所要执行的时间事件。

时间事件的处理是在事件循环中的 aeProcessEvents 中进行。执行过程是:

  1. 首先遍历所有的时间事件。

  2. 比较事件的时间和当前时间,找出可执行的时间事件。

  3. 然后执行时间事件的 timeProc 函数。

  4. 执行完毕后,对于周期性时间,设置时间新的执行时间;对于单次性时间,设置事件的 ID为 -1,后续在事件循环中,下一次执行 aeProcessEvents 的时候从链表中删除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1495635.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java】关于ZooKeeper的原理以及一致性问题,协议和算法和ZooKeeper的理论知识和应用 场景

1. 目录 目录 1. 目录 2. 什么是ZooKeeper 3. 一致性问题 4. 一致性协议和算法 4.1. 2PC(两阶段提交) 4.2. 3PC(三阶段提交) 4.3. Paxos 算法 4.3.1. prepare 阶段 4.3.2. accept 阶段 4.3.3. paxos 算法的死循环…

2024年阿里云2核4G服务器租用价格_2核4G性能测评_支持人数

阿里云2核4G服务器多少钱一年?2核4G配置1个月多少钱?2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

JavaScript 入门手册(一)

目录 一、JavaScript 是什么? 1.1 JavaScript 介绍 1.2 JavaScript 与 ECMAScript 的关系 1.3 JavaScript 是脚本语言 1.4 JavaScript 的特点 1.5 运行 JavaScript 1.6 保留关键字 二、Node.js 是什么? 2.1 运行时是什么? 2.2 Node.js 的组成…

Ubuntu20.04安装并配置vscode

Ubuntu20.04安装并配置vscode vscode安装miniconda安装创建虚拟python3.8环境pytorch和匹配的cuda安装 vscode安装 VSCode可以通过 Snapcraft 商店或者微软源仓库中的一个 deb 软件包来安装。 我们这里选用安装VSCode snap版,打开你的终端(CtrlAltT)并且运行下面的…

LeetCode_25_困难_K个一组翻转链表

文章目录 1. 题目2. 思路及代码实现(Python)2.1 模拟 1. 题目 给你链表的头节点 h e a d head head ,每 k k k 个节点一组进行翻转,请你返回修改后的链表。 k k k 是一个正整数,它的值小于或等于链表的长度。如果节…

VTK的编译和部署,配合c++和visual studio2022,VTK开发环境的配置

1.下载 在官网选择最新的版本 Download | VTK 下载之后进行解压,然后再里面创建build目录,方便后面使用cmake进行编译 2.对源码进行编译 打卡Cmake,如图操作 可以看到点击configure之后,cmake对我们的代码在进行处理 处理完成之…

openssl3.2 - exp - 产生随机数

文章目录 openssl3.2 - exp - 产生随机数概述笔记END openssl3.2 - exp - 产生随机数 概述 要用到openssl产生的随机数, 查了资料. 如果用命令行产生随机数, 如下: openssl rand -hex -num 6 48bfd3a64f54单步跟进去, 看到主要就是调用了一个RAND_bytes(), 没其他了. 官方说…

【vue.js】文档解读【day 2】 | 计算属性

如果阅读有疑问的话,欢迎评论或私信!! 本人会很热心的阐述自己的想法!谢谢!!! 文章目录 计算属性计算属性 vs 方法可计算属性Getter不应有副作用避免直接修改计算属性值 计算属性 我们已经学习…

基于SpringBoot+Vue+ElementUI+Mybatis前后端分离管理系统超详细教程(二)

学习后端CRUD操作 书接上文,我们学习了前后端分离项目的基础环境配置和用户管理模块的前后端基础搭建,以下链接是上一节教程内容详细步骤,友友们可以跟着步骤实操。本节课程我们在前面项目的基础上接着学习后端CRUD操作,真正打通数…

【你也能从零基础学会网站开发】Web建站之HTML+CSS入门篇 网站开发的基本概念与站点文件的管理

🚀 个人主页 极客小俊 ✍🏻 作者简介:web开发者、设计师、技术分享 🐋 希望大家多多支持, 我们一起学习和进步!😄 🏅 如果对你有帮助的话,欢迎评论 💬点赞👍&…

leetcode2

翻转链表 struct ListNode* reverseList(struct ListNode* head) {struct ListNode* prev NULL;struct ListNode* curr head;while (curr ! NULL) {struct ListNode* nextTemp curr->next;//nextTemp的作用是为了记录,以便再反转后可以curr->next prev; …

聚观早报 | ChatGPT新增朗读功能;vivo X Fold3细节曝光

聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 3月6日消息 ChatGPT新增朗读功能 vivo X Fold3细节曝光 魅族21 PRO开启内测 Anthropic推出Claude 3系列 海底捞…

基于Mindspore,通过Resnet50迁移学习实现猫十二分类

使用平台介绍 使用平台:启智AI协作平台 使用数据集:百度猫十二分类 数据集介绍 有cat_12_train和cat_12_test和train_list.txt train_list.txt内有每张图片所对应的标签 Minspore部分操作科普 数据集加载 Mindspore加载图片数据集就直接调整成这种…

6020一拖二快充线:手机充电的革命性创新

在快节奏的现代生活中,手机已不仅仅是一个通讯工具,更是我们工作、学习和娱乐的得力助手。然而,手机的电量问题一直是困扰着我们的难题。为了解决这个问题,市场上出现了一种名为“一拖二快充线”的充电设备,它不仅具备…

事件对象与环境对象

一、事件对象 事件对象里有事件触发时的相关信息&#xff0c;包括属性和方法。注册时间中&#xff0c;回调函数的第一个参数就是事件对象&#xff0c;一般命名为event、ev、e。其中e.target是主要对象&#xff0c;target是事件源对象&#xff0c;即当前触发元素。 <button …

Midjourney入门:AI绘画真的能替代人类的丹青妙笔吗?

名人说&#xff1a;一花独放不是春&#xff0c;百花齐放花满园。——《增广贤文》 作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、简要介绍1、Midjourney2、使用方法 二、绘画1、动物类2、风景类3、动漫类4、艺…

Unity:Animation 三 Playable、ImportModel

目录​​​​​​​ 1. Playables API 1.1 Playable vs Animation 1.2 Advantages of using the Playables API 1.3 PlayableGraph Visualizer 2. Creating models outside of Unity 2.1 Preparing your model files for export 2.1.1 Scaling factors 2.1.2 优化模型文…

腾讯云2核2G3M轻量应用服务器优惠价格61元一年

腾讯云2核2G3M轻量应用服务器优惠价格61元一年&#xff0c;200GB月流量、40GB SSD云硬盘。 一张表看懂腾讯云服务器租用优惠价格表&#xff0c;一目了然&#xff0c;腾讯云服务器分为轻量应用服务器和云服务器CVM&#xff0c;CPU内存配置从2核2G、2核4G、4核8G、8核16G、4核16…

网络编程:数据库实现增删改

1.数据库实现增删改 程序代码&#xff1a; 1 #include<myhead.h>2 //定义添加数据函数3 int do_add(sqlite3*ppDb)4 {5 //准备sql语句6 int add_numb;//工号7 char add_name[20];//姓名8 double add_salary;9 printf("请输入要添加的工号:&quo…

网康科技 NS-ASG 应用安全网关 SQL注入漏洞复现(CVE-2024-2022)

0x01 产品简介 网康科技的NS-ASG应用安全网关是一款软硬件一体化的产品,集成了SSL和IPSec,旨在保障业务访问的安全性,适配所有移动终端,提供多种链路均衡和选择技术,支持多种认证方式灵活组合,以及内置短信认证、LDAP令牌、USB KEY等多达13种认证方式。 0x02 漏洞概述 …