Redis-网络模型

参考资料 :极客时间 Redis(亚风)

前置知识

系统隔离
为了避免⽤户应⽤导致冲突甚⾄内核崩溃,⽤户应⽤与内核是分离的:
进程的寻址空间会划分为两部分:内核空间、⽤户空间
• ⽤户空间只能执⾏受限的命令(Ring3),⽽且不能直接调⽤系统资源,必
须通过内核提供的接⼝来访问
• 内核空间可以执⾏特权命令(Ring0),调⽤⼀切系统资源

在这里插入图片描述
缓冲区
Linux系统为了提⾼IO效率,会在⽤户空间和内核空间都加⼊缓冲区:
• 写数据时,要把⽤户缓冲数据拷⻉到内核缓冲区,然后写⼊设备
• 读数据时,要从设备读取数据到内核缓冲区,然后拷⻉到⽤户缓冲区
在这里插入图片描述
这里的数据交互采用不同的模型就会有不同的性能,因而也诞生了一些网络IO模型。

IO模型

阻塞IO

在这里插入图片描述

非阻塞IO

在这里插入图片描述

⽆论是阻塞IO还是⾮阻塞IO,⽤户应⽤在⼀阶段都需要调⽤recvfrom来获取数据,差别在于⽆数据时的理⽅案:
• 如果调⽤recvfrom时,恰好没有数据,阻塞IO会使进程阻塞,⾮阻塞IO使CPU空转,都不能充分发挥CPU的作⽤。
• 如果调⽤recvfrom时,恰好有数据,则⽤户进程可以直接进⼊第⼆阶段,读取并处理数据。

IO多路复用
文件表述符的概念

⽂件描述符(File Descriptor):简称FD,是⼀个从0开始递增的⽆符号整数,⽤来关联Linux中的⼀个⽂件。在Linux中,⼀切皆⽂件,例如常规⽂件、视频、硬件设备等,当然也包括⽹络套接字 (Socket)。
IO多路复⽤:是利⽤单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从⽽避免⽆效的等待,充分利⽤CPU资源。

区间听FD有三种实现方式

1 select
Sekect的结构

typedef struct {
	// ⻓度为 1024/32 = 32
	// 共1024个bit位,每个bit位代表⼀个fd,0代表未就绪,1代表就绪
	int fds_bits[__FD_SETSIZE / __NFDBITS]} fd_set;
// select函数,⽤于监听多个fd的集合
int select(
int nfds,//要监视的fd_set的最⼤fd + 1
fd_set *readfds, //要监听读事件的fd集合
fd_set *writefds, // 要监听写事件的fd集合
fd_set *exceptfds,// 要监听异常事件的fd集合
//超时时间,null-永不超时;0-不阻塞等待;⼤于0-固定等待时间
struct timeval *timeout);

在这里插入图片描述
select模式存在的问题:
• 需要将整个fd_set从⽤户空间拷⻉到内核空间,select结束还要再次拷⻉回⽤户空间
• select⽆法得知具体是哪个fd就绪,需要遍历整个fd_set
• fd_set监听的fd数量不能超过1024(因为32个int,每个int 4 * 8 32 位)总共1024位。
2 poll

#define POLLIN //可读事件
#define POLLOUT //可写事件
#define POLLERR //错误事件
// pollfd结构
struct pollfd {
    int fd; //要监听的fd
    short int events;/*要监听的事件类型:读、写、异常*/
    short int revents;/* 实际发⽣的事件类型*/
}// poll函数
int poll(
struct pollfd *fds,// pollfd数组,可以⾃定义⼤⼩
nfds_t nfds, //数组元素个数
int timeout) // 超时时间

1 ) 创建pollfd数组,向其中添加关注的fd信息
2 )调⽤poll函数,将pollfd数组拷⻉到内核空间,转链表存储(内核要求转换为链表)
3 )内核遍历fd,判断是否就绪
4 )数据就绪或超时后,拷⻉pollfd数组到⽤户空间,返回就绪fd数量n
5 )判断n是否⼤于0,⼤于0则遍历pollfd数组,找到就绪的fd

