redis 从0到1完整学习 (十八):阻塞/非阻塞 IO

文章目录

  • 1. 引言
  • 2. redis 源码下载
  • 3. I/O 模型
    • 3.1 阻塞 I/O
    • 3.2 非阻塞 I/O
  • 4. 参考


1. 引言

前情提要:
《redis 从0到1完整学习 (一):安装&初识 redis》
《redis 从0到1完整学习 (二):redis 常用命令》
《redis 从0到1完整学习 (三):redis 数据结构》
《redis 从0到1完整学习 (四):字符串 SDS 数据结构》
《redis 从0到1完整学习 (五):集合 IntSet 数据结构》
《redis 从0到1完整学习 (六):Hash 表数据结构》
《redis 从0到1完整学习 (七):ZipList 数据结构》
《redis 从0到1完整学习 (八):QuickList 数据结构》
《redis 从0到1完整学习 (九):SkipList 数据结构》
《redis 从0到1完整学习 (十):RedisObject 数据结构》
《redis 从0到1完整学习 (十一):RedisObject 之 String 类型》
《redis 从0到1完整学习 (十二):RedisObject 之 List 类型》
《redis 从0到1完整学习 (十三):RedisObject 之 Set 类型》
《redis 从0到1完整学习 (十四):RedisObject 之 ZSet 类型》
《redis 从0到1完整学习 (十五):RedisObject 之 Hash 类型》
《redis 从0到1完整学习 (十六):内存回收之 key 过期处理策略》
《redis 从0到1完整学习 (十七):内存回收之内存淘汰策略》

之前我们介绍了 redis 的内存回收相关处理策略。Redis 巧妙地结合了非阻塞 I/O 技术和多路复用机制来实现高并发、低延迟的服务能力,这也是它作为高性能缓存数据库的重要原因之一。

为了连续性,本文主要介绍下 Linux 的阻塞和非阻塞 IO 概念,方便后续理解。

2. redis 源码下载

Redis 源码可以点击这里下载,方便查看其中定义的一些数据结构。
在这里插入图片描述

3. I/O 模型

在操作系统和计算机网络中,通常提到的五种I/O(Input/Output)模型是:

I/O 模型描述
阻塞I/O (Blocking I/O)进程发起I/O操作后,会一直等待(阻塞)直到该操作完成。期间不能执行其他任务。
非阻塞I/O (Non-Blocking I/O)进程发起请求后立即返回,不关心数据是否准备好。进程需不断轮询检查I/O状态。
I/O复用 (I/O Multiplexing)单个线程可以同时监听多个文件描述符,当任意一个准备就绪时进行实际I/O操作,如selectpollepoll
信号驱动I/O (Signal-Driven I/O)应用程序注册信号处理器,内核在数据准备就绪时发送信号通知进程,进程在信号处理函数中完成I/O操作。
异步I/O (Asynchronous I/O, AIO)进程发起I/O请求后立刻返回,内核在后台完成操作并在所有操作完成后通过回调函数通知应用程序。进程中无需关心I/O何时完成也不需要轮询。

3.1 阻塞 I/O

在这里插入图片描述
阻塞I/O(Blocking I/O)的详细过程描述如下:

  1. 进程发起调用:

    • 当用户进程需要从网络套接字或磁盘等设备读取数据时,它会调用一个系统级别的阻塞I/O函数,调用 revcfrom函数来系统调用。
  2. 内核等待数据准备:

    • 当所请求的数据尚未准备好(如网络数据包还未到达,或磁盘上的数据还未加载到内存缓冲区),那么该进程会被操作系统挂起(阻塞),即暂时停止执行。
  3. 数据准备阶段:

    • 内核在此期间负责等待数据准备完成。对于网络 I/O 来说,这可能涉及到接收完整的数据包、处理网络协议栈、填充内核缓冲区等步骤。
  4. 数据复制:

    • 当所需的数据完全准备好并存在于内核缓冲区中后,内核开始将数据从内核空间复制到用户空间,即将数据从内核的缓冲区复制到应用程序提供的缓冲区。
  5. 唤醒进程:

    • 数据复制完成后,内核解除对该进程的阻塞状态,并返回到用户态。此时,调用 I/O 操作的函数会返回,通常表示成功读取了数据以及读取了多少字节。
  6. 进程继续执行:

    • 进程现在可以访问已读取的数据,并进行后续处理。与此同时,如果还有更多的 I/O 操作需要执行,则该进程将继续发出新的 I/O 请求,整个过程可能会再次进入阻塞状态直到数据准备好。

总结来说,在阻塞 I/O 模型下,进程在等待 I/O 操作完成期间不能执行其他任务,这种模式简单直观,但当 I/O 操作耗时较长时,会导致进程效率低下。在高并发和实时性要求较高的场景下,不建议使用阻塞 I/O 模型。

