Redis原理篇(二)网络模型

news2024/10/6 2:25:55

一、用户空间和内核空间

应用需要通过Linux内核与硬件交互。
在这里插入图片描述
内核本质也是应用,运行的时候也需要CPU资源、内存资源。用户应用也在消耗这些资源。
为了避免用户应用导致冲突甚至内核崩溃,用户应用与内核是分离的:

  • 进程的寻址空间会划分为两部分:内核空间、用户空间
  • 用户空间只能执行受限的命令(Ring3),而且不能直接调用系统资源,必须通过内核提供的接口来访问
  • 内核空间可以执行特权命令(Ring0),调用一切系统资源。

寻址空间:无论内核还是用户应用,都无法直接访问物理内存,而是分配虚拟的内存空间,映射到不同的物理内存空间。内核和用户应用,再去访问虚拟内存空间,就需要有对应的虚拟地址(无符号的整数)
示例:32位系统,带宽32,地址的最大值就是2的32次方,也就是寻址的范围从0到2的32次方,也就是4GB.
在这里插入图片描述

在这里插入图片描述

IO在用户空间和内核空间切换的整体流程:
在这里插入图片描述

二、阻塞IO

访问流程图
在这里插入图片描述
顾名思义,阻塞IO就是两个阶段都必须阻塞等待。
在这里插入图片描述

三、非阻塞IO

顾名思义,非阻塞IO的recvfrom操作会立即返回结果而不是阻塞用户进程。
在这里插入图片描述
可以看到,非阻塞IO模型中,用户进程在第一个阶段是非阻塞,第二个阶段是阻塞状态。虽然是非阻塞,但是性能并没有得到提高。而且忙等机制导致CPU空转,CPU使用率暴增。

四、IO多路复用

1、背景

无论是阻塞IO还是非阻塞IO,用户应用在一阶段都需要调用recvfrom来获取数据,差别在于无数据时的处理方案:

  • 如果调用recvfrom时,恰好没有数据,阻塞IO会使进程阻塞,非阻塞IO使CPU空转,都不能充分发挥CPU的作用。
  • 如果调用recvfrom时,恰好有数据,则用户进程可以直接进入第二阶段,读取并处理数据

比如服务端处理客户端Socket请求时,在单线程情况下,只能依次处理每一个socket,如果正在处理的soket恰好未就绪(数据不可读或不可写),线程就会被阻寒,所有其它客户端socket都必须等待,性能自然会很差。
这就像服务员给顾客点餐,分两步:
1、顾客思考要吃什么(等待数据就绪);
2、顾客想好了,开始点餐(读取数据)。

第一步要提高效率的几种方法:
1、方案一:增加更多服务员(多线程)
2、方案二:不排队,谁想好了吃什么(数据就绪了),服务员就给谁点餐(用户应用就去读取数据)

那么问题来了:用户进程如何知道内核中数据是否就绪呢?

2、IO多路复用

文件描述符(File Descriptor):简称FD,是一个从0 开始递增的无符号整数,用来关联Linux中的一个文件。在Linux中,一切皆文件,例如常规文件、视频、硬件设备等,当然也包括网络套接字 (Socket)。
IO多路复用:是利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源。
在这里插入图片描述
监听FD的方式、通知的方式又有多种实现,常见的有:
1、select
2、poll
3、epoll
差异:
(1)select和poll只会通知用户进程有FD就绪,但不确定具体是哪个FD,需要用户进程逐个遍历FD来确认;
(2)epoll则会在通知用户进程FD就绪的同时,把已就绪的FD写入用户空间

3、select

(1)底层框架

select是Linux中最早的I/O多路复用时限方案:
在这里插入图片描述

(2)执行流程

  1. 用户空间创建fd_set rfds,默认值0,大小1024bit位
  2. 用户空间假如要监听 fd=1,2,5,把1、2、5bit位置为1
  3. 用户空间执行select(5+1, rfds, null, null, 3)
  4. 用户空间拷贝fd_set 到内核空间
  5. 内核空间遍历fd_set
  6. 内核空间没有就绪,则休眠。
  7. 内核空间等待数据就绪,被唤醒或超时。未就绪的改成0
  8. 内核空间拷贝fd_set 到用户空间,覆盖用户空间的fd_set
  9. 用户空间遍历fd_set,找到就绪的fd,读取其中数据

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

