I/0模型

同步I/O、异步I/O、阻塞I/0、非阻塞I/O、五种I/O模型、高性能网络模型 面试最常问问题之二:五种I/O模型及区别 ​ 阅读详情
在高性能服务器中,一般采用非阻塞网络IO,单进程事件驱动的架构。这种架构的核心是事件驱动机制。目前Linux常用select,poll和epoll系统调用来完成事件驱动。select和poll是传统的unix事件驱动机制,但它们有很大的缺点:在大量的并发连接中,如果冷连接较多,select和poll的性能会因为并发数的线性上升而成平方速度的下降,这是因为调用者在每次select和poll返回时都要检测每个连接是否有事件发生,当连接数很大时,系统开销会非常大。另外select和poll每次返回时都要从内核向用户空间复制大量的数据,这样的开销也很大。所以,select和poll并不是处理网络IO的最好方案。

于是从Linux2.5开始,出现了一个新的系统调用epoll,它不仅可以完成select/epoll的功能,而且性能更高,功能更强。epoll的优点:1,每次只返回有事件发生的文件描述符信息,这样调用者不用遍历整个文件描述符队列,而且系统不用从内核向用户空间复制大量无用的数据;2,epoll可以设置不同的事件触发方式:边缘触发和电平触发,为用户使用epoll提供了灵活性。epoll也有缺点:1,在冷连接很少的情况下,性能与select和poll相比并没有什么优势;2,目前的实现还不完整,不支持EPOLLHUP事件,在边缘触发情况下,无法处理客户端网络连接主动断开;3,使用比较麻烦,如何边缘触发方式必须要小心处理,否则程序可能无法完成功能,在采用电平触发方式时,调用者要避免epoll_wait发生空转。

一, 磁盘IO

Linux磁盘IO有同步模式和异步模式。同步模式就是常见read/write系统调用,这两个系统调用都被认为是低速系统调用,执行时可能会使进程阻塞,在单进程的服务器中,这会使系统性能下降。所以Linux提供了异步磁盘IO。目前Linux中主要有两种异步IO解决方案:1,由glibc 实现的Posix AIO(aio_read,aio_write,….),采用线程或实时信号来通知IO完成,用户也可以采用轮询方式来检测IO是否完成;2,由kernel实现的Linux AIO(io_setup, io_getevents,…),事件的通知机制(io_getevents)是采用类似select的语义。它们的共同点都是采用了多线程的方式来处理阻塞的磁盘IO,使其看起来像异步的。这两种方式主要区别是:1,Posix AIO是在用户态下实现的而Linux AIO是在内核中实现的;2,事件的通知机制不同,前面已说明。Posix AIO和Linux AIO性能的比较还没有做过。Linux的异步磁盘IO机制的缺点是:无论Posix AIO还是Linux AIO在处理新的IO请求时都会做创建线程的操作,这样比较的费时。

Linux磁盘IO还可以用内存映射的方式,优点是:1,可以避免在用户空间和内核空间之间复制数据;2,如果把小文件合成大文件,对大文件进行内存映射,可以减少open系统调用的次数。但内存映射的缺点也很明显:1,由于3G以上的大文件无法映射进内存,使用有局限性;2,如果所访问的页面不在内存中,需要进行换页操作,进程会阻塞。虽然合理地使用mincore可以避免进程阻塞,但编程实现难度较高。

如果是从磁盘向网络传送数据的话还可以使用sendfile,sendfile可以在内核空间中直接从磁盘向网络传送数据,避免了内存复制。

二, 同时处理网络IO和磁盘IO

数据服务器要同时处理大量的并发网络连接,而且处理这些网络连接需要进行大量的磁盘IO,如读取文件。在这样情况下,我们提出了两种模型:

1,分离网络IO和磁盘IO。这种模型是指用一个进程(RelayServer)来处理大量并发的网络连接,另一个进程(DataServer)处理磁盘IO,两个进程通过一个TCP连接交换信息,当客户(Client)请求到达,RelayServer将其转发给DataServer,DataServer去磁盘上读数据,读好数据后,将数据回传给RelayServer,RelayServer再转发给Client。

