一. 简介
Onload本质是采用了LD_PRELOAD加载sf的网络库,取代socket(), read(), write()
原本的glibc实现,避开了网络协议栈做到了网络加速的效果,由于其易于使用、不用额外开发API,所以非常的方便好用且效果拔群。本文记录onload的使用基础知识。
二. 说明
Onload Stacks
Onload栈类似于TCP/IP栈,包括发送、接受缓冲区,连接和端口数,栈操作选项等。每个栈均会和一个或多个虚拟NIC相关联。通常一个进程的多个连接会共享同一个Onload栈,但是也可以让多进程共享同一个Onload栈,或让一个进程拥有多个栈。
Onload在多网卡下的表现
对于PC插有SF卡和非SF卡的,如果指定的IP是非SF卡,则会自动切换至linux套接字走内核处理。
接口控制
- 系统级别的配置在
/proc/driver/sfc_resource/<intf-name>/
目录 - 对于每个栈环境,可以通过EF_INTERFACE_BLACKLIST 和 EF_INTERFACE_WHITELIST 实现
支持的系统调用说明
在该列表中可见[onload]/src/include/onload/declare_syscalls.h.tmpl
I/O复用的支持
对于Linux下常见的poll(), select(), epoll()
均有支持,表现如下
- 如果某个文件描述符有操作可以执行,则会立刻返回,否则如果spining未开则会走到内核并阻塞
- 如果多个套接字中存在某些未被onload加速的,则
poll(), select()
会有一个系统调用的损耗去判断是否该加速。 - 如果没有文件描述符准备好,spining开启,onload会进入spin状态,避免了陷入内核。
数据包的传递顺序
TCP/UDP应用在多套接字同时工作的环境下时,很难保证到达的严格顺序,Onload提供了接口onload_ordered_epoll_wait()
使用时间戳来还原包的顺序。为开启此功能,需要以下条件
- 多套接字必须都是Onload栈工作才可以,通过
onload_fd_stat()
可以保证 - 需要硬件时间戳
EF_RX_TIMESTAMPING
设置为1EF_UL_EPOLL
设置为1或者3EPOLLET
和ONESHOT
禁用onload_ordered_epoll_wait()
多线程下不安全
栈共享
默认情况下,每个调用Onload的进程都有自己的Onload栈。但是使用EF_NAME环境变量,可以让多个进程也可以共享同一个Onload栈。栈共享在以下场景可以有较好的加速效果
- 多个进程接受同一个组播/多播流
- 一个进程接受另一个本地进程写的多播流
除了栈共享,还可以使用Multicast Replication and Hardware Multicast Loopback达到类似的效果。
可能带来的问题:
- 共享情况下,安全问题
- 一个程序的BUG可能导致两个程序都工作失常