(3) select模式存在的问题

  • 需要将整个fd_set从用户空间拷贝到内核空间,select结束还要再次拷贝回用户空间
  • select无法得知具体是哪个fd就绪,需要遍历整个fd_set
  • fd_set监听的fd数量不能超过1024

4、poll

(1)底层框架

poll模式对select模式进行了简单改进,但性能提升不明显。
在这里插入图片描述

(2)执行流程

  • 创建pollfd数组,向其中添加关注的fd信息,数组大小自定义
  • 调用poll函数,将pollfd数组拷贝到内核空间,转链表存储,无上限
  • 内核遍历fd,判断是否就绪
  • 数据就绪或超时后,拷贝pollfd数组到用户空间,返回就绪fd数量n
  • 用户进程判断n是否大于0
  • 大于0则遍历pollfd数组,找到就绪的fd

(3)对比select

  • select模式中的fd_set大小固定为1024,而pollfd在内核中采用链表,理论上无上限
  • 监听FD越多,每次遍历消耗时间也越久,性能反而会下降

5、epoll

(1)底层代码

epoll模式是对select和poll的改进,它提供了三个函数:
在这里插入图片描述

(2)执行流程

1、调用epoll_create(1),创建epoll实例
在这里插入图片描述
2、调用epoll_ctl(…),添加要监听的FD,关联callback,当callback触发时,把对应的FD加入到链表list_head中。
在这里插入图片描述
在这里插入图片描述

3、epoll_wait(…, events)等待FD就绪
在这里插入图片描述

6、总结

1、select模式存在的三个问题:

  • 能监听的FD最大不超过1024
  • 每次select都需要把所有要监听的FD都拷贝到内核空间
  • 每次都要遍历所有FD来判断就绪状态
    2、poll模式的问题:
  • poll利用链表解决了select中监听FD上限的问题,但依然要遍历所有FD,如果监听较多,性能会下降
    3、epoll模式中如何解决这些问题的?
  • 基于epoll实例中的红黑树保存要监听的FD,理论上无上限,而且增删改查效率都非常高,性能不会随监听的FD数量增多而下降
  • 每个FD只需要执行一次epoll_ctl添加到红黑树,以后每次epol_wait无需传递任何参数,无需重复拷贝FD到内核空间
  • 内核会将就绪的FD直接拷贝到用户空间的指定位置,用户进程无需遍历所有FD就能知道就绪的FD是谁

7、事件通知机制

当FD有数据可读时,我们调用epoll_wait就可以得到通知。事件通知的模式有两种:

  • LevelTriggered:简称LT。当FD有数据可读时,会重复通知多次,直到数据处理完成。是Epoll的默认模式。
  • EdgeTriggered:简称ET。当FD有数据可读时,只会被通知一次。不管数据是否处理完成。

区别:
拷贝数据之前,会将链表中的fd从list_head中断开连接,然后拷贝。
假如数据没有处理完,
当采用ET时,直接删掉fd,再次调用epoll_wait,list_head中没有数据;
当采用LT,会再次添加到 list_head,再次调用epoll_wait,list_head中有数据;

在这里插入图片描述
结论:

  • ET模式避免了LT模式可能出现的惊群现象
  • ET模式最好结合非阻塞IO读取FD数据,相比LT会复杂一些

8、web服务流程

基于epoll模式的web服务的基本流程图:
在这里插入图片描述

五、信号驱动IO

信号驱动IO是与内核建立SIGIO的信号关联并设置回调,当内核有FD就绪时,会发出SIGIO信号通知用户,期间用户应用可
以执行其它业务,无需阻塞等待,
在这里插入图片描述
当有大量IO操作时,信号较多,SIGIO处理函数不能及时处理可能导致信号队列溢出。
而且内核空间与用户空间的频繁信号交互性能也较低。

六、异步IO

在这里插入图片描述
IO操作是同步还是异步,关键看数据在内核空间与用户空间的拷贝过程(数据读写的IO操作),也就是阶段二是同步还是异步:
在这里插入图片描述

七、Redis网络模型

面试题:Redis到底是单线程还是多线程?

  • 如果仅聊Redis核心业务部分(命令处理),答案是单线程;
  • 如果是聊整个Redis,那么答案就是多线程。

