PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Systemweites Anheben der maximal offenen Filedeskriptoren



7.e.Q
09.08.05, 10:02
Hi Leute,

ich muss systemweit die maximal offene Anzahl Filedeskriptoren pro Prozess massiv anheben. ulimit -n 4096 reicht offenbar nicht aus. Wir brauchen mindestens 65536 offene Filedeskriptoren pro Prozess. Ist das technisch überhaupt möglich? Reicht es aus, die defines NR_OPEN und/oder INR_OPEN in der fs.h des Kernels entsprechend anzupassen?

Hintergrund ist, daß wir Last simulieren müssen. Sprich, es sollen bis zu 10.000 Teilnehmer (je Teilnehmer 2 Sockets und 2 offene Dateien, also 4 Filedeskriptoren benötigt) gleichzeitig miteinander kommunizieren können. Bis jetzt funktionieren nur 256 Teilnehmer: 256 * 4 = 1024 offene Filedeskriptoren. Obwohl ulimit -a folgendes ausgibt:



core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 4096
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 4096
virtual memory (kbytes, -v) unlimited


Es ist zwingend erforderlich, daß die "open files" später auch tatsächlich systemweit mindestens 65536 beträgt.

Wie bekommt man das System soweit auf???? :confused:

christophwth
09.08.05, 11:42
Hi

falls das nicht geht : echo 65535 > /proc/sys/fs/file-max

normal würde ich die limits.h dafür editieren. aber warum das verändern der fs.h nichts gebracht hat kann ich auch nicht sagen.

wie weit du die aufbohren kannst kann ich dir auch nicht sagen.
aber ich würde vermuten : 1024*1024
weil fs.h



/*
* It's silly to have NR_OPEN bigger than NR_FILE, but you can change
* the file limit at runtime and only root can increase the per-process
* nr_file rlimit, so it's safe to set up a ridiculously high absolute
* upper limit on files-per-process.
*
* Some programs (notably those using select()) may have to be
* recompiled to take full advantage of the new limits..
*/

/* Fixed constants first: */
#undef NR_OPEN
#define NR_OPEN (1024*1024) /* Absolute upper limit on fd num */
#define INR_OPEN 1024



gruss
christoph

Jasper
09.08.05, 12:09
Wie bekommt man das System soweit auf???? :confused:

in /etc/security/limits.conf das limit für den user hochsetzen und gleichzeitig den bereits geposteten proc-eintrag in /etc/sysctl.conf eintragen. der proc-eintrag ist der systemwert, also die summe über alle user-limits.


-j

7.e.Q
09.08.05, 12:12
Arbeitet das System grundsätzlich mit diesen beiden Dateien? Es handelt sich dabei nämlich um ein Linux From Scratch, das so absolut proprietär ist. Reicht es da, die beiden Dateien anzulegen? :confused:

Jasper
09.08.05, 16:52
/etc/security/limits.conf wird von pam_limit verwendet, /etc/sysctl.conf wird von sysctl verwendet. ansonsten halt 'ulimit -n 65536' ins startskript der applikation eintragen und den proc-eintrag per echo in rc.local setzen.


-j

7.e.Q
10.08.05, 06:55
Hilft nix. Anscheinend stößt er da an irgendein anderes Limit. accept() auf dem Socket meldet mir EAGAIN = Resource temporarily not available, sobald ich über eine bestimmte Anzahl Filedeskriptoren komme, und diese Anzahl ist unabhängig von ulimit -n. ulimit -n steht definitiv systemweit auf 4096, und wenn ich im /proc System in das Prozessverzeichnis schaue, mir die FDs darin ansehe, sie zähle, sind das nur 1026, zumeist, wenn der besagte Fehler auftritt.

Jasper
10.08.05, 07:44
Hilft nix. Anscheinend stößt er da an irgendein anderes Limit. accept() auf dem Socket meldet mir EAGAIN = Resource temporarily not available, sobald ich über eine bestimmte Anzahl Filedeskriptoren komme, und diese Anzahl ist unabhängig von ulimit -n. ulimit -n steht definitiv systemweit auf 4096, und wenn ich im /proc System in das Prozessverzeichnis schaue, mir die FDs darin ansehe, sie zähle, sind das nur 1026, zumeist, wenn der besagte Fehler auftritt.