2,不分离网络IO和磁盘IO。这种模型是指只用一个进程(DataServer)来同时处理磁盘IO和网络IO。

下面讨论这两种模型的实现方案:

无论是采用哪种模型,都涉及到对大量磁盘IO的处理。根据前面对Linux磁盘IO的讨论,我们试验了以下几种磁盘IO的实现方式:

1,Posix AIO,实时信号通知。由于磁盘IO通常会在较短的时间内完成,进程频繁地被信号中断,系统调用频繁自动重启动,造成整个性能的下降。另外,因为无法向信号处理函数传参数,信号处理函数很难实现较为复杂的功能。

2,Posix AIO,线程通知。每完成一个IO请求,系统就会创建线程,开销较大。

3,Posix AIO,轮询。很难跟DataServer的epoll逻辑结合,只有不断轮询,性能较低。
Linux AIO未作测试,性能未知。内存映射无法处理很大的文件,也未采用。

从上面看来,Linux提供的异步IO机制无法满足我们的需求,于是我们自己在用户层实现了异步IO。我们的异步IO主要框架是采用预先创建线程,形成线程池。处理流程:用户发IO请求,线程池中的工作线程被唤醒,工作线程采用一般的read/write系统调用处理IO(为了保证磁盘IO能够完成,我们用的是readn和writen),工作线程做完IO后通过一个管道向epoll通知,并把用户IO的请求挂到完成队列上,epoll收到通知后,从完成队列中取下,再做相应的操作。根据我们的性能比较,这种方式比前面几种实现性能都要高,而且实现起来比较容易。所以我们对磁盘IO的处理主要采用这种方式,但针对不分离模型和分离模型的不同细节,又有所变化。

针对不分离模型,我们系统使用epoll管理socket描述符和一个管道描述符(磁盘IO用管道来通知epoll)。epoll只处理socket的读事件,负责完整收到Client一个请求,然后把请求交给磁盘IO。磁盘IO使用线程池,跟前面的区别在于,工作线程在读数据时使用sendfile,直接将磁盘数据发给对应的网络套接字,如果sendfile返回EAGAIN错误或者没发完数据,就更新请求,然后把请求重新放回队列。

分离的模型中DataServer也是用epoll管理socket描述符和与磁盘IO通信的管道描述符。epoll需要处理socket的读事件和写事件,负责从RelayServer收请求和向RelayServer发送数据。磁盘IO与前面的模型一致。

不分离模型和分离模型的对比结论:

1,不分离模型和分离模型在面对200左右并发连接数时性能上基本一致。测试表明:当请求读文件的大小较大时(超过256KB),无论OS对文件的缓存命中率大小,两种模型所能达到的网络吞吐量都差不多(20-30MB/S)。并且网络吞吐量随着请求文件大小的增大而增大,在这种情况下,磁盘IO严重滞后于网络IO和CPU的速度,所以网络吞吐量由磁盘IO的速度所决定。因为当读文件较大时,根据磁盘IO特点,磁盘吞吐量会较高,所以请求文件越大,网络吞吐量越好。当请求文件的大小较小时(如16KB和64KB),如果OS文件缓存的命中率较高,磁盘IO在整个系统中几乎没有影响,网络的吞吐量基本可以达到网卡的物理上限。但是,当OS文件缓存命中率很小时,由于磁盘IO很难高效地处理对小块数据的读,整个系统性能受制于磁盘IO,并且网络吞吐量和磁盘吞吐量都很低(4MB/S)。总得来看,无论使用哪种模型,磁盘IO都是瓶颈。

