IO读写基础
应用层在进行read,write系统调用时,不是物理级别的读写,而是缓存的复制,进程缓冲区同内核缓冲区的缓存复制,底层数据交换是有由操作系统内核完成,控制内核缓冲与硬件(物理设备)之间数据交换.linux系统在系统内核只有一个内核缓冲区,用户进程都有独立的缓冲区,是进程缓冲区。外部设备的直接读写涉及操作系统的中断,底层操作会对内核缓冲区进行监控,等待缓冲区达到一定数量的时候,再进行IO设备的中断处理,集中执行物理设备的实际IO操作,这种机制提升了系统的性能,至于什么时候中断(读中断、写中断),由操作系统的内核来决定,用户程序则不需要关心.
2、同步非阻塞IO: 不断的进行IO系统调用,轮询数据状态,用户线程不会阻塞,会占用大量的CPU时间,在高并发场景下,也不采可.简称NIO.
3、 IO多路复用:
系统调用,一种是select/epoll(就绪查询),一种是IO操作,轮询查找出达到IO操作就绪的socket连,一个选择器查询线程可处理成千上万个连接,不必创建维护大量线程,减小系统开销,缺点>select/epoll系统调用是阻塞式的,属于同步IO.都需要在读写事件就绪后,由系统调用本身负责进行读写,也就是说这个读写过程是阻塞的。
4、异步IO:AIO
在内核等待数据和复制数据的两个阶段,用户线程都不是阻塞的。用户线程需要接收内核的IO操作完成的事件,或者用户线程需要注册一个IO操作完成的回调函数。异步IO有时也被称为信号驱动IO.缺点>应用程序仅需要进行事件的注册与接收,其余的工作都留给了操作系统,即需要底层内核提供支持。目前Windows系统下通过IOCP实现了真正的异步IO,在linux系统中还不太完善。
高并发连接数配置
在生产环境Linux系统中,基本上都需要解除文件句柄数的限制。文件句柄,也叫文件描述符。文件描述符(File Descriptor)是内核为了高效管理已被打开的文件所创建的索引,它是一个非负整数(通常是小整数),用于指代被打开的文件。所有的IO系统调用,包括socket的读写调用,都是通过文件描述符完成的。
ulimit -n
一个高并发的应用,并发连接数可以达到数十万百万千万级别,文件句柄数不够,当单个进程打开的文件句柄数量,超过了系统配置的上限值时,会发出“Socket/File:Can't open so many files”的错误提示。
ulimit -n 1000000
永久修改配置,可以编辑 /etc/rc.local 开机启动文件,在文件中添加如下内容,选项-S表示软性极限值,-H表示硬性极限值
ulimit -SHn 1000000
终极解除Linux系统的最大文件打开数量的限制,编辑Linux的极限配置文件/etc/security/limits.conf来解决,加入如下内容
#软性极限 soft nofile 1000000 #硬性极限 hard nofile 1000000
软性极限是系统警告(Warning)的极限值,超过这个极限值,内核会发出警告。