高性能网络设计
大约 2 分钟
高性能网络设计
reactor
io_uring
版本问题
io_uring 是 aio,Linux也有aio呢?我之前学boost::asio时还说linux网络还没aio呢……现在终于有了!以前就Window有AIO (IOCP)
这个是 Linux Kernel 5.1 版本加入的,并在 5.10 版本后才得到较好支持,libaio 即将埋入黄土。参考:https://zhuanlan.zhihu.com/p/62682475
发行版本 发行时间 内核版本 发布时间 18.04 2018.04.26 4.15 2018.01 18.10 2018.10.18 4.18 2018.08 19.04 2019.04.18 5.0 2019.03 19.10 2019.10.17 5.2 2019.07 20.04 2020.04.23 5.4 2019.11 22.04.2 LTS 6.2 版本对照如上
以前的Linux操作是:
- 网络用epoll
- 磁盘操作用多线程
- 大文件和数据库用libaio (io_uring 可能代替之)
不过io_uring现在有系统调用了,但库现在还未调研,不知道支持好不好
同步io、异步、aio
- 同步
- read:读->等
- write
- 异步
- read_request
- write_……
- aio
- aio_read
同步与异步用来处理两者之间的关系
实现细节
环形队列
环形队列实现方式
- 链表
- 好处:插入简单、删除简单
- 坏处:有锁(双向链表)
- 连续内存 (数组):逻辑环,双指针快
- 好处:无锁队列、原子操作
- 坏处:读写需要拷贝
- io_uring 一般选择后者比较多,考量为:
- 链表容易出现很多小的内存,不好
- 连续内存的另一个好处是,可以做共享内存的映射
- 不过链表法还有另一种分支:手动管理内存,也能避免上面那个缺点,也还不错
两个环:
- submit queue, sq
- complete queue, sq
- 这两个环是使用了mmap映射的,这两个环是用户空间和内核空间共享的,所以取的时候是零拷贝
操作流程:
- 每次读请求,放到sq
- 处理完的结果,放到cq
- 遍历cq
io_uring
- liburing:用户态
- 3个syscall:内核态
tcp
tcp
- accept()
- recv()
- send()
流程
- 客户多次连接,多次accept
- recv
- send
- close
代码
略
其他
fio
iops,每秒的io次数
iodepth,异步时ring的长度
理论
代码实现
应用场景
更好的解决方案
协程
用户态协议栈 三部曲 uio,数据帧,协议栈
透过tcp server看到网络编程,多线程,网络协议栈
手撕 epoll 组件
链接到当前文件 0
没有文件链接到当前文件