2,不分离模型的优缺点。优点:1,不分离模型的实现较为容易,可以使用sendfile等高效的系统调用。2,由于对每个并发连接不需要分配大量的内存缓冲区来缓存从磁盘读到的数据,对并发连接数的支持可以不受内存大小的限制,具有较好的伸缩性。缺点:可扩展性不足,比如对于客户端要求写文件就很难处理,而且如果加上复杂的协议分析,性能可能会大幅度下降。

3,分离模型的优缺点。优点:扩展性好,可以专门对磁盘IO进行优化,而不必考虑其对同时处理大量并发网络连接的影响;针对网络IO也可以添加复杂协议的分析,不必考虑对同时处理磁盘IO的影响。缺点:实现较为复杂,实现方案直接影响系统性能;用户接收数据的速率不平滑,有时会较长时间没有数据到达,而有时会瞬间到达很多数据,这样对于流媒体的应用,用户体验会很差。

三, 结论

针对我们的需求,决定使用分离模型。因为分离模型的扩展性很好,并且通过优化预计可以达到较高的效率。
中国能源消费的LMDI I分解分析 中国能源消费的LMDI I分解分析,林骋,李娜,中国是能源消费大国,随着经济的增长,能源消费一直处于不断上升趋势,高耗能不但带来能源安全的问题还有环境污染的代价,故本文 立即下载

相关推荐

CXL协议-第三章 CXL事务层

CXL.io为I/O设备提供了一个非一致的负载/存储接口。图3-1显示了Flex总线分层层次结构中的位置。事务类型、事务分组格式、基于信用的流量控制、虚拟通道管理和事务排序规则遵循PCIe*定义,详情请参考PCIe基础规范的“事务层规范”章节。本章重点介绍了用于CXL.io的著名的PCIe操作模式或特性。

qq_41305217的博客 2769

(转)I/0模型

在高性能服务器中,一般采用非阻塞网络IO,单进程事件驱动的架构。这种架构的核心是事件驱动机制。目前Linux常用select,poll和epoll系统调用来完成事件驱动。select和poll是传统的unix事件驱动机制,但它们有很大的缺点:在大量的并发连接中,如果冷连接较多,select和poll的性能会因为并发数的线性上升而成平方速度的下降,这是因为调用者在每次select和poll返回时都要...

weixin_33786077的博客 110

AI智能体评估基准AgentBench:从原理到实战的完整指南

在人工智能领域,智能体(AI Agent)的评估是衡量其实际应用能力的关键环节。评估基准通过设计标准化的测试任务,系统性地检验智能体的推理、规划和工具使用等核心能力。其技术价值在于为模型迭代和产品选型提供了客观、可复现的量化依据,能有效推动技术从演示走向工程落地。典型的应用场景包括模型能力评测、智能体框架对比以及具体应用(如自动化运维、智能客服)的性能验证。本文聚焦于清华团队推出的AgentBench,它作为一个多维度的综合评估套件,涵盖了从操作系统、数据库操作到网页浏览、数字卡牌游戏等八个贴近真实世界的任

weixin_27207591的博客 599

I/0模型(select模型)

select 模型 1)引入 为什么要引入select模型呢  同步阻塞问题我们可以利用多线程 或者把socket改成非阻塞 当我们要接受数据的时候我们要来回查看接受缓冲区有没有数据这样我们就要来回切换用户和内核浪费时间降低效率 所以我们让一个把所有的socket的有无数据都看了呢 这样我没就要引入select select 模型是Winsock中最常见的I/0模型,核心是利用selec...

qq_37163944的博客 4621

# 解决 win11 连接共享打印机,报错 0x00000709 问题

# 解决 win11 连接共享打印机,报错 0x00000709 问题

段子手168的博客 9万+

SAP RAP学习系列合集介绍

《SAP RAP学习系列合集:从入门到部署的完整指南》摘要: 本文介绍了作者创建的SAP RAP学习系列合集,涵盖RAP开发从基础概念到实战部署的全流程。系列目前包含17篇文章,系统讲解了RAP核心开发技术:从数据建模、UI构建到行为定义(包括并发控制、草稿功能、授权验证等),最后详细演示了应用部署到Fiori Launchpad的两种方案(OP版和ES版)。