在Redis版本迭代过程中,在两个重要的时间点上引入了多线程支持:

  • Redis4.0:引入多线程异步处理一些耗时较长的任务,例如异步删除命令unlink
  • Redis6.0:在核心网络模型中引入多线程,进一步提高对于多核CPU的利用率

Redis为什么要选择单线程?

  • 抛开持久化不谈,Redis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,因此多线程并不会带来巨大的性能提升。
  • 多线程会导致过多的上下文切换,带来不必要的开销。
  • 引入多线程会面临线程安全问题,必然要引入线程锁这样的安全手段,实现复杂度增高,而且性能也会大打折扣。

1、单线程

Redis通过IO多路复用来提高网络性能,并且支持各种不同的多路复用实现,并且将这些实现进行封装,提供了统一的高性能事件库API库AE:
在这里插入图片描述
ae.c文件判断服务器类型,选择执行哪个ae.c文件
在这里插入图片描述
Redis单线程网络模型的整个流程:
在这里插入图片描述
在这里插入图片描述
整个流程:

在这里插入图片描述
Redi6.0版本中引入了多线程,目的是为了提高IO读写效率。因此在解析客户端命令、写响应结果时采用了多线程。核心的命令执行、IO多路复用模块依然是由主线程执行。

在这里插入图片描述

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

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

相关文章

《安富莱嵌入式周报》第301期:ThreadX老大离开微软推出PX5 RTOS第5代系统,支持回流焊的自焊接PCB板设计,单色屏实现多级灰度播放视频效果

往期周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 祝大家开工大吉 视频版: https://www.bilibili.com/video/BV1GT411o7zr 1、ThreadX老大离开微软&…

又一个开源工具搞完了,工作效率直接翻倍

🏡 博客首页:派 大 星 ⛳️ 欢迎关注 🐳 点赞 🎒 收藏 ✏️ 留言 🎢 本文由派大星原创编撰 🚧 系列专栏:《开源专栏》 🎈 本系列主要输出作者自创的开源项目 🔗 作品&…

JavaScript switch 语句

