Das FreeBSD-Handbuch
Zurück | Kapitel 12. Konfiguration und Tuning | Weiter

# 12.13. Einstellungen von Kernel Limits

## 12.13.1. Datei und Prozeß Limits

### 12.13.1.1. `kern.maxfiles`

Abhängig von den Anforderungen Ihres Systems kann `kern.maxfiles` erhöht oder erniedrigt werden. Die Variable legt die maximale Anzahl von Dateideskriptoren auf Ihrem System fest. Wenn die Dateideskriptoren aufgebraucht sind, werden Sie die Meldung “`file: table is full`” wiederholt im Puffer für Systemmeldungen sehen. Den Inhalt des Puffers können Sie sich mit `dmesg` anzeigen lassen.

Jede offene Datei, jedes Socket und jede FIFO verbraucht einen Dateideskriptor. Auf “dicken” Produktionsservern können leicht Tausende Dateideskriptoren benötigt werden, abhängig von der Art und Anzahl der gleichzeitig laufenden Dienste.

In älteren FreeBSD-Versionen wurde die Voreinstellung von `kern.maxfile` aus der Kernelkonfigurationsoption `maxusers` bestimmt. `kern.maxfiles` wächst proportional mit dem Wert von `maxusers`. Wenn Sie einen angepassten Kernel kompilieren, empfiehlt es sich diese Option entsprechend der maximalen Benutzerzahl Ihres Systems einzustellen. Obwohl auf einer Produktionsmaschine vielleicht nicht 256 Benutzer gleichzeitig angemeldet sind, können die benötigten Ressourcen ähnlich denen eines großen Webservers sein.

Die Variable `kern.maxusers` wird beim Systemstart automatisch aus dem zur Verfügung stehenden Hauptspeicher bestimmt. Im laufenden Betrieb kann dieser Wert aus der (nur lesbaren) sysctl-Variable `kern.maxusers` ermittelt werden. Falls ein System für diese Variable einen anderen Wert benötigt, kann der Wert über den Loader angepasst werden. Häufig verwendete Werte sind dabei 64, 128, sowie 256. Es ist empfehlenswert, die Anzahl der Dateideskriptoren nicht auf einen Wert größer 256 zu setzen, es sei denn, Sie benötigen wirklich eine riesige Anzahl von ihnen. Viele der von `kern.maxusers` auf einen Standardwert gesetzten Parameter können beim Systemstart oder im laufenden Betrieb in der Datei `/boot/loader.conf` (sehen Sie sich dazu auch loader.conf(5) sowie die Datei `/boot/defaults/loader.conf` an) an Ihre Bedürfnisse angepasst werden, so wie es bereits an anderer Stelle dieses Dokuments beschrieben ist.

Ältere FreeBSD-Versionen setzen diesen Wert selbst, wenn Sie in der Konfigurationsdatei den Wert `0` [1] angeben. Wenn Sie den Wert selbst bestimmen wollen, sollten Sie `maxusers` mindestens auf `4` setzen. Dies gilt insbesondere dann, wenn Sie beabsichtigen, das X Window-System zu benutzen oder Software zu kompilieren. Der Grund dafür ist, dass der wichtigste Wert, der durch `maxusers` bestimmt wird, die maximale Anzahl an Prozessen ist, die auf `20 + 16 * maxusers` gesetzt wird. Wenn Sie also `maxusers` auf 1 setzen, können gleichzeitig nur 36 Prozesse laufen, von denen ungefähr 18 schon beim Booten des Systems gestartet werden. Dazu kommen nochmals etwa 15 Prozesse beim Start des X Window-Systems. Selbst eine einfache Aufgabe wie das Lesen einer Manualpage benötigt neun Prozesse zum Filtern, Dekomprimieren und Betrachten der Datei. Für die meisten Benutzer sollte es ausreichen, `maxusers` auf 64 zu setzen, womit 1044 gleichzeitige Prozesse zur Verfügung stehen. Wenn Sie allerdings den gefürchteten Fehler proc table full beim Start eines Programms oder auf einem Server mit einer großen Benutzerzahl (wie `ftp.FreeBSD.org`) sehen, dann sollten Sie den Wert nochmals erhöhen und den Kernel neu bauen.

> Anmerkung: Die Anzahl der Benutzer, die sich auf einem Rechner anmelden kann, wird durch `maxusers` nicht begrenzt. Der Wert dieser Variablen legt neben der möglichen Anzahl der Prozesse eines Benutzers weitere sinnvolle Größen für bestimmte Systemtabellen fest.

### 12.13.1.2. `kern.ipc.somaxconn`

Die Variable `kern.ipc.somaxconn` beschränkt die Größe der Warteschlange (Listen-Queue) für neue TCP-Verbindungen. Der Vorgabewert von `128` ist normalerweise zu klein, um neue Verbindungen auf einem stark ausgelasteten Webserver zuverlässig zu handhaben. Auf solchen Servern sollte der Wert auf `1024` oder höher gesetzt werden. Ein Dienst (z.B. sendmail(8), oder Apache) kann die Größe der Queue selbst einschränken. Oft gibt es die Möglichkeit, die Größe der Listen-Queue in einer Konfigurationsdatei einzustellen. Eine große Listen-Queue übersteht vielleicht auch einen Denial of Service Angriff (DoS).