DeveloperMrMeng的博客 1492

Netty从0到1系列之I/O模型

摘要 本文从操作系统设计角度,深入解析了内核态与用户态的核心概念及其交互机制。文章通过公司管理层的类比,形象阐述了两种状态的权限差异:用户态如普通员工受限操作,内核态则拥有最高权限。系统调用是用户程序请求内核服务的唯一通道,文中以文件写入为例展示了完整的调用流程。 第二部分聚焦缓冲区技术,分析了其在解决CPU与I/O设备速度差异中的关键作用。详细对比了应用程序缓冲区(用户空间)与内核缓冲区(内核空间)的不同职责,并通过文件读写场景演示了数据在多层缓冲区间的流动过程。

编程技术圈 1584

8、音频运行时系统的架构设计

本文深入探讨了音频运行时系统的分层设计及其优势,包括逻辑层和物理层的功能划分。通过分层设计,开发者可以更轻松地管理和优化音频资源,确保其在不同平台上的高效运行。文章还介绍了平台适配与优化、错误处理与调试以及未来发展方向等内容,为开发者提供了宝贵的参考和指导。

juice的博客 463

小红书抗住高并发的背后:Redis 7.0 性能必杀技之 I/O 多线程模型

大家好,我是码哥,《Redis 高手心法》作者。本书获得前阿里 P9 级资深技术专家李运华的推荐。进入正文......在《Redis 为什么这么快》这篇文章中,我们已经知道 Redis 使用全局 dict 字典表 + 内存数据库 + 丰富高效的数据结构 + 单线程模型 + I/O 多路复用事件驱动框架使得 Redis 快到飞起。Redis 的网络 I/O 以及键值对指令读写是由单个线程来执行的,避...

码哥字节 813

【异常】OpenClaw 连接异常This site can‘t be reached 127.0.0.1 refused to connect Try: Checking the proxy

在访问OpenClaw相关服务时,浏览器提示如下异常信息,无法正常加载页面:Try:补充说明:该报错仅出现于本地访问场景(127.0.0.1为本地回环地址),涉及OpenClaw核心服务的本地连接交互,无外部网络及敏感信息泄露风险。

奶爸的编程之路,也就一周冷个三天 1484

把大表拆成更好用的“小仓库”:SAP HANA 表分区设计、分区裁剪与内存代价全解析

摘要:本文深入解析SAP HANA分区技术的核心价值与实现策略。作为内存数据库的"手术刀",分区通过将逻辑表横向切分为独立物理容器,显著提升并行计算能力与查询效率。重点探讨了三种分区类型(Range、Hash、Round-robin)的适用场景,以及分区裁剪的优化原理与前提条件。特别指出分区设计需要平衡查询模式与数据分布,并揭示了分区对内存占用的双向影响机制:既可能因字典复制增加消耗,也可能因数据纯度提升压缩率。通过电商订单表等实际案例,展示了合理分区如何将分钟级报表优化至秒级响应。文章

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1650

Redis 6.0 多线程网络 I/O 模型

Redis 6.0 引入多线程架构,主要优化网络I/O处理,同时保持核心命令执行的单线程特性。通过将耗时的网络数据读写操作分配给多个I/O线程并行执行,充分利用多核CPU能力,显著提升吞吐量。关键设计在于:1)I/O线程并行处理网络数据拷贝;2)主线程仍串行执行内存操作,避免锁竞争;3)严格的任务同步机制确保执行顺序一致性。该架构在保持Redis高性能和简单性的同时,有效突破了单核CPU处理网络I/O的瓶颈。配置时需注意多线程功能默认关闭,仅在高并发场景下按需开启。

love___me的博客 494

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

关于I/0模型的简略概述[英文]

原网址:http://blogs.msdn.com/b/csliu/archive/2009/08/18/winsock-i-o-model-part-ii-implementation.aspx In the previous post[6], I summarized several scalable network I/O models in theory. In this a

