0

我正在编写一个多进程 UDP 服务器,它使用 SO_REUSEPORT 让多个工作进程在同一个端口上侦听。

有没有办法告诉内核我希望根据数据包的源地址将数据包一致地传递给进程?

(服务器需要为每个源地址保存一些状态。将状态置于进程本地会更容易,而不是必须在进程之间共享状态。)

4

2 回答 2

2

您应该查看并配置RPS:接收数据包转向

为 RPS 确定目标 CPU 的第一步是计算数据包地址或端口上的流散列(2 元组或 4 元组散列取决于协议)。这用作数据包关联流的一致散列。哈希要么由硬件提供,要么将在堆栈中计算。

...

每个接收硬件队列都有一个关联的 CPU 列表,RPS 可以将数据包排入队列以进行处理。对于每个接收到的数据包,列表中的索引是根据流哈希以列表的大小为模计算得出的。索引的 CPU 是处理数据包的目标,数据包排队到该 CPU 的积压队列的尾部。

...

RPS 在不引入重新排序的情况下跨 CPU 扩展内核接收处理。如果流的数据包速率不同,则将来自同一流的所有数据包发送到同一 CPU 的权衡是 CPU 负载不平衡。

另一种选择是英特尔以太网流量控制器

英特尔以太网 FD 支持将接收到的数据包定向到不同队列的高级过滤器,并能够对平台中的流量进行严格控制。它匹配运行处理应用程序的流和 CPU 内核以实现流关联,并支持多个参数以实现灵活的流分类和负载平衡。在应用程序目标路由 (ATR) 模式下运行时,英特尔以太网 FD 本质上是 Linux* 系统上可用的接收流引导的硬件卸载版本,在此模式下运行时,接收数据包引导和接收流引导被禁用。

于 2019-07-09T13:41:39.093 回答
1

您可以使用带有 SO_ATTACH_REUSEPORT_CBPF 或 SO_ATTACH_REUSEPORT_EBPF套接字选项的 BPF 来实现类似的结果,以将每个客户端分配给特定的套接字索引。

于 2019-07-09T13:51:23.763 回答