我正在尝试了解在Linux上为我们的流媒体网络应用程序增加套接字缓冲区大小的正确方法。应用程序接收在多个UDP套接字上流式传输的可变比特率数据。在流的开头,数据量大大增加,我用过:
# sar -n UDP 1 200
表示UDP堆栈丢弃数据包和
# ss -un -pa
表示每个套接字Recv-Q长度在丢弃数据包之前增长到接近极限(124928. sysctl net.core.rmem_default
)。这意味着应用程序根本无法跟上流的开始。丢弃足够的初始数据包后,数据速率变慢,应用程序赶上。 Recv-Q趋向于0,并在此期间保持不变。
我能够通过大幅增加rmem_default值来解决数据包丢失问题,这会增加套接字缓冲区的大小,并使应用程序有时间从大的初始突发中恢复。我的理解是,这会更改系统上所有套接字的默认分配。我宁愿只增加特定UDP套接字的分配,而不是修改全局默认值。
我最初的策略是修改rmem_max并在每个单独的套接字上使用setsockopt(SO_RCVBUF)。但是,这个question使我担心禁用所有套接字的Linux自动调整而不仅仅是UDP。
udp(7)描述了udp_mem设置,但我很困惑这些值如何与rmem_default和rmem_max值相互作用。它使用的语言是“所有套接字”,所以我怀疑这些设置适用于完整的UDP堆栈而不是单独的UDP套接字。
udp_rmem_min是我正在寻找的设置吗?它似乎适用于单个套接字,但对于系统上的所有UDP套接字都是全局的。
有没有办法安全地增加应用程序中使用的特定UDP端口的套接字缓冲区长度而不修改任何全局设置?
感谢。
答案 0 :(得分:0)
网络数据包泛洪的解决方案几乎从不增加缓冲。为什么你的协议的排队策略没有退出?如果您尝试在流中发送如此多的数据(这就是TCP的设计目的),为什么不能只使用TCP。