我正在编写一个多进程UDP服务器,该服务器使用SO_REUSEPORT允许多个工作进程在同一端口上侦听。
是否有一种方法可以告诉内核,我希望基于数据包的源地址将数据包一致地传送到进程?
(服务器需要为每个源地址保留一个小状态。在进程本地拥有状态比在进程之间共享状态要容易得多。)
答案 0 :(得分:1)
您应该看一下并配置RPS: Receive Packet Steering:
确定RPS的目标CPU的第一步是计算 在数据包的地址或端口上进行流哈希(2元组或4元哈希) 取决于协议)。这用作 数据包的相关流。哈希由硬件提供 或将在堆栈中计算。
...
每个接收硬件队列都有一个与之关联的CPU列表 RPS可以使数据包排队以进行处理。对于每个收到的数据包, 根据流哈希对大小进行取模,从而得出列表的索引 列表中。索引CPU是处理数据包的目标, 并且数据包排队到该CPU的待办事项队列的末尾。
...
RPS扩展了内核在不引入CPU的情况下跨CPU接收处理的能力 重新排序。权衡从同一流发送所有数据包 如果流量的数据包速率不同,则到同一CPU的问题就是CPU负载不平衡。
另一个选项是Intel Ethernet Flow Director:
英特尔®以太网FD支持将接收到的数据包定向到不同队列的高级过滤器,并能够严格控制平台中的流量。它与运行处理应用程序的流和CPU内核相匹配,以实现流亲和力,并支持多个参数以实现灵活的流分类和负载平衡。在以应用程序定向路由(ATR)模式运行时,英特尔以太网FD本质上是Linux *系统上可用的硬件分流版本的接收流控制,而在此模式下运行时,则禁用接收数据包控制和接收流控制。
答案 1 :(得分:1)
使用带有SO_ATTACH_REUSEPORT_CBPF或SO_ATTACH_REUSEPORT_EBPF socket options的BPF将每个客户端分配给特定的套接字索引,您也许能够获得类似的结果。