JavaScript switch 语句 switch 语句评估一个表达式,将表达式的值与case子句匹配,并执行与该情况相关联的语句。 举例说明 const expr Papayas; switch (expr) {case Oranges:console.log(Oranges are $0.59 a pound.);break;case Mangoes:case Papa…

力扣刷题|104.二叉树的最大深度、559.n 叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

文章目录LeetCode 104.二叉树的最大深度题目链接🔗思路LeetCode 111.二叉树的最小深度题目链接🔗思路LeetCode 222.完全二叉树的节点个数题目链接🔗普通二叉树求法针对完全二叉树解法LeetCode 104.二叉树的最大深度 题目链接🔗 …

WebAssembly 助力 桌面端运行web

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.WebAssembly 是基…

缺陷分析测试人员绕不开的知识点

缺陷分析也是测试工程师需要掌握的一个能力,但是很多时候大家只记得要提交缺陷、统计缺陷情况,而忽视了缺陷分析。 其实每个项目的缺陷记录都是有很大价值的。在测试阶段分析当前缺陷情况,及时发现存在的问题并调整测试策略,才能…

区间一维dp史上最细总结(绝对干货,还不会的一定要进来)

那年初夏(三) 注:此部分仅为娱乐和引入用,与本文没有太大关联,可以跳过,阅读下面的正文部分。 上篇出现于:DFS(深度优先搜索)详解(概念讲解,图片…

HashSet源码分析

一、HashSet继承关系 1、继承 public boolean equals(Object o) {if (o this)return true;// o没有实现Set接口&#xff0c;返回falseif (!(o instanceof Set))return false;// 向下转换Collection<?> c (Collection<?>) o;// 元素个数不相等&#xff0c;返回f…

4.组件通讯

默认情况下组件只能使用自己的状态&#xff0c;但当组件拆分的比较小的时候&#xff0c;就不可避免的使用到其他组件的状态&#xff0c;比如之前做的例子&#xff0c;当我们的发表评论区域与显示评论区域拆分为两个组件时&#xff0c;这两个组件之间一定要进行通讯以达成某些功…

π122M30代替Si8621AB-B-IS 低功耗,高能效、抗干扰能力好的 双通道数字隔离器解决方案

π122M30代替Si8621AB-B-IS 低功耗&#xff0c;高能效、抗干扰能力好的解决方案电路简单、稳定性更高 &#xff0c;具有出色的性能特征和可靠性&#xff0c;整体性能优于光耦和基于其他原理的数字隔离器产品。 产品传输通道间彼此独立&#xff0c;可实现多种传输方向的配置&…

Day11 C++STL入门基础知识八——stack、queue容器 基本概念-常用接口 【全面深度剖析+例题代码展示】

&#x1f483;&#x1f3fc; 本人简介&#xff1a;男 &#x1f476;&#x1f3fc; 年龄&#xff1a;18 &#x1f6a9; 今日留言&#xff1a;亮亮被迫去练科目二啦&#xff0c;定时发布的文章&#xff0c;回来统一给大家三连回复嗷~&#x1f609; 文章目录1. stack容器——栈1.…

CSDN常见问题汇总

1.怎么申请退款&#xff1f; 通过CSDN平台购买的“VIP会员、余额”&#xff0c;在刚购买后未使用的情况可支持退款&#xff1b; “付费资源、付费专栏、盲盒、魔盒、课程、C认证”等虚拟商品一经购买后&#xff0c;除了特殊原因外&#xff0c;概不支持退款&#xff1b; 特殊原…

美团8年测试经验,一文手把手教你抒写接口测试框架集成测试报告

在接口自动化测试完成后&#xff0c;通常我们都需要一个测试报告来进行结果展示&#xff0c;而测试报告的美观程度直接决定了你在同事和领导眼中的技术形象&#xff0c;本文将介绍rest-assured接口测试框架集成ExtentReports测试报告&#xff0c;让你的框架更加完美。 ExtentR…

【大唐杯备考】——5G网元功能与接口(学习笔记)

&#x1f4d6; 前言&#xff1a;本期介绍5G网元功能与接口。 目录&#x1f552; 1. 5G移动通信系统整体网络架构&#x1f558; 1.1 5G核心网架构&#x1f558; 1.2 5G接入网架构&#x1f552; 2. 5G主要网元功能&#x1f558; 2.1 UPF&#xff08;用户面功能&#xff09;&#…

使用code-server为Docker容器搭建在线开发环境

Code-server是一个基于服务端的开源VSCode。只要服务器端配置好code-server&#xff0c;就可以在任何浏览器上使用VScode访问服务器的代码进行编程。&#xff08;GitHub地址&#xff1a;https://github.com/cdr/code-server&#xff09; Docker是一个开源的Linux容器引擎。我们…

DeepLabV3+:搭建Mobilenetv2网络

目录 Mobilenetv2的介绍 Mobilenetv2的结构 Inverted Residual Block倒残差结构 Pytorch实现Inverted Residual Block 搭建Mobilenetv2 Pytorch实现Mobilenetv2主干网络 相关参考资料 Mobilenetv2的介绍 Mobilenetv2网络设计基于Mobilenetv1&#xff0c;它保持了其简单…

【进击的算法】动态规划——01背包

&#x1f37f;本文主题&#xff1a;动态规划 01背包 背包问题 C/C 算法 &#x1f388;更多算法&#xff1a;基础回溯算法 基础动态规划 &#x1f495;我的主页&#xff1a;蓝色学者的主页 文章目录一、前言二、概念✔️动态规划概念✔️01背包的概念三、问题描述与讲解&#x1…

spring 中 mybaits 的一级缓存失效

mybatis 的一级缓存 简单回顾下mybatis的一级缓存 本质上是一个基于map实现的内存级别的缓存&#xff0c;默认开启&#xff0c;生命周期是 sqlsession 级别的 为什么会失效 其实这个问题反向分析一下就会有思路了&#xff0c;一级缓存默认是sqlsession级别的&#xff0c;这个规…

2022年rust杂记

以下记录的是&#xff0c;我在学习中的一些学习笔记&#xff0c;这篇笔记是自己学习的学习大杂烩&#xff0c;主要用于记录&#xff0c;方便查找1、相关学习链接https://www.rust-lang.org/zh-CN/governance/ RUST 官网博客https://kaisery.github.io/trpl-zh-cn/&#xff08;最…

应用性能监控对DMS系统综合分析案例

背景 DMS系统是某汽车集团的经销商在线系统&#xff0c;是汽车集团的重要业务系统。本次分析重点针对DMS系统性能进行分析&#xff0c;以供安全取证、性能分析、网络质量监测以及深层网络分析。 该汽车总部已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和…