web-dev-qa-db-ja.com

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).

この不思議なことに触れているのは、トランスポート層の下にあるプロトコル制御ブロックルックアップサブセクションです FreeBSDIPとTCPスタック の最適化)==ですが、その説明はこれは、それを使用する際の潜在的なボトルネックに関するものです。新しいTCPセグメントをリスニングソケットに一致させることに関連しているようですが、方法がわかりません。

TCP制御ブロックは何に使用されますか?ハッシュサイズを4096またはその他の特定の数値に設定する必要があるのはなぜですか?

8
sh-beta

それはコンピュータサイエンスの質問のようなものです。特に、 ハッシュテーブル および big-O 表記を掘り下げたい場合。

答えは:
多くのTCPセッションをサーバーで処理している場合は、接続のtcpパラメーターをOではなくO(1)時間で検索する必要があります(n)。FreeBSDは chaining を使用してハッシュテーブルの衝突を解決します。したがって、接続が多い場合は、O(1)の代わりに、衝突が多くなります。ハッシュテーブルルックアップは、O(n)複雑さの線形チェーンルックアップを実行する必要があります。

あなたが言及したパラメータ-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 。ライト、W。リチャードスティーブンス

3
SaveTheRbtz