IO模型
- 阻塞IO
- 非阻塞IO
- IO多路复用
- 异步IO
常见多路复用IO实现:
- select: 基于数组实现,时间复杂度O(n),发生事件时,需要把所有的文件描述符从用户空间复制到内核空间,遍历文件描述符数组
- poll: 基于链表实现,总时间复杂度(O(n)),发生事件时,遍历链表。链表在大量删除插入场景时间复杂度为O(1),查找时O(n),性能高于数组,poll记录大量fd时的性能高于select
- epoll: 基于红黑树实现,时间复杂度(O(1),属于异步事件驱动方式,epoll是一种 I/O 事件通知机制,可以用于实现异步I/O,也可以用于实现非阻塞多路复用I/O
Nginx采用epoll IO多路复用处理多个连接:epoll处理大量连接请求和并发请求非常高效,能支持超10W连接的高并发访问;而异步IO模型在处理大量连接时,需要为每个连接创建独立的上下文,会导致上下文切换消耗服务器资源、降低性能。epoll支持水平触发和边缘触发,而异步IO只支持边缘触发
在Linux系统中,epoll和异步I/O都是非常强大的I/O机制,都能够提供高性能和可伸缩性。 epoll和异步I/O虽然有许多相同之处,但它们的应用场景和实现方式是不同的。epoll主要用于I/O事件的多路复用,可以同时处理大量客户端连接,避免了传统多线程网络编程模型的缺点。而异步 I/O 主要用于处理少量高负载的网络请求,可以避免线程切换和上下文切换等开销。 因此,从实际应用出发,要根据具体场景需求选择合适的I/O模型。对于高并发连接数的场景,通常使用epoll机制,而对于少量高负载请求的场景,通常使用异步I/O机制。
静态磁盘IO性能优化出发点
- 应用程序
- 文件系统
- 物理磁盘
应用程序
1、根据应用场景选择IO模型,比如采用epoll多路复用IO
2、使用队列机制,如果是大量小IO,一次性处理多个小IO落盘,增加吞吐量
3、使用零拷贝
文件系统
1、调整文件系统缓存参数
2、关闭atime等,降低IOPS
3、使用高效的文件系统,比如ext4、xfs,这种文件系统会先将数据写在日志中,然后才写入实际文件,可以提供写入性能和数据可靠性
ext4、xfs等都提供了区段、预读、预分配、延迟分配等机制
物理磁盘
1、使用Raid技术 2、使用更高转速的HDD或则使用SSD等
HDD最外圈的吞吐量比较高,内圈比较低 使用SSD时最关注的问题是寿命,ssd具有读写次数限制,最好的颗粒是SLC(single-level cell 每个单元只存储一个比特的数据),其次是MLC(multi-level cell可以存储2/4/8多个比特),MLC成本与优势,但是擦写次数少
使用SSD时尽量预留一些空间,某个存储单元坏掉时会触发坏块管理以保证数据可靠性,自动使用备用存储单元顶替,如果坏掉了大量的存储单元会影响性能和可靠性,SSD还具备均衡存储单元的能力
最后: 最好的IO是没有IO