ist der socket blocking or non-blocking? ich vermute, non-blocking. falls die connection queue leer ist und der socket non-blocking ist, liefert accept() EAGAIN zurück.


-j

7.e.Q
10.08.05, 08:01
Der Socket ist tatsächlich non-blocking, was sich aus meiner Position aber auch nicht ändern lässt. Merkwürdig ist, daß dieses Phänomen immer nur ab einer bestimmten Anzahl offener FDs auftritt.

Ich hab das non-blocking doch mal probehalber geändert, und der Effekt ist - wie erwartet - daß das Programm an der Stelle blockiert. Die ersten Verbindungen werden ja auch erfolgreich angenommen, auch von dem non-blocking Socket. Aber nach besagter Anzahl offener FDs geht das eben nicht mehr. Jetzt ist die Frage, warum das so ist. Wie gesagt, ulimit -n steht auf 4096. Auch für den Bereich, in dem das Programm läuft.

Jasper
10.08.05, 10:31
Ich hab das non-blocking doch mal probehalber geändert, und der Effekt ist - wie erwartet - daß das Programm an der Stelle blockiert. Die ersten Verbindungen werden ja auch erfolgreich angenommen, auch von dem non-blocking Socket. Aber nach besagter Anzahl offener FDs geht das eben nicht mehr. Jetzt ist die Frage, warum das so ist. Wie gesagt, ulimit -n steht auf 4096. Auch für den Bereich, in dem das Programm läuft.

du bekommst im blocking mode auch EAGAIN?


-j

7.e.Q
10.08.05, 10:33
Nein, das Programm blockiert dann an der Stelle, wie erwartet.

Jasper
10.08.05, 15:25
aehm, was ich meine ist: läuft dein test im blocking-mode ohne fehler durch, d.h. bekommst du mehr als die erwähnten 1026 offenen FDs?

EAGAIN tritt IMHO nur auf, wenn dein accept() kein connection-request in der queue vorfindet. allerdings ist das bei non-blocking der normalfall und wird über fehlerbehandlung abgefangen. insofern kann ich mir nicht so ganz vorstellen, wie deine applikationslogik aussieht. gib mal pseudocode falls vorhanden.
ich kann mir vorstellen, dass bei steigender last die connection-requests nicht schnell genug in der queue landen, allerdings dürften dann nur einzelne accept() EAGAIN zurückliefern und nicht alle.


-j

7.e.Q
11.08.05, 07:48
Nein, im Blocking-Mode bleibt accept() stehen, blockiert also, wie erwartet. Im Non-Blocking-Mode kehrt accept() bis zu besagter Grenze in der FD Anzahl immer ohne Fehler zurück (auch kein EAGAIN) und liefert einen verwendbaren Socket, schließt den Verbindungsaufbau also erfolgreich ab. Bis hin zu eben jener besagten, mir unerfindlichen Grenze.

Ein kleines von mir geschriebenes Dummy-Programm, das einfach stumpf Sockets aufmacht, schafft es bis zu 4093 Sockets aufzumachen (4096 FDs Maximum pro Prozess; 0, 1 und 2 bereits durch Standardkonsole belegt), bevor socket() fehlschlägt.

Warum kann unsere Software dann nur so wenig Verbindungen aufbauen? Wir brauchen mehr.

Die Sache ist leider sehr dringend!

7.e.Q
11.08.05, 11:19
Also die Begrenzung ist definitiv auf den Prozess beschränkt. Starten wir mehrere Prozesse, so haben alle Prozesse die gleiche Grenze. Wir könnten also mit 8 Prozessen jeweils maximal 250 Verbindungen aufbauen, bis der einzelne Prozess an seine Grenzen stößt. Trotzdem ist mir schleierhaft, wo diese Grenze liegt, da die maximale Anzahl offener Filedeskriptoren systemweit 4096, nicht 1024 beträgt. Wo kann die Grenze, die diesen Effekt hervorruft (accept kehrt mit -1 zurück, errno = EAGAIN) noch liegen?