12.14. Fijnafstemming van kernellimieten

12.14.1. Bestandsproceslimieten

12.14.1.1. kern.maxfiles

kern.maxfiles kan worden verhoogd of verlaagd, afhankelijk van de systeembehoeften. Deze variabele geeft het maximale aantal bestandsdescriptors op een systeem. Als de bestandsdescriptortabel vol is, toont de systeembuffer meerdere malen “file: table is full”, hetgeen achteraf te zien is met dmesg.

Elk geopend bestand, socket of fifo heeft een bestandsdescriptor. Een grote produktieserver kan makkelijk enige duizenden bestandsdescriptors nodig hebben, afhankelijk van het soort en aantal diensten die tegelijk draaien.

In oudere versies van FreeBSD werd de standaard waarde van kern.maxfiles afgeleid van de optie maxusers in het kernelconfiguratiebestand. kern.maxfiles groeit evenredig met de waarde van maxusers. Als een aangepaste kernel wordt gebouwd, is het een goed idee om deze kerneloptie in te stellen afhankelijk van het gebruikt van een systeem (maar niet te laag). Hoewel een produktieserver misschien niet 256 gelijktijdige gebruikers heeft, kunnen de benodigde systeembronnen het beste vergeleken worden met een grootschalige webserver.

De optie maxusers stelt de grootte van een aantal belangrijke systeemtabellen in. Dit aantal moet ruwweg gelijk zijn aan het aantal gebruikers dat verwacht wordt gelijktijdig van de machine gebruik te maken.

Vanaf FreeBSD 4.5 wordt kern.maxusers automatisch ingesteld tijdens het opstarten gebaseerd op de hoeveelheid beschikbare geheugen in het systeem en kan worden vastgesteld tijdens het draaien door te kijken naar de alleen-lezen sysctl kern.maxusers. Sommige configuraties hebben grotere of kleinere waarden nodig van kern.maxusers, deze kunnen worden gezet als een opstartvariabele. Waardes van 64, 128 en 256 zijn daarin niet ongewoon. We raden aan om niet boven de 256 te gaan tenzij er heel veel bestandsdescriptors benodigd zijn; veel van de aanpasbaare waarden die standaard worden bepaald door kern.maxusers kunnen individueel worden overschreven tijdens het opstarten en/of tijdens het draaien van het systeem in /boot/loader.conf (zie de handleiding loader.conf(5) of /boot/defaults/loader.conf voor een paar aanwijzingen) of zoals elders beschreven in dit document.

Voor oudere versies stelt het systeem deze waarde zelf in als deze uitdrukkelijk op 0 is gezet. [1] Als het gewenst is om deze waarde zelf aan te geven, wordt aangeraden om maxusers minstens op 4 te zetten, met name als het X Window systeem in gebruik is of als er software gecompileerd wordt. De reden hiervoor is dat de belangrijkste tabel die door maxusers ingesteld wordt, het maximum aantal processen is, dat ingesteld wordt op 20 + 16 * maxusers, dus als maxusers op 1 ingesteld wordt, zijn er maar 36 gelijktijdige processen mogelijk, inclusief de ongeveer achttien processen die door het systeem tijdens het opstarten start en de ongeveer vijftien processen die waarschijnlijk aangemaakt worden door het opstarten van het X Window systeem. Zelfs een eenvoudige taak als het afbeelden van een hulppagina start negen processen op om de pagina te filteren, te decomprimeren en af te beelden. Als maxusers op 64 ingesteld wordt, zijn er 1044 gelijktijdige processen mogelijk, wat genoeg moet zijn voor bijna alle soorten gebruik. Als echter de gevreesde fout proc table full verschijnt als er geprobeerd wordt om een programma op te starten of als er een server gedraaid wordt met een groot aantal gelijktijdige gebruikers, zoals ftp.FreeBSD.org, kan het getal altijd verhoogd worden en kan de kernel opnieuw gebouwd worden.

Opmerking: maxusers stelt geen grens aan het aantal gebruikers dat zich op de machine kan aanmelden. Het stelt gewoon verschillende tabelgroottes in op redelijke waardes, uitgaande van het maximum aantal gebruikers dat waarschijnlijk de machine gebruikt en van het aantal processen dat elk van deze gebruikers zal draaien. Een sleutelwoord dat wel het aantal gelijktijdige aanmeldingen op afstand en X-terminalvensters begrensd is pseudo-device pty 16. In FreeBSD 5.X kan dit getal genegeerd worden omdat daar het stuurprogramma pty(4) “auto-cloning” is. Er kan eenvoudig gebruik worden gemaakt van de regel device pty in het instellingenbestand.

