Mein Server wurde mit Amazon Ec2 Linux ausgeführt. Ich habe einen Mongodb-Server im Inneren. Der Mongodb-Server wurde stark ausgelastet, und leider bin ich auf ein Problem damit gestoßen: /
Wie bekannt, erstellt der Mongodb für jede Clientverbindung einen neuen Thread, und dies hat zuvor einwandfrei funktioniert. Ich weiß nicht warum, aber MongoDB kann nicht mehr als 975 Verbindungen auf dem Host als nicht privilegierter Benutzer erstellen (es läuft unter einem Mongod-Benutzer). Aber wenn ich es als Root-Benutzer ausführe, kann es bis zu 20000 Verbindungen verarbeiten (internes Mongodb-Limit). Weitere Untersuchungen zeigen jedoch, dass dieses Problem nicht der MongoDB-Server ist, sondern ein Linux selbst.
Ich habe ein einfaches Programm gefunden, das die maximale Anzahl von Verbindungen überprüft:
/* compile with: gcc -lpthread -o thread-limit thread-limit.c */
/* originally from: http://www.volano.com/linuxnotes.html */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#define MAX_THREADS 100000
#define PTHREAD_STACK_MIN 1*1024*1024*1024
int i;
void run(void) {
sleep(60 * 60);
}
int main(int argc, char *argv[]) {
int rc = 0;
pthread_t thread[MAX_THREADS];
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN);
printf("Creating threads ...\n");
for (i = 0; i < MAX_THREADS && rc == 0; i++) {
rc = pthread_create(&(thread[i]), &thread_attr, (void *) &run, NULL);
if (rc == 0) {
pthread_detach(thread[i]);
if ((i + 1) % 100 == 0)
printf("%i threads so far ...\n", i + 1);
}
else
{
printf("Failed with return code %i creating thread %i (%s).\n",
rc, i + 1, strerror(rc));
// can we allocate memory?
char *block = NULL;
block = malloc(65545);
if(block == NULL)
printf("Malloc failed too :( \n");
else
printf("Malloc worked, hmmm\n");
}
}
sleep(60*60); // ctrl+c to exit; makes it easier to see mem use
exit(0);
}
Und die Sutuation wird noch einmal wiederholt, als Root-Benutzer kann ich ungefähr 32k Threads erstellen, als nicht privilegierter Benutzer (Mongod oder Ec2-Benutzer) ungefähr 1000.
Dies ist ein Ulimit für Root-Benutzer:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 59470
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 60000
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Dies ist ein Ulimit für Mongod-Benutzer:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 59470
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 60000
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 1024
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Kernel max Threads:
bash-4.1$ cat /proc/sys/kernel/threads-max
118940
SELinux ist deaktiviert. Sie wissen nicht, wie Sie dieses seltsame Problem lösen sollen ... Möglicherweise tut es jemand?
quelle