3.2 非阻塞 I/O

在这里插入图片描述
非阻塞I/O(Non-Blocking I/O)的详细过程描述如下:

  1. 进程发起调用:

    • 当用户进程尝试从一个非阻塞套接字读取数据时,它会调用相应的非阻塞 I/O 函数,调用 revcfrom 函数来系统调用。
  2. 内核处理请求:

    • 如果所请求的数据还未准备好(即没有数据可读),而非阻塞模式下,内核不会等待数据准备完成,而是立即返回一个错误代码,例如在Linux中通常会是EAGAINEWOULDBLOCK,表示当前无数据可读。
  3. 轮询与事件循环:

    • 进程收到错误码后,知道此时无法读取到数据,但它并不会被挂起或阻塞。相反,它会通过循环不断地重新尝试读取操作,或者切换执行其他任务,然后在一段时间后再次检查该文件描述符是否可以进行读取。
  4. 数据准备阶段:

    • 同时,内核在后台继续处理网络数据包接收、磁盘读取等操作,一旦数据准备好,内核将更新其内部状态。
  5. 读取数据:

    • 当进程再次尝试读取时,如果数据已经就绪,那么这次调用将会成功,并且数据会被复制到用户空间缓冲区中。

总结来说,在非阻塞 I/O 模型下,进程不会因 I/O 操作而阻塞,而是不断轮询以检测 I/O 事件的状态,当事件发生时才执行实际的 I/O 操作。这种模式能够提高并发处理能力,但也增加了编程复杂度,因为它要求应用开发者自行处理事件循环和轮询逻辑。

4. 参考

《redis 从0到1完整学习 (一):安装&初识 redis》
《redis 从0到1完整学习 (二):redis 常用命令》
《redis 从0到1完整学习 (三):redis 数据结构》
《redis 从0到1完整学习 (四):字符串 SDS 数据结构》
《redis 从0到1完整学习 (五):集合 IntSet 数据结构》
《redis 从0到1完整学习 (六):Hash 表数据结构》
《redis 从0到1完整学习 (七):ZipList 数据结构》
《redis 从0到1完整学习 (八):QuickList 数据结构》
《redis 从0到1完整学习 (九):SkipList 数据结构》
《redis 从0到1完整学习 (十):RedisObject 数据结构》
《redis 从0到1完整学习 (十一):RedisObject 之 String 类型》
《redis 从0到1完整学习 (十二):RedisObject 之 List 类型》
《redis 从0到1完整学习 (十三):RedisObject 之 Set 类型》
《redis 从0到1完整学习 (十四):RedisObject 之 ZSet 类型》
《redis 从0到1完整学习 (十五):RedisObject 之 Hash 类型》
《redis 从0到1完整学习 (十六):内存回收之 key 过期处理策略》
《redis 从0到1完整学习 (十七):内存回收之内存淘汰策略》

欢迎关注本人,我是喜欢搞事的程序猿; 一起进步,一起学习;

也欢迎关注我的wx公众号:一个比特定乾坤

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

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

相关文章

jetlinks 规则编排中的函数节点使用 js 脚本格式化输出当前系统时间的坑

网上搜到的都是类似如下这种: // 获取当前时间 var date new Date();// 格式化输出当前时间 var year date.getFullYear(); var month date.getMonth(); var day date.getDate(); var hour date.getHours(); var minute date.getMinutes(); var second date.…

捷为科技亮相2024深圳PMO年度论坛 探讨项目管理赋能企业数字化转型

1月13日,一场聚焦项目管理创新与数字化转型的盛会——2024年深圳PMO年度论坛在深圳新一代产业园隆重举行。本次论坛以“项目管理赋能企业数字化转型”为主题,汇聚了众多行业专家、学者和企业代表,共同探讨如何通过项目管理推动企业数字化转型…

电商概念之商品模型

1、基本定义 广义定义:商品是为了出售而生产的劳动成果,人类社会生产力发展到一定历史阶段的产物,用于交换的劳动产品。 电商商品基本概念: 商品类目商品属性销售属性商品编码&商品规格编码SKU和SPU… 2、商品类目 电商平…

【动态规划】20子数组系列_环形子数组的最大和_C++(medium)

题目链接:leetcode环形子数组的最大和 目录 题目解析: 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析: 题目让我们求返回 nums 的非空 子数组 的最大可能和 这道题如果是按照-这道题-是不对…

基于信号完整性的一些PCB设计建议

最小化单根信号线质量的一些PCB设计建议 1. 使用受控阻抗线; 2. 理想情况下,所有信号都应该使用完整的电源或地平面作为其返回路径,关键信号则使用地平面作为返回路径; 3. 信号的返回参考面发生变化时,在尽可能接近…