12.14.1.2. kern.ipc.somaxconn

De sysctl-variabele kern.ipc.somaxconn beparkt de grootte van de luisterwachtrij voor het accepteren van nieuwe TCP-verbindingen. De standaardwaarde van 128 is meestal te laag voor robuuste behandeling van nieuwe verbindingen in een zwaarbeladen webserveromgeving. Voor zulke omgevingen wordt aangeraden deze waarde te verhogen tot 1024 of hoger. De dienstdaemon beperkt misschien zelf de luisterwachtrij (bijvoorbeeld sendmail(8) of Apache), maar heeft vaak een mogelijkheid in een configuratiebestand de wachtrijgrootte aan te passen. Grote luisterwachtrijen zijn ook beter in het ontwijken van Ontzegging van Dienst (DoS) aanvallen.

12.14.2. Netwerkbeperkingen

De kerneloptie NMBCLUSTERS bepaalt het aantal netwerk-Mbufs dat beschikbaar is voor een systeem. Een veel bezochte server met een laag aantal Mbufs beperkt de mogelijkheden van FreeBSD. Elk cluster staat voor ongeveer 2 K geheugen, dus een waarde van 1024 stelt 2 megabyte aan kernelgeheugen voor, dat is gereserveerd voor netwerkbuffers. Een simpele berekening geeft aan hoeveel er nodig is. Stel dat een webserver met een maximum van 1000 simultane verbindingen voor elke verbinding 16 K aan ontvangstnetwerkbuffers en 16 K aan zendbuffers kost, dan is ongeveer 32 MB aan netbuffers nodig voor de webserver. Een goede vuistregel is te vermeniguldigen met twee, dus 2x32 MB / 2 KB = 64 MB / 2 kB = 32768. Voor machines met veel geheugen wordt 4096 tot 32768 aangeraden. Er moet in geen geval een arbitrair hoge waarde voor deze sysctl opgegeven worden, want dat kan leiden tot een crash tijdens het opstarten. Met de optie -m van netstat(1) kan het clustergebruik van het netwerk bekeken worden.

De loaderparameter kern.ipc.nmbclusters moet gebruikt worden om dit tijdens het opstarten toe te passen. Alleen voor oudere versies van FreeBSD is het nodig om de kerneloptie NMBCLUSTERS te gebruiken.

Voor drukke servers die extensief gebruik maken van de systeemaanroep sendfile(2), kan het nodig zijn het aantal sendfile(2)-buffers te verhogen via de kerneloptie NSFBUFS of door de waarde in te stellen in /boot/loader.conf (in loader(8) staan details). Als er in de procestabel processen staan met een status sfbufa is dat een algemene indicator dat deze parameter aangepast moet worden. De sysctl-variabele kern.ipc.nsfbufs is alleen-lezen en laat zien op welke waarde deze kernelvariabele is ingesteld. Deze parameter schaalt engiszins met de variabele kern.maxusers, maar het kan nodig zijn om deze bij te stellen.

Belangrijk: Zelfs als een socket als non-blocking gemarkeerd is, dan nog kan het aanroepen van sendfile(2) op de non-blocking socket ertoe leiden dat er toch blokkade optreedt totdat er voldoende struct sf_buf's vrijgemaakt zijn.

12.14.2.1. net.inet.ip.portrange.*

De sysctl-variabelen net.inet.ip.portrange.* bepalen welke reeks poortnummers automatisch gebonden wordt aan TCP- en UDP-sockets. Er zijn drie gebieden: een laag gebied, een (standaard) middengebied en een hoog gebied. De meeste netwerkprogramma's gebruiken het standaardbereik, wat begrensd wordt door net.inet.ip.portrange.first en net.inet.ip.portrange.last met standaardwaarden van respectievelijk 1024 en 5000. Gebonden poortreeksen worden gebruikt voor uitgaande verbindingen en het is onder bepaalde omstandigheden mogelijk dat poorten op raken. Dit gebeurt meestal in het geval van een zwaar belaste webproxy. Poortbereik is niet van belang als vooral diensten draaien die zich bezighouden met inkomende verbindingen, zoals een normale webserver, of als het aantal uitgaande verbindingen beperkt is, zoals bij een mailrelay. Voor situaties waarin een tekort aan poorten dreigt, wordt aangeraden om net.inet.ip.portrange.last bescheiden op te hogen. Een waarde van 10000, 20000 of 30000 is redelijk. Er moet ook rekening met effecten op firewalls gehouden worden als de poortreeks gewijzigd wordt. Sommige firewalls kunnen grote poortreeksen blokkeren, meestal de lagere poorten, en verwachten dat andere systemen hogere poorten gebruiken voor uitgaande verbindingen. Om deze reden wordt het niet aanbevolen om net.inet.ip.portrange.first te verlagen.