与select对⽐:

整体过程和Select大同小异。结构优化了一些,但是还是需要遍历fd_set.

select模式中的fd_set⼤⼩固定为1024,⽽pollfd⽆上限,监听FD越多,每次遍历消耗时间也越久,性能反⽽会下降。

3 epoll

struct eventpoll {

    struct rb_root rbr;//红⿊树,记录要监听的FD

    struct list_head rdlist;// 链表,记录就绪的FD

}//1.会在内核创建eventpoll结构体,返回对应的句柄epfd

int epoll_create(int size)//2.将⼀个FD添加到epoll的红⿊树中,并设置ep_poll_callback

// callback触发时,就把对应的FD加⼊到rdlist这个就绪列表中

int epoll_ctl(

    int epfd, // epoll实例的句柄

    int op, //要执⾏的操作,包括:ADD、 MOD、 DEL

    int fd,//要监听的FD

    struct epoll_event *event // 要监听的事件类型:读、写、异常等

)//3.循环检查rdlist列表是否为空,不为空则返回就绪的FD的数量

int epoll_wait(

int epfd,

struct epoll_event *events, //event数组,⽤于接收就绪的FD 属于用户空间

int maxevents, // events数组的最⼤⻓度

int timeout //超时时间,-1不超时;0不阻塞;⼤于0为阻塞时间);
    )

在这里插入图片描述
具体流程:
在这里插入图片描述

三种模式的对比:
select模式存在的三个问题:

• 能监听的FD最⼤不超过1024

• 每次select都需要把所有要监听的FD都拷⻉到内核

• 每次都要遍历所有FD来判断就绪状态

poll模式的问题:

• poll利⽤链表解决了select中监听FD上限的问题,但依然要遍历所有FD,如

果监听较多,性能会下降

epoll模式中如何解决这些问题的?

• 基于epoll实例中的红⿊树保存要监听的FD,增删改查效率⾮常⾼

• 每个FD只需要执⾏⼀次epollctl添加到红⿊树,⽆需重复拷⻉FD到内核空间

• 内核会将就绪的FD直接拷⻉到⽤户空间的指定位置,⽤户进程⽆需遍历所有FD就能知道就绪的FD是谁当FD有数据可读时,我们调⽤epollwait就可以得到通知。但是事件通知的模式

有两种:

LevelTriggered:简称LT。当FD有数据可读时,会重复通知多次,直⾄数据处理完成。是Epoll的默认模式。

EdgeTriggered:简称ET。当FD有数据可读时,只会被通知⼀次,不管数据是否处理完成。

ET模式避免了LT模式可能出现的惊群现象(就比如有多个进程监听了FD,这个FD一旦通知就会唤醒所有的进程,但是实际只需要一个进程来处理。)

ET模式最好结合⾮阻塞IO读取FD数据,相⽐LT会复杂。

信号驱动IO

信号驱动IO是与内核建⽴SIGIO的信号关联并设置回调,当內核有FD就绪时,会发出SIGIO信号通知⽤户,期间⽤户应⽤可以执⾏其它业务,⽆需阻塞等待。
在这里插入图片描述

存在的问题:当有⼤量lO操作时,信号较多,SIGlO处理函数不能及时处理可能导致信号队列溢出,⽽且内核空间与⽤户空间的频繁信号交互性能也较低。

AIO(异步IO)

AIO的整个过程都是⾮阻塞的,⽤户进程调⽤完异步API后就可以去做其它事情,内核等待数据就绪并拷⻉到⽤户空间后才会递交信号,通知⽤户进程。
在这里插入图片描述
IO操作是同步还是异步,关键看数据在内核空间与⽤户空间的拷⻉过程(数据读写的IO操作)
在这里插入图片描述