JMeter笔记(三)

个人学习笔记(整理不易,有帮助点个赞) 笔记目录:学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 目录 一:参数化方法 1)用户定义的变量 2)函数助手 3)…

MYSQL的事务隔离

本章概览 mysql是一个支持多引擎的系统,并不是所有引擎都支持事务,本篇以innodb为例解析mysql在事务支持的实现。提到事务一定会想到ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性),今天…

旧路由重置新路由设置新路由设置教程|适用于PPPoE拨号

前言 前几天朋友说路由器想要重置,但不知道怎么弄。所以就想着只帮忙重置路由器的话,只能帮到一个人。但把整个过程写成图文,就可以帮助更多人。 本文章适合电脑小白,请注意每一步哦! 注意事项 开始之前需要确认光猫…

pod控制器的作用

pod控制器的作用 1、动态pv和pvc deployment是控制器 pod空气器:工作负载,workload用于管理pod的中间层,确保podi资源符合预期的状态 预期状态 1、副本数 2、容器重启策略 3、镜像拉取策略 pod、出现故障时重启等等 pod的控制器类型 1、replic…

删除运行框中的文件打开历史记录

当我们使用everything、百度、迅雷等软件,在列表中右键选中打开文件夹时。 当使用 winR 快捷键等方式打开运行时,输入盘符会出现之前打开过的文件夹, 一方面展示的特别多会比较混乱,另一方面 记得在之前的window版本中&#xff08…

WIFI7时代正式来临

Wi-Fi联盟在2024年1月8日宣布推出了Wi-Fi CERTIFIED 7认证,标志着WIFI7时代的正式来临!这一认证引入了一系列强大的新功能,旨在提升Wi-Fi性能并改善各种连接环境。WIFI7支持多用户AR/VR/XR、沉浸式3D培训、电子游戏、混合工作、工业物联网和汽…

架构师之超时未支付的订单进行取消操作的几种解决方案

今天给大家上一盘硬菜,并且是支付中非常重要的一个技术解决方案,有这块业务的同学注意自己尝试一把哈! 一、需求如下: 生成订单30分钟未支付,自动取消 生成订单60秒后,给用户发短信 对上述的需求,我们给…

【算法与数据结构】63、LeetCode不同路径 II

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:参考【算法与数据结构】62、LeetCode不同路径的题目,可以发现本题仅仅是多了障碍物。我们还…

springboot下载图片的简单处理方式

参考地址 springboot:各种下载文件的方式_springboot下载文件-CSDN博客 开箱即用实战 GetMapping("/t1")public void down1(HttpServletResponse response) throws Exception {response.reset();response.setContentType("application/octet-strea…

STM32F103标准外设库——认识STM32(一)

个人名片: 🦁作者简介:一名喜欢分享和记录学习的在校大学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:V…

MySQL存储引擎索引事务

一.存储引擎 1.创建的存储引擎 MyISAM 不支持事务、也不支持外键,索引采用非聚集索引,其优势是访问的速度快,对事务完整性没有要求,以 SELECT 、 INSERT 为主的应用基本上都可以使用这个存储引擎来创建表。 MyISAM 的表在磁盘上…

从零学Java 线程的状态

Java 线程的状态 文章目录 Java 线程的状态线程的基础状态1 常见方法1.1 休眠1.2 放弃1.3 加入1.4 优先级1.5 线程打断1.6 守护线程1.7 线程的状态 - 等待 2 线程安全问题2.1 线程同步: 同步代码块2.2 线程同步: 同步方法2.3 同步规则2.4 线程的状态 - 阻塞2.5 特殊现象: 死锁 …

新版网易滑块

突然发现脸皮厚根本没用,大冬天的,风吹过来还是会冷。 大哥们多整件衣裳,好冷!!!! 网易更新了,这俩 dt跟f值。 dt为 这里返回的,忽略掉他。 data参数中的d值&#xff…

未来气膜体育馆的发展趋势是什么?

未来气膜体育馆的发展趋势是多方面的,以下是其中几个方面的趋势。 起初,随着人们对体育运动的需求不断增加,气膜体育馆的建设和使用将成为一种趋势。气膜体育馆具有灵活性和可移动性的特点,可以快速搭建和拆除,能够适…

低代码平台,新型应用程序开发神器

目前低代码平台如火如荼。这一新兴技术为企业提供了一种高效、灵活、快速开发应用程序的方法,并在短时间内取得了巨大成功。然而,我们不得不面对低代码平台的优劣以及其所带来的挑战。本文将深入探讨低代码平台在不同情况下的优劣势,并与您分…