12.14.2.2. TCP Bandbreedtevertragingsproduct (TCP Bandwidth Delay Product)

De TCP-bandbreedtevertragingsproductlimitatie lijkt op TCP/Vegas in NetBSD. Het kan aangezet worden door de sysctl-variabele net.inet.tcp.inflight.enable de waarde 1 te geven. Het systeem tracht dan het bandbreedtevertragingssprodukt te berekenen voor elke verbinding en beperkt dan de hoeveelheid gegevens in de wachtrij naar het netwerk tot de hoeveelheid die vereist is om maximale doorvoer te kunnen handhaven.

Dit is nuttig bij gebruik van modems, Gigabit Ethernet of zelfs bij WAN-verbindingen met hoge snelheid (of elke andere verbinding met een groot bandbreedtevertragingsprodukt), in het bijzonder als ook windowschaling of een groot verzendwindow gebruikt wordt. Als deze optie aangezet wordt, dient ook net.inet.tcp.inflight.debug de waarde 0 te krijgen (geen debugging) en voor produktiegebruik kan het instellen van net.inet.tcp.inflight.min naar minstens 6144 voordeel opleveren. Het instellen van hoge minima kan effectief het beperken van bandbreedte ondermijnen, afhankelijk van de verbinding. De mogelijkheid tot limitering zorgt ervoor dat de hoeveelheid gegevens die opgebouwd wordt, in tussentijdse route- en switchwachtrijen verlaagd kan worden en tevens kan de hoeveelheid gegevens die opgebouwd wordt in de interfacewachtrij van de lokale host verlaagd worden. Met minder pakketten in wachtrijen kunnen interactieve verbindingen opereren met lagere Round Trip tijden, met name over langzame modems. Deze optie gaat alleen over datatransmissie (upload / serverkant) en heeft geen effect gegevensontvangst (download / cliëntkant).

Aanpassen van net.inet.tcp.inflight.stab wordt niet aangeraden. Deze parameter krijgt standaard een waarde van 20, wat 2 maximale pakketten opgeteld bij de bandbreedtevensterberekening representeert. Het extra venster is nodig om het algoritme stabiel te houden en om de reactietijd bij veranderende omstandigheden te verbeteren, maar het kan ook leiden tot langere pingtijden over langzame verbindingen (zonder het inflight-algoritme kan dit echter nog erger zijn). In dergelijke gevallen kan deze parameter misschien verlaagd worden naar 15, 10 of 5 en misschien moet voor het gewenste effect ook net.inet.tcp.inflight.min verlaagd worden (bijvoorbeeld naar 3500). Het verlagen van deze parameters moet pas in laatste instantie overwogen worden.

12.14.3. Virtueel Geheugen

12.14.3.1. kern.maxvnodes

Een vnode is de interne representatie van een bestand of een map. Het verlagen van het aantal beschikbare vnodes voor het besturingssysteem leidt dus tot een daling van schijf-I/O. Normaliter wordt dit door het besturingssysteem afgehandeld en hoeft de instelling niet gewijzigd te worden. Im sommige gevallen kan schijf-I/O de beperkende factor zijn en kan het systeem alle beschikbare vnodes in gebruik hebben. Dan dient deze instelling gewijzigd te worden. De hoeveelheid inactief en beschikbaar RAM dient meegenomen te worden in de beslissing.

Het huidige aantal gebruikte vnodes kan als volgt bekeken worden:

# sysctl vfs.numvnodes
vfs.numvnodes: 91349

Om het maximale aantal vnodes weer te geven:

# sysctl kern.maxvnodes
kern.maxvnodes: 100000

Als het huidige aantal gebruikte vnodes dicht bij het maximale aantal ligt, is het verstandig om kern.maxvnodes op te hogen met 1.000. Ook vfs.numvnodes dient in de gaten gehouden te worden. Als de waarde weer tot aan het maximum stijgt, dan moet kern.maxvnodes verder opgehoogd worden. Er dient een verschuiving op te treden in het door top(1) gerapporteerde geheugengebruik. Er hoort meer geheugen actief te zijn.

Noten

[1]

Het auto-tuning-algoritme stelt maxusers in afhankelijk van de hoeveelheid geheugen in het systeem, met een minimum van 32 en een maximum van 384.