总结在Redis里面采用了IO多路复用,具体是epoll这种模式来实现。后面的信号IO 和 AIO虽然比较理想,但是目前使用起来还有一些问题。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

激活函数-SwiGLU

SwiGLU SiLU 函数是一种神经网络中的激活函数,全称是 Sigmoid Linear Unit, 也被称为 Swish 函数。它由 Google Brain 在 2017 年提出,是一种非线性激活函数,能够有效地对神经网络的输入进行非线性变换。 定义 f ( x ) x ∗ σ ( x ) f(x)…

vue3使用vue-router嵌套路由(多级路由)

文章目录 1、Vue3 嵌套路由2、项目结构3、编写相关页面代码3.1、编写route文件下 index.ts文件3.2、main.ts文件代码:3.3、App.vue文件代码:3.4、views文件夹下的Home文件夹下的index.vue文件代码:3.5、views文件夹下的Home文件夹下的Tigerhh…

生命在于学习——TV电视盒子渗透测试抓包设置

一、前言 封面图是示例图,因为涉及到保密,所以本次测试的电视盒子不放出外观和设置界面。 这一次要测试电视盒子,大家也都知道,市面上的电视盒子大部分都是Android,当然,要使用笔记本去抓电视盒子的数据包…

圣诞节来了,为大家送上专属圣诞树

Hello大家好,我是Dream。 今天给大家分享一下我很早之前做过的圣诞树,分享给大家,希望可以帮助到大家度过一个浪漫的圣诞节~ Python打造专属于你的圣诞树落叶雪花背景音乐浪漫弹窗 五合一版圣诞树 一、背景故事圣诞节风波❤️❤️❤️ 二、五…

针对海量数据的存储与访问瓶颈的解决方案

背景 在当今这个时代,人们对互联网的依赖程度非常高,也因此产生了大量的数据,企业视这些数据为瑰宝。而这些被视为瑰宝的数据为我们的系统带来了很大的烦恼。这些海量数据的存储与访问成为了系统设计与使用的瓶颈,而这些数据往往存…

内网BUG管理系统本地部署并结合内网穿透实现异地远程访问

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

Windows如何安装使用TortoiseSVN客户端并实现公网访问本地SVN Server

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统,它与Apache Subversion(SVN)集成在一起,提供了一个用户友好的界面,方便用…

泛型深入理解

泛型的概述 泛型&#xff1a;是JDK5中引入的特性&#xff0c;可以在编译阶段约束操作的数据类型&#xff0c;并进行检查。 泛型的格式&#xff1a;<数据类型>; 注意&#xff1a;泛型只能支持引用数据类型。 集合体系的全部接口和实现类都是支持泛型的使用的。 泛型的…

周周清(3)

周一&#xff1a; 写了一道算法题&#xff0c;然后由于身体原因&#xff0c;在宿舍休息了很久&#xff1b;然后还是完成了一道算法题&#xff1a;写了一道LRC缓存题&#xff0c;之前就开始写了&#xff0c;写了很久&#xff0c;每次都开始动笔&#xff0c;刚开始用的是队列加m…

太阳能电池效能IV测试PV检测太阳光模拟器

目录 概述 一、系统组成 产品特点&#xff1a; 技术参数 数字源表 本系统支持Keithley24xx系列源表 标准太阳能电池 低阻测试夹具 自动化测试软件 概述 太阳能光伏器件的所有性能表征手段中&#xff0c;IV特性测试无疑是最直观、最有效、最被广泛应用的一种…

智能配电房运维

智能配电房运维是指利用先进的信息化技术&#xff0c;依托电力智慧运维工具-电易云&#xff0c;对配电房的电气运行设备进行实时在线监测、集中监控和故障诊断处理&#xff0c;以提高设备维护效率、降低停电损失、提高用电效益&#xff0c;并消除用户终端配电系统的安全隐患。 …

进来看!企业有效监管员工工作微信的总要性

