Warum net.inet.tcp.tcbhashsize in FreeBSD ändern?

8

In praktisch jedem FreeBSD-Netzwerkoptimierungsdokument kann ich Folgendes finden:

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

Dies wird normalerweise mit einer nicht hilfreichen Anweisung wie "TCP-Steuerblock-Hash-Tabellenoptimierung" oder "Setzen Sie dies auf einen vernünftigen Wert" gepaart. man 4 tcpist auch nicht viel Hilfe:

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

Das einzige Dokument, das dieses mysteriöse Thema berührt, ist der Unterabschnitt "Protokollsteuerungsblock-Suche" unter "Transportschicht" zur Optimierung des FreeBSD-IP- und TCP-Stacks . In seiner Beschreibung geht es jedoch mehr um mögliche Engpässe bei der Verwendung. Es scheint daran gebunden zu sein, neue TCP-Segmente mit ihren Listening-Sockets abzugleichen, aber ich bin mir nicht sicher, wie.

Wofür genau wird der TCP-Steuerblock verwendet? Warum sollten Sie die Hash-Größe auf 4096 oder eine andere bestimmte Zahl festlegen?

sh-beta
quelle
+1, sehr interessante Frage!
Janne Pikkarainen
AFAIK, alle Informationen zur Zustellung des Pakets an den entsprechenden Socket sind nur über verfügbar inpcb.
SaveTheRbtz

Antworten:

3

Es ist eher eine Frage der Informatik. Vor allem, wenn Sie sich mit Hash-Tabellen und Big-O- Notationen beschäftigen möchten .

Die Antwort lautet:
Wenn Sie viele TCP-Sitzungen auf einem Server abwickeln, möchten Sie die TCP-Parameter der Verbindung wirklich in O (1) -Zeit anstelle von O (n) nachschlagen. FreeBSD verwendet Verkettung , um Kollisionen von Hash-Tabellen aufzulösen. Wenn also viele Verbindungen bestehen, kommt es zu vielen Kollisionen. Anstelle der Suche nach O (1) -Hashtabellen müssen Sie daher eine lineare Kettensuche mit O (n) -Komplexität durchführen.

Der von Ihnen erwähnte Parameter tcbhashsizeist im Grunde die Anzahl der Buckets in der Hash-Tabelle.
Auf unseren Servern ist es auf ziemlich hohe Werte wie 16384und noch höher eingestellt. Mit dieser Einstellung verarbeiten wir ungefähr 60.000 Verbindungen pro Server.

Jeder Eintrag in der Hash-Tabelle auf x86_64 verwendet 252 Bytes ( tcp_inpcb) + 688 Bytes ( tcpcb) Kernelspeicher für jeden Eintrag (kmem-Größe beträgt 512 G in amd64 seit 7.2+ IIRC). Es kann über angesehen werden vmstat -z.

Über die Struktur des TCP- Steuerblocks können Sie FreeBSD-Quellen lesen: tcp_var.h oder TCP / IP Illustrated, Band 2: Die Implementierung von Gary R. Wright, W. Richard Stevens

SaveTheRbtz
quelle
Es war alles verschwommen, aber jetzt mit diesem obskuren C-Header ist alles klar;)
gparent
Ich verstehe, warum das Erhöhen der Anzahl von Buckets in einer Hashtabelle die Leistung von Suchvorgängen in diesen Buckets verbessern würde. Ich wusste nicht, dass dies tatsächlich das war, was dieser Wert tat. Wenn dies eine Tabelle mit Buckets ist, dann werden in der TCPCB tatsächlich Socket-Informationen gespeichert, damit TCP-Segmente mit dem richtigen Empfänger abgeglichen werden können. Können Sie das bestätigen? Ein Teil des Zwecks dieser Websites besteht auch darin, Informationen zu aggregieren, sodass die Antworten "Quelle lesen" oder "Buch lesen" nicht sehr nützlich sind.
Sh-Beta
Wie bist du zu deiner Stimmung von 16384 gekommen? Warum das? Und was opfern Sie für diesen Wert (ich nehme an, Kernelspeicher, aber wie viel?)? Wenn es ein kostenloser Leistungsgewinn wäre, würde ich gerne denken, dass dies die Standardeinstellung ist. Sicher kostet es etwas.
Sh-Beta
Meiner Meinung nach sollte dieser Wert etwas nahe an der Anzahl der gleichzeitigen Verbindungen liegen, die dieser Server verarbeiten möchte. PS. Möchten Sie wirklich ein Experte in einem bestimmten Bereich werden, ohne Quellen / Bücher zu lesen? =)
SaveTheRbtz
1
@SaveTheRbtz Ich verabscheue diese Vorstellung, dass Sie, wenn Sie eine Technologie verwenden, entweder aufhören müssen, Fragen zu stellen, oder so gut mit dem Code vertraut werden müssen, dass Sie den genauen Zweck jeder einzelnen Struktur und Funktion im Netzwerkstapel angeben können. Der Zweck von StackExchange ist der Austausch von Wissen. Ich bin ein Experte in einigen Dingen und nicht in anderen. Diese Linie wird durch meine Arbeit bestimmt, bei der ich sorgfältig auswählen muss, wo ich meine Zeit verbringe. Das heißt aber nicht, dass ich damit zufrieden bin, einfach "Ratschläge" zu akzeptieren, die scheinbar undenkbar von Blog zu Blog kopiert und eingefügt wurden.
Sh-Beta