C 使用SO_REUSEPORT时,是否从同一客户端获取UDP数据包,并将其传送到同一服务器进程?

C 使用SO_REUSEPORT时,是否从同一客户端获取UDP数据包,并将其传送到同一服务器进程?,c,udp,so-reuseport,C,Udp,So Reuseport,我正在编写一个多进程UDP服务器,它使用SO_REUSEPORT让多个工作进程监听同一端口 有没有一种方法可以告诉内核,我希望根据数据包的源地址将数据包一致地传递给进程 (服务器需要为每个源地址保留一点状态。将状态设置为进程的本地状态比在进程之间共享状态更容易。)您应该查看并配置: 确定RPS的目标CPU的第一步是计算 数据包地址或端口上的流散列(2元组或4元组散列 取决于协议)。这将作为 数据包的关联流。哈希要么由硬件提供 或将在堆栈中计算 每个接收硬件队列都有一个与之关联的CPU列表 RP

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

有没有一种方法可以告诉内核,我希望根据数据包的源地址将数据包一致地传递给进程


(服务器需要为每个源地址保留一点状态。将状态设置为进程的本地状态比在进程之间共享状态更容易。)

您应该查看并配置:

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

每个接收硬件队列都有一个与之关联的CPU列表 RPS可以将数据包排队以进行处理。对于每个接收到的数据包, 列表中的索引是根据流哈希值乘以大小计算的 在名单上。索引CPU是处理数据包的目标, 数据包被排到CPU待办事项队列的尾部

RPS跨CPU扩展内核接收处理,而不引入 重新排序。从同一个流发送所有数据包的权衡 对于同一个CPU,如果数据流的数据包速率不同,则CPU负载不平衡

另一个选择是:

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


您应该查看并配置:

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

每个接收硬件队列都有一个与之关联的CPU列表 RPS可以将数据包排队以进行处理。对于每个接收到的数据包, 列表中的索引是根据流哈希值乘以大小计算的 在名单上。索引CPU是处理数据包的目标, 数据包被排到CPU待办事项队列的尾部

RPS跨CPU扩展内核接收处理,而不引入 重新排序。从同一个流发送所有数据包的权衡 对于同一个CPU,如果数据流的数据包速率不同,则CPU负载不平衡

另一个选择是:

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


使用带有SO_ATTACH_REUSEPORT_CBPF或SO_ATTACH_REUSEPORT_EBPF的BPF将每个客户机分配给特定的套接字索引,您可能能够获得类似的结果

使用BPF和SO_ATTACH_REUSEPORT_CBPF或SO_ATTACH_REUSEPORT_EBPF将每个客户机分配到特定的套接字索引,您可能能够获得类似的结果

假设您正在尝试分离流,那么如果一个主机启动多个客户端(因此是流),该怎么办?你还需要把它们分开吗?我真的(真的)不建议每个客户都有一个流程。我也不建议每个客户端使用线程。。。当然,除非您知道您的服务器永远不会经历高并发负载。考虑一下,在1k个客户端,您将拥有1k进程/线程。这是一个很大的开销-在每个线程2Mb堆栈的情况下,最便宜的内存成本将是2Gb,我甚至没有考虑复制页表(分叉时)所用的内存或上下文切换中增加的成本。@Myst抱歉,我不清楚-我每个核心使用一个工作进程。我只想在八个工作进程中的一个进程中保存每个客户端的状态。假设您试图分离流,那么如果一个主机启动多个客户端(因此流)会怎么样?你还需要把它们分开吗?我真的(真的)不建议每个客户都有一个流程。我也不建议每个客户端使用线程。。。当然,除非您知道您的服务器永远不会经历高并发负载。考虑一下,在1k个客户端,您将拥有1k进程/线程。这是一个很大的开销-在每个线程2Mb堆栈的情况下,最便宜的内存成本将是2Gb,我甚至没有考虑复制页表(分叉时)所用的内存或上下文切换中增加的成本。@Myst抱歉,我不清楚-我每个核心使用一个工作进程。我只想在八个工作进程中的一个进程中保存每个客户机的状态。