为什么要在FreeBSD中更改net.inet.tcp.tcbhashsize?


8

在几乎每个FreeBSD网络调整文档中,我都能找到:

# /boot/loader.conf
net.inet.tcp.tcbhashsize=4096

这通常与一些无用的语句配对,例如“ TCP控制块哈希表调整”或“将其设置为合理的值”。man 4 tcp并没有太大帮助:

tcbhashsize         Size of the TCP control-block hash table (read-only).
                    This may be tuned using the kernel option TCBHASHSIZE
                    or by setting net.inet.tcp.tcbhashsize in the
                    loader(8).

我能找到的唯一涉及到这一神秘事物的文档是“ 优化FreeBSD IP和TCP堆栈”中“传输层”下的“协议控制块查找”小节,但其描述更多地是关于使用它的潜在瓶颈。这似乎与将新的TCP段匹配到其侦听套接字有关,但是我不确定如何。

TCP控制块到底是做什么用的?为什么要将其哈希大小设置为4096或任何其他特定数字?


+1,非常有趣的问题!
Janne Pikkarainen 2012年

AFAIK,inpcb仅可通过以下方式获得有关将数据包传送到适当套接字的所有信息。
SaveTheRbtz 2012年

Answers:


3

这更像是计算机科学的问题。特别是如果您想深入研究哈希表big-O表示法。

答案是:
如果要在服务器上处理许多TCP会话,则您真的想在O(1)而不是O(n)的时间内查找连接的tcp参数。FreeBSD使用链接来解决哈希表冲突。因此,如果存在大量连接,则会发生大量冲突,因此,您需要进行复杂度为O(n)的线性链表查找,而不是O(1)哈希表查找。

您提到的参数- tcbhashsize基本上是哈希表中的存储桶数。
在我们的服务器上,它设置为相当高的值16384,甚至更高。使用该设置,我们每个服务器可以处理约60,000个连接。

当前在x86_64上,哈希表中的每个条目本身就为每个条目使用252字节(tcp_inpcb)+ 688字节(tcpcb)的内核内存(由于7.2+ IIRC,kmd在amd64中为512G)。可以通过查看vmstat -z

关于TCP Control块的结构,您可以阅读FreeBSD源:tcp_var.h或阅读TCP / IP图解,第2卷:实现作者:Gary R. Wright,W. Richard Stevens


一切都很模糊,但是现在有了这个晦涩的C头,一切都清楚了;)
gparent

我了解为什么增加哈希表中的存储桶数量会有助于这些存储桶中查询的性能,但我没有意识到这实际上就是该值的作用。如果这是一个存储桶表,那么我想TCPCB确实是存储套接字信息的地方,以便可以将TCP段匹配到正确的接收者。你能确认吗?另外,这些站点的部分目的是汇总信息,因此“阅读源代码”或“阅读书”答案并不是很有用。
sh-beta

您是如何调整16384的?为什么?您要为此值牺牲什么(我假设内核内存,但是多少?)?如果这是一场免费的比赛胜利,我想这将是默认的。当然要花些钱。
sh-beta

我认为该值应设置为与该服务器愿意处理的并发连接数接近。PS。您是否真的想成为某些领域的专家,而无需阅读源/书?=)
SaveTheRbtz 2012年

1
@SaveTheRbtz我不赞成这种观点,即如果您使用某种技术,则需要停止提出问题或变得对代码如此熟练,以至于可以重申网络堆栈中每个结构和功能的确切目的。StackExchange的目的是交换知识。我是某些方面的专家,而不是其他方面的专家。那条线是由我的工作决定的,我必须仔细选择我在哪里度过的时间。但这并不意味着我满足于简单地接受调整“建议”,而这些建议似乎是从博客到博客的无意复制和粘贴。
sh-beta
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.