高并发编程必备知识IO多路复用技术select,poll讲解

简介: 高并发编程必备知识IO多路复用技术select,poll讲解

百万级连接和千万级连接的请求就是通过这些模型来做的

epoll:是nginx底层的机制了,运用事件驱动的方式支持千万级连接,像一些大厂使用的代理服务器就用nginx来做

一、select.poll的原理和优缺点:

上篇文章讲解了unix的五种网络编程模型

1、什么是IO多路复用:

   I/O多路复用,I/O指的是网络I/O,就是客户端请求,到服务端响应,多路指多个TCP连接(即socket或者channel),复用指复用一个或几个线程。

   简单来说:就是使用一个或者几个线程处理多个TCP连接,服务器创建线程和时间片的切换是很耗性能的。

   最大优势是减少系统开销小,不必创建过多的进程/线程,也不必维护这些进程/线程。

上面的图中,每一个actor代表一个客户端,每一条线代表10万条请求连接,Linux内核相当于服务器。

然后Linux内核有多个进程/线程去处理连接数,轮询的去处理这些的连接数。IO的多路复用就是这种的意思。

Select:是多路复用的其中一种

基本原理:

   监听文件3类描述符:writefds,readfds和exceptfds,所以在IO多路复用里面有写事件,读事件,异常事件。

在linux里面所有的文件的操作,socket连接都是一个文件描述符,在java编程里面,所有的东西都是对象,在Linux里面一切的东西都是fd,不是百分百,大部分都是这样的。

select的时候会调用一个函数,这个函数会监听用户的30万个连接,监听是否有读和写还有异常事件,调用后select函数会阻塞住,等有数据,可读,可写,或者出现异常,或者超时就会返回。select函数正常返回后,通过遍历30万个连接的请求的数组才能发现哪些句柄发生了事件(来判断哪些是可读或者可写的),来找到就绪的描述符fd,然后进行对应的IO操作。几乎在所有的平台上支持,跨平台支持性好。

这是最原始的多路复用技术。

缺点:

     1):select采用轮询的方式扫描文件描述符,全盘扫描,随着文件描述符FD数量增多而性能下降。因为30万个请求的链接会在用户空间和linux内核空间拷来拷去,是很耗性能的。

     2):每次调用 select(),需要把fd集合从用户态拷贝到内核态,并进行遍历(消息传递都是从内核到用户空间)

     3):最大的缺陷就是单个进程打开的FD有限制,默认是1024(可修改宏定义,但是效率仍然慢)   宏定义:就是java定义的常量      static  final  int MAX_FD=1024000,

所以在select模型支持太多的并发是不可能的,最多有几千个,上万的话性能就会急剧的下降。

poll:

   基本流程:

          select()和poll()系统调用的大体一样,处理多个描述符也是使用轮询的方式,根据描述符的状态进行处理,一样需要把fd集合从用户态拷贝到内核态,并进行遍历

最大的区别是:poll没有最大文件描述符限制(使用链表的方式存储fd,因为链表可以无限的去扩展,单/双向链表都可以无限扩展)

高并发编程必备知识IO多路复用技术-epoll讲解

epoll模型是nginx的模型,nginx底层就可以用这个,可以支持千万级的连接并发

基本原理:在2.6内核中提出的,对比select和poll,epoll更加灵活,没有描述符限制,用户态拷贝到内核只需要一次使用,采用事件通知的方式而不是轮询,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用callback的回调机制来激活对应的fd,然后进行io事件的处理。

优点:

   1):没fd这个限制,所支持的FD上限是操作系统的最大文件句柄数,这个最大句柄数是可以查看的,一般是65535,不用去在意它,一般是可以修改的,1G内存大概支持10万个句柄,虽然是65535,但是可以去调整它,一把把它调整成几十万,要支持单机百万连接的话,10G的话16G内存就可以解决了,所以单机解决百万的连接是不难的,只要模型用的对,Linux内核配的对就没问题。但是你要说网路IO阻塞了那是没有办法。

    2):效率提高,使用回调通知而不是轮询的方式,不会随着增加FD的数目的增加而效率下降,前面的两种模型是随着FD的数目增加而下降 。采用回调机制callback

   3):通过callback机制通知,内核和用户空间mmap同一块内存实现,不用拷贝来拷贝去,性能非常高。

当启动linux内核的时候:会涉及到下面三个函数

Linux内核核心函数:是c里面的,poll和select采用的是分别一个函数

         1)epoll_create():在系统启动的时候,在linux内核里面申请一个文件系统:B+树,查找效率非常快,返回epoll对象,也是一个fd

          2)  epoll_ctl():操作epoll对象,在这个对象里面修改添加删除对应的链接fd,在epoll对象里面有100万个链接的话,假如有1万个链接是活跃的,1万个fd会就绪放到一个集合里面去,那么这1万个fd就会有对应的回调函数

          3) epoll_wait():在ctl操作epoll对象的时候,wait就会做对应的处理了。判断并完成对应的io操作,判断这个集合callback是否为空,不为空的话,对集合中的fd都做一个io的操作。

三个函数组成函数组成epoll的高性能,这三个是互相搭配的

缺点:

  编程模型比select/poll复杂

举个例子:100百万个链接,里面有1万个链接是活跃的,在select,poll,epoll三个模型中表现是怎么样的?

在select模型里面:想要支持百万个链接的话,单个进程的话支持1024,在不修改宏定义的情况下该怎么做呢?则需要1000个进程才可以支持100万个连接,1000个进程在一台机器上创建的话给8核16G的话,这时机器会挂掉的,1000个进程每个进程处理1000个连接,cpu是轮询不过来的。性能会特别的差

poll:100万个链接的话,遍历都响应不过来了,还有空间的拷贝消耗大量的资源

epoll:不会遍历整个fd,通过上面的三个函数,第一个函数进行注册,注册好之后,100万个链接进来的时候,有1万个链接活跃,就会操作epoll对象,并绑定一个callback函数,当每一个fd就绪的时候就会触发callback函数,从而调用wait函数进行处理从而完成io的操作。省了两点:不用遍历fd,不用进行内核空间和用户空间之间的拷贝。

相关文章
|
1天前
|
消息中间件 NoSQL Java
面试官:谈谈你对IO多路复用的理解?
面试官:谈谈你对IO多路复用的理解?
面试官:谈谈你对IO多路复用的理解?
|
1月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
27 2
|
2月前
|
存储 Java Unix
(八)Java网络编程之IO模型篇-内核Select、Poll、Epoll多路复用函数源码深度历险!
select/poll、epoll这些词汇相信诸位都不陌生,因为在Redis/Nginx/Netty等一些高性能技术栈的底层原理中,大家应该都见过它们的身影,接下来重点讲解这块内容。
|
1月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
7天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
1月前
|
XML 存储 JSON
【IO面试题 六】、 除了Java自带的序列化之外,你还了解哪些序列化工具?
除了Java自带的序列化,常见的序列化工具还包括JSON(如jackson、gson、fastjson)、Protobuf、Thrift和Avro,各具特点,适用于不同的应用场景和性能需求。
|
1月前
|
缓存 Java
【IO面试题 一】、介绍一下Java中的IO流
Java中的IO流是对数据输入输出操作的抽象,分为输入流和输出流,字节流和字符流,节点流和处理流,提供了多种类支持不同数据源和操作,如文件流、数组流、管道流、字符串流、缓冲流、转换流、对象流、打印流、推回输入流和数据流等。
【IO面试题 一】、介绍一下Java中的IO流
|
2月前
|
存储 缓存 Java
Java零基础入门之IO流详解(二)
Java零基础入门之IO流详解(二)
|
2月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用