為什麼要在 FreeBSD 中更改 net.inet.tcp.tcbhashsize?
在幾乎所有 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 或任何其他特定數字?
這更像是電腦科學問題。特別是如果您想深入研究雜湊表和大 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 Illustrated, Volume 2: The Implementation By Gary R. Wright, W. Richard Stevens