Sunshine 807

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Redis 6.0 多线程网络I/O模型详解:从单线程瓶颈到高效演进

Redis 6.0引入多线程网络I/O模型,突破单线程瓶颈。本文通过高速公路收费站和餐厅运营的类比,解析Redis单线程模型的优势与局限,以及6.0版本如何通过"网络I/O多线程+核心命令单线程"的混合架构实现性能飞跃。文章详细拆解了多线程I/O的工作流程、线程职责划分,并给出关键配置参数说明,帮助开发者理解Redis如何平衡性能与简洁性,在高并发场景下充分利用多核CPU资源。

m0_65159391的博客 709

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

JAVA I/0模型

JAVA I/0模型

weixin_42548604的博客 237

Socket回顾与I/0模型

Socket,套接字就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。...

凉茶铺的博客 299

SOKET模型重叠I/0

四。     实现重叠模型的步骤 作了这么多的准备工作,费了这么多的笔墨,我们终于可以开始着手编码了。其实慢慢的你就会明白,要想透析重叠结构的内部原理也许是要费点功夫,但是只是学会如何来使用它,却是真的不难,唯一需要理清思路的地方就是和大量的客户端交互的情况下,我们得到事件通知

goodadult2012的专栏 1168

Redis 7.0 I/O多线程模型:小红书高并发性能的幕后推手

小红书在应对高并发场景时,采用了Redis 7.0版本中的I/O多线程模型以提升性能。此模型不同于传统的Multi-Reactors/Master-Workers架构,在I/O多线程模型中,线程专注于通过socket读取客户端请求命令、解析命令,并将执行结果回写到socket,而命令的实际执行则交由其他组件负责。通过引入Redis 7.0的I/O多线程模型,小红书成功应对了高并发场景下的性能挑战。

Xs_20240309的博客 1281

windows套接字I/0模型-WSAAsyncSelect 模型

其中,hwnd 是窗口句柄,WM_SOCKET 是自定义的消息类型,FD_READ 表示套接字上有可读数据,FD_WRITE 表示套接字可写,FD_CLOSE 表示套接字已关闭,FD_CONNECT 表示套接字连接已建立。WSAAsyncSelect 函数的第一个参数是套接字的句柄,第二个参数是窗口句柄,第三个参数是一个整数,表示需要监听的网络事件,第四个参数是错误代码。(2)回调函数的第一个参数是窗口句柄,第二个参数是消息类型,第三个参数是套接字句柄,第四个参数是网络事件类型,第五个参数是错误代码。

ai agent 1062

Redis 7.0 新特性助力:小红书利用 I/O 多线程模型应对高并发挑战

Redis 7.0的I/O多线程模型为小红书应对高并发挑战提供了有力的支持。通过充分利用Redis的高性能特性和不断优化的技术架构,小红书能够在保证数据一致性和可靠性的同时,提供极致的用户体验。未来,随着大数据和人工智能技术的广泛应用,Redis和其他数据库技术将不断发展和演变,为互联网企业应对高并发挑战提供更多更好的解决方案。

2408_88802129的博客 756

【Java 多线程编程 | 从0到1】线程I/O模型

线程I/O模型 2.1 线程与阻塞 I/O 2.1.1 单线程阻塞 I/O 模型 2.1.2 多线程阻塞 1/0 模型 2.2 线程与非阻塞 1/0 模型 2.3 Java 多线程非阻塞I/O 模型 2.4 多线程带来了什么

鱼干的博客 1516

Socket回顾与I/0模型(一)

Socket回顾与I/0模型 Socket网络编程回顾 Socket概述:Socket,套接字就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的协议端口。 Socket整体流程: Socket编程主

qq_40977467的博客 322
上一篇: select,poll和epoll的区别
下一篇: [精华] 讨论 Setsockopt选项
hardworkba
博客等级 码龄18年 11粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值