在几乎每一个 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
这更像是计算机科学问题。特别是如果你想深入研究哈希表和大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 以来,amd64 中的 kmem 大小为 512G)。可以通过 查看vmstat -z
。
关于 TCP 控制块的结构,你可以阅读 FreeBSD 源代码:tcp_var.h或阅读TCP/IP 图解,第 2 卷:实施,作者:Gary R. Wright、W. Richard Stevens