随着社交媒体的普及和信息传播的便捷化&#xff0c;员工在工作间隙利用微信进行交流已经成为一种常见的现象。然而&#xff0c;这种行为也引发了企业对员工微信监管的需求。 首先&#xff0c;企业监管员工微信可以帮助确保企业对内部信息的保密和安全。通过监管员工微信&#…

演讲回顾:半导体设计中的数字资产管理最佳实践

近日&#xff0c;在广州举行的中国集成电路设计业2023年会&#xff08;ICCAD 2023&#xff09;上&#xff0c;龙智资深顾问、技术支持部门负责人李培将带来主题演讲“半导体设计中的数字资产管理”&#xff0c;聚焦数字资产管理的两个层面——文件级别的管理和更高抽象层次的管…

Kotlin 笔记 -- Kotlin 语言特性的理解(二)

都是编译成字节码&#xff0c;为什么 Kotlin 能支持 Java 中没有的特性&#xff1f; kotlin 有哪些 Java 中没有的特性&#xff1a; 类型推断、可变性、可空性自动拆装箱、泛型数组高阶函数、DSL顶层函数、扩展函数、内联函数伴生对象、数据类、密封类、单例类接口代理、inter…

每日一练2023.12.18——天梯赛的善良【PTA】

题目链接&#xff1a;L1-079 天梯赛的善良 题目要求&#xff1a; 天梯赛是个善良的比赛。善良的命题组希望将题目难度控制在一个范围内&#xff0c;使得每个参赛的学生都有能做出来的题目&#xff0c;并且最厉害的学生也要非常努力才有可能得到高分。 于是命题组首先将编程能…

「Vue3面试系列」Vue3.0的设计目标是什么?做了哪些优化?

文章目录 一、设计目标更小更快更友好 三、优化方案源码源码管理TypeScript 性能语法 API逻辑组织逻辑复用 参考文献 一、设计目标 不以解决实际业务痛点的更新都是耍流氓&#xff0c;下面我们来列举一下Vue3之前我们或许会面临的问题 随着功能的增长&#xff0c;复杂组件的代…

【Cocos Creator】vscode 保存代码自动编译

使用Cocos Creator的时候&#xff0c;之前每次修改代码&#xff0c;都要到编辑器界面点击刷新按钮&#xff0c;感觉有些麻烦&#xff0c;搜索引擎上找到的解决方案都比较麻烦&#xff0c; 最后在vscode&#xff0c;刚好找到一款插件–Cocos Creator Devtools。 cocos-creator-…

盲盒扭蛋机小程序,科技与传统的完美结合

盲盒扭蛋具有着较大的粉丝群体&#xff0c;成为一大商业模式。扭蛋机与盲盒具有一样的特征&#xff0c;不确定性、未知性&#xff0c;深深吸引着消费者。 传统的扭蛋机一般活跃于各大商场中&#xff0c;深受不同年龄层人的喜欢。但随着互联网技术的完善&#xff0c;相对于线下…

Kafka消息延迟和时序性详解(文末送书)

目录 一、概括1.1 介绍 Kafka 消息延迟和时序性1.1.1 什么是 Kafka 消息延迟&#xff1f;1.1.2 为什么消息延迟很重要&#xff1f;1.1.3 什么是 Kafka 消息时序性&#xff1f;1.1.4 消息延迟和时序性的关系 1.2 延迟的来源1.2.1 Kafka 内部延迟 二、衡量和监控消息延迟2.1 延迟…

解决 Hbuilder打包 Apk pad 无法横屏 以及 H5 直接打包 成Apk

解决 Hbuilder打包 Apk pad 无法横屏 前言云打包配置 前言 利用VUE 写了一套H5 想着 做一个APP壳 然后把 H5 直接嵌进去 客户要求 在pad 端 能够操作 然后页面风格 也需要pad 横屏展示 云打包 配置 下面是manifest.json 配置文件 {"platforms": ["iPad"…