Redis-网络模型

news2024/11/24 8:37:48

参考资料 :极客时间 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虽然比较理想,但是目前使用起来还有一些问题。
在这里插入图片描述

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

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

相关文章

sql服务无法启动 请键入net helpmsg 3534

然后 如果是管理员权限打开命令行输入操作的话 先清空 MySQL 下的 data 文件夹,然后确保系统环境变量中已经配置了 mysql 的 bin 目录到Path中,然后执行 sc delete mysql 得到 [SC] DeleteService 成功 后(也可能不会有返回信息&#xff…

SpringBoot项目jar包加密防止反编译

业务场景 由于公司业务需要,需要把jar包部署到其它公司的服务器,又不想泄露源码。 解决方法 1、代码混淆 采用proguard-maven-plugin插件 在单模块中此方案还算简单,但是现在项目一般都是多模块,一个模块依赖多个公共模块。那…

flask搞个简单登录界面

登录界面 直接放上login.html模板&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Lo…

Airoha AB157x EVB 介绍

0 Preface/Foreword 常用词汇&#xff1a; baseband and radio for intentive stereo, mono, or TWS &#xff08;AiroStereo&#xff09; audio application. baseband:基带 TWS&#xff1a;AiroStereo Audio Transparency&#xff1a;AiroThru EVK: Evaluation Kit A…

中国90米分辨率可蚀性因子K数据

数据时间&#xff1a;2023年 数据空间位置&#xff1a;全国 数据空间分辨率&#xff1a;90m 数据坐标系&#xff1a;WGS1984 数据格式&#xff1a;tiff 数据来源&#xff1a;地球资源数据云平台(www.gis5g.com)&#xff0c;如需要请自行联系 数据简介&#xff1a;土壤可蚀…

JVM-10-类加载

Java虚拟机把描述类的数据从Class文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#xff0c;最终形成可以被虚拟机直接使用的Java类型&#xff0c;这个过程被称作虚拟机的类加载机制。 一个类型从被加载到虚拟机内存中开始&#xff0c;到卸载出内存为止&#…

强大的电子书阅读器:OmniReader Pro for mac

&#x1f50d; OmniReader Pro 是一款专为 Mac 设计的强大阅读工具&#xff0c;它能够帮助你更高效地阅读和处理各种文本内容。无论是电子书、新闻文章、网页文本还是文件资料&#xff0c;OmniReader Pro 都能胜任&#xff01; ✅ OmniReader Pro 提供了丰富的功能&#xff0c…

劲松中西医结合医院hpv诊疗中心建议:提高免疫力做好5件事

谭巍主任在近期的一次访谈中明确指出&#xff0c;免疫力是HPV最好的医生。他强调&#xff0c;提高免疫力是预防和治疗HPV的关键。通过科学的饮食和营养搭配&#xff0c;我们可以增强免疫力&#xff0c;有效抵抗病毒的侵袭。 首先&#xff0c;我们要明白什么是免疫力。免疫力是…

大创项目推荐 深度学习 opencv python 实现中国交通标志识别

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

1.3 什么是接口?什么是接口测试?

上一小节我们认识了C/S和B/S架构,那在B/S架构中,我们测试最常接触的,就是接口。本课程的重点是接口自动化测试,那同学们真的了解什么是接口吗?首先,我们从通俗的角度来看什么是接口。在计算机中,接口是计算机系统中两个独立的部件进行信息交换的共享边界。这种交换可以发…

Mac managing Multiple Python Versions With pyenv 【 mac pyenv 管理多个python 版本 】

文章目录 1. 简介2. 安装2.1 brew 安装 pyenv2.2 脚本安装 3. pyenv 安装 Python4. 卸载 python5. 管理 python 1. 简介 Pyenv 是一个用于管理和切换多个 Python 版本的工具。它允许开发人员在同一台计算机上同时安装和使用多个不同的 Python 版本&#xff0c;而无需对系统进行…

基于SSM的婚恋网站的设计与实现论文

基于SSM的婚恋网站的设计与实现 摘要 随着信息互联网购物的飞速发展&#xff0c;一般企业都去创建属于自己的管理系统。本文介绍了基于SSM的婚恋网站的设计与实现的开发全过程。通过分析企业对于基于SSM的婚恋网站的设计与实现的需求&#xff0c;创建了一个计算机管理基于SSM…

力扣刷题记录(15)LeetCode:509、70、746

目录 509.斐波那契数 70.爬楼梯 746.使用最小花费爬楼梯 总结 ​​​​​​ 用一个数组来存储前两个数的值&#xff0c;然后根据前两个数的值来确定当前的值。 class Solution { public:int fib(int n) {if(n<2) return n;vector<int> v;v.push_back(0);v.push…

【深度学习目标检测】九、基于yolov5的路标识别(python,目标检测)

YOLOv5是目标检测领域一种非常优秀的模型&#xff0c;其具有以下几个优势&#xff1a; 1. 高精度&#xff1a;YOLOv5相比于其前身YOLOv4&#xff0c;在目标检测精度上有了显著的提升。YOLOv5使用了一系列的改进&#xff0c;如更深的网络结构、更多的特征层和更高分辨率的输入图…

大模型(LLM)+词槽(slot)构建动态场景多轮对话系统

构建动态场景多轮对话系统 引言 在人工智能和自然语言处理领域&#xff0c;聊天机器人的开发一直是一个热点话题。近年来&#xff0c;随着大型语言模型&#xff08;LLM&#xff09;的进步&#xff0c;构建能够理解和响应各种用户需求的聊天机器人变得更加可行和强大。本文将介…

python识别增强静脉清晰度 opencv-python图像处理案例

一.任务说明 用python实现静脉清晰度提升。 二.代码实现 import cv2 import numpy as npdef enhance_blood_vessels(image):# 调整图像对比度和亮度enhanced_image cv2.convertScaleAbs(image, alpha0.5, beta100)# 应用CLAHE&#xff08;对比度受限的自适应直方图均衡化&am…

万能在线答题考试小程序源码系统 网课必备 既能刷题又能考试 附带完整的搭建教程

在当前的数字化时代&#xff0c;移动应用程序已经成为人们日常生活的重要组成部分。其中&#xff0c;小程序因其无需下载、即用即走的特性&#xff0c;备受用户青睐。现如今&#xff0c;将在线答题考试功能集成到小程序中&#xff0c;可以极大地提高学习者的学习效率和兴趣。 …

历时两个月,我终于研究透外卖红包是怎么一回事

近几年&#xff0c;推广外卖红包爆火&#xff0c;各种推广外卖红包的公众号层出不穷。于是&#xff0c;我就在想外卖红包究竟是怎么一回事。就这样&#xff0c;我带着问题开始了关于外卖红包的研究。 在研究的过程中&#xff0c;我开始了解隐藏优惠券、cps等一系列相关的术语。…

rabbitmq界面主要参数分析

本篇主要分析rabbitmq broker界面参数 rabbitmq界面主要参数分析 1、connections User Name: user - 连接所使用的用户名。 State: running - 连接当前的状态&#xff0c;这里表明连接是活动的。 SSL/TLS: ○ - 表示这个连接没有使用SSL/TLS加密。 内部或受信任的网络中可能…

【RTOS学习】源码分析(通用队列 队列 队列集)

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《RTOS学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 前面本喵讲解了和任务相关的FreeRTOS源码&#xff0c;进行再来介绍一下用于任务间通信的几种数据结…