## 12.13.2. Netzwerk Limits

Die Kerneloption `NMBCLUSTERS` schreibt die Anzahl der Netzwerkpuffer (Mbufs) fest, die das System besitzt. Eine zu geringe Anzahl Mbufs auf einem Server mit viel Netzwerkverkehr verringert die Leistung von FreeBSD. Jeder Mbuf-Cluster nimmt ungefähr 2 kB Speicher in Anspruch, so dass ein Wert von 1024 insgesamt 2 Megabyte Speicher für Netzwerkpuffer im System reserviert. Wie viele Cluster benötigt werden, lässt sich durch eine einfache Berechnung herausfinden. Wenn Sie einen Webserver besitzen, der maximal 1000 gleichzeitige Verbindungen servieren soll und jede der Verbindungen je einen 16 kB großen Puffer zum Senden und Empfangen braucht, brauchen Sie ungefähr 32 MB Speicher für Netzwerkpuffer. Als Daumenregel verdoppeln Sie diese Zahl, so dass sich für `NMBCLUSTERS` der Wert 2x32 MB / 2 kB = 32768 ergibt. Für Maschinen mit viel Speicher sollten Werte zwischen 4096 und 32768 genommen werden. Sie können diesen Wert nicht willkürlich erhöhen, da dies bereits zu einem Absturz beim Systemstart führen kann. Mit der Option `-m` von netstat(1) können Sie den Gebrauch der Netzwerkpuffer kontrollieren.

Die Netzwerkpuffer können beim Systemstart mit der Loader-Variablen `kern.ipc.nmbclusters` eingestellt werden. Nur auf älteren FreeBSD-Systemen müssen Sie die Kerneloption `NMBCLUSTERS` verwenden.

Die Anzahl der sendfile(2) Puffer muss auf ausgelasteten Servern, die den Systemaufruf sendfile(2) oft verwenden, vielleicht erhöht werden. Dazu können Sie die Kerneloption `NSFBUFS` verwenden oder die Anzahl der Puffer in `/boot/loader.conf` (siehe loader(8)) setzen. Die Puffer sollten erhöht werden, wenn Sie Prozesse im Zustand `sfbufa` sehen. Die schreibgeschützte sysctl-Variable `kern.ipc.nsfbufs` zeigt die Anzahl eingerichteten Puffer im Kernel. Der Wert dieser Variablen wird normalerweise von `kern.maxusers` bestimmt. Manchmal muss die Pufferanzahl jedoch manuell eingestellt werden.

> Wichtig: Auch wenn ein Socket nicht blockierend angelegt wurde, kann der Aufruf von sendfile(2) blockieren, um auf freie `struct sf_buf` Puffer zu warten.

### 12.13.2.1. `net.inet.ip.portrange.*`

Die sysctl-Variable `net.inet.ip.portrange.*` legt die Portnummern für TCP- und UDP-Sockets fest. Es gibt drei Bereiche: den niedrigen Bereich, den normalen Bereich und den hohen Bereich. Die meisten Netzprogramme benutzen den normalen Bereich. Dieser Bereich umfasst in der Voreinstellung die Portnummern 500 bis 5000 und wird durch die Variablen `net.inet.ip.portrange.first` und `net.inet.ip.portrange.last` festgelegt. Die festgelegten Bereiche für Portnummern werden von ausgehenden Verbindungen benutzt. Unter bestimmten Umständen, beispielsweise auf stark ausgelasteten Proxy-Servern, sind alle Portnummern für ausgehende Verbindungen belegt. Bereiche für Portnummern spielen auf Servern keine Rolle, die hauptsächlich eingehende Verbindungen verarbeiten (wie ein normaler Webserver) oder nur eine begrenzte Anzahl ausgehender Verbindungen öffnen (beispielsweise ein Mail-Relay). Wenn Sie keine freien Portnummern mehr haben, sollten Sie die Variable `net.inet.ip.portrange.last` langsam erhöhen. Ein Wert von `10000`, `20000` oder `30000` ist angemessen. Beachten Sie auch eine vorhandene Firewall, wenn Sie die Bereiche für Portnummern ändern. Einige Firewalls sperren große Bereiche (normalerweise aus den kleinen Portnummern) und erwarten, dass hohe Portnummern für ausgehende Verbindungen verwendet werden. Daher kann es erforderlich sein, den Wert von `net.inet.ip.portrange.first` zu erhöhen.

### 12.13.2.2. TCP Bandwidth Delay Product Begrenzung

Die TCP Bandwidth Delay Product Begrenzung gleicht TCP/Vegas von NetBSD. Die Begrenzung wird aktiviert, indem Sie die sysctl-Variable `net.inet.tcp.inflight.enable` auf den Wert `1` setzen. Das System wird dann versuchen, für jede Verbindung, das Produkt aus der Übertragungsrate und der Verzögerungszeit zu bestimmen. Dieses Produkt begrenzt die Datenmenge, die für einen optimales Durchsatz zwischengespeichert werden muss.

Diese Begrenzung ist nützlich, wenn Sie Daten über Verbindungen mit einem hohen Produkt aus Übertragungsrate und Verzögerungszeit wie Modems, Gigabit-Ethernet oder schnellen WANs, zur Verfügung stellen. Insbesondere wirkt sich die Begrenzung aus, wenn die Verbindung die TCP-Option Window-scaling verwendet oder große Sende-Fenster (send window) benutzt. Schalten Sie die Debug-Meldungen aus, wenn Sie die Begrenzung aktiviert haben. Dazu setzen Sie die Variable `net.inet.tcp.inflight.debug` auf `0`. Auf Produktions-Systemen sollten Sie zudem die Variable `net.inet.tcp.inflight.min` mindestens auf den Wert `6144` setzen. Allerdings kann ein zu hoher Wert, abhängig von der Verbindung, die Begrenzungsfunktion unwirksam machen. Die Begrenzung reduziert die Datenmenge in den Queues von Routern und Switches, sowie die Datenmenge in der Queue der lokalen Netzwerkkarte. Die Verzögerungszeit (Round Trip Time) für interaktive Anwendungen sinkt, da weniger Pakete zwischengespeichert werden. Dies gilt besonders für Verbindungen über langsame Modems. Die Begrenzung wirkt sich allerdings nur auf das Versenden von Daten aus (Uploads, Server). Auf den Empfang von Daten (Downloads) hat die Begrenzung keine Auswirkungen.

Die Variable `net.inet.tcp.inflight.stab` sollte nicht angepasst werden. Der Vorgabewert der Variablen beträgt `20`, das heißt es werden maximal zwei Pakete zu dem Produkt aus Übertragungsrate und Verzögerungszeit addiert. Dies stabilisiert den Algorithmus und verbessert die Reaktionszeit auf Veränderungen. Bei langsamen Verbindungen können sich aber die Laufzeiten der Pakete erhöhen (ohne diesen Algorithmus wären sie allerdings noch höher). In solchen Fällen können Sie versuchen, den Wert der Variablen auf `15`, `10` oder `5` zu erniedrigen. Gleichzeitig müssen Sie vielleicht auch `net.inet.tcp.inflight.min` auf einen kleineren Wert (beispielsweise `3500`) setzen. Ändern Sie diese Variablen nur ab, wenn Sie keine anderen Möglichkeiten mehr haben.

## 12.13.3. Virtueller Speicher (Virtual Memory)

### 12.13.3.1. `kern.maxvnodes`

Ein vnode ist die interne Darstellung einer Datei oder eines Verzeichnisses. Die Erhöhung der Anzahl der für das Betriebssystem verfügbaren vnodes verringert also die Schreib- und Lesezugriffe auf Ihre Festplatte. vnodes werden im Normalfall vom Betriebssystem automatisch vergeben und müssen nicht von Ihnen angepasst werden. In einigen Fällen stellt der Zugriff auf eine Platte allerdings einen Flaschenhals dar, daher sollten Sie in diesem Fall die Anzahl der möglichen vnodes erhöhen, um dieses Problem zu beheben. Beachten Sie dabei aber die Größe des inaktiven und freien Hauptspeichers.

Um die Anzahl der derzeit verwendeten vnodes zu sehen, geben Sie Folgendes ein:

    # sysctl vfs.numvnodes
    vfs.numvnodes: 91349

Die maximal mögliche Anzahl der vnodes erhalten Sie durch die Eingabe von:

    # sysctl kern.maxvnodes
    kern.maxvnodes: 100000

Wenn sich die Anzahl der genutzten vnodes dem maximal möglichen Wert nähert, sollten Sie den Wert `kern.maxvnodes` zuerst um etwa 1.000 erhöhen. Beobachten Sie danach die Anzahl der vom System genutzten `vfs.numvnodes`. Nähert sich der Wert wiederum dem definierten Maximum, müssen Sie `kern.maxvnodes` nochmals erhöhen. Sie sollten nun eine Änderung Ihres Speicherverbrauches (etwa über top(1)) registrieren können und über mehr aktiven Speicher verfügen.

### Fußnoten

[1] | Der verwendete Algorithmus setzt `maxusers` auf die Speichergröße des Systems. Der minimale Wert beträgt dabei `32`, das Maximum ist `384`.

Zurück | Zum Anfang | Weiter
Tuning von Laufwerken | Nach oben | Hinzufügen von Swap-Bereichen

Wenn Sie Fragen zu FreeBSD haben, schicken Sie eine E-Mail an <de-bsd-questions@de.FreeBSD.org>.
Wenn Sie Fragen zu dieser Dokumentation haben, schicken Sie eine E-Mail an <de-bsd-translators@de.FreeBSD.org>.