mon serveur fonctionne avec Amazon Ec2 linux. J'ai un serveur mongodb à l'intérieur. Le serveur mongodb fonctionne sous une charge importante et, malheureusement, je suis tombé sur un problème avec lui: /
Comme on le sait, le mongodb crée un nouveau thread pour chaque connexion client, et cela fonctionnait bien avant. Je ne sais pas pourquoi, mais MongoDB ne peut pas créer plus de 975 connexions sur l'hôte en tant qu'utilisateur non privilégié (il fonctionne sous un utilisateur mongod). Mais lorsque je l'exécute en tant qu'utilisateur root, il peut gérer jusqu'à 20000 connexions (limite interne mongodb). Mais, de nouvelles investigations montrent que ce problème n'est pas le serveur MongoDB, mais un Linux lui-même.
J'ai trouvé un programme simple, qui vérifie le nombre maximum de connexions:
/* 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);
}
Et la sutuation est répétée à nouveau, en tant qu'utilisateur root, je peux créer environ 32k threads, en tant qu'utilisateur non privilégié (mongod ou ec2-user) autour de 1000.
Ceci est un ulimit pour l'utilisateur root:
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
Ceci est un ulimit pour l'utilisateur mongod:
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
Nombre maximal de threads du noyau:
bash-4.1$ cat /proc/sys/kernel/threads-max
118940
SELinux est désactivé. Je ne sais pas comment résoudre cet étrange problème ... Peut-être que quelqu'un le fait?