Linux最大线程数


8

我的服务器已在Amazon Ec2 linux上运行。我里面有一个mongodb服务器。mongodb服务器一直在高负载下运行,不幸的是,我遇到了问题:/

众所周知,mongodb会为每个客户端连接创建新线程,并且在此之前运行良好。我不知道为什么,但是MongoDB不能以非特权用户(在mongod用户下运行)在主机上创建超过975个连接。但是当我以root用户身份运行它时,它最多可以处理20000个连接(mongodb内部限制)。但是,进一步的调查表明,问题不是MongoDB服务器,而是Linux本身。

我找到了一个简单的程序,该程序检查最大连接数:

/* 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);
}

然后再次重复进行缝合,作为root用户,我可以创建约32k线程,作为非特权用户(mongod或ec2-user)可以创建约1000个线程。

这是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

这是mongod用户的ulimit:

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

内核最大线程数:

bash-4.1$ cat /proc/sys/kernel/threads-max 
118940

SELinux已禁用。不知道如何解决这个奇怪的问题...也许有人可以解决吗?

Answers:


12

你的问题是max user processes极限。

getrlimit(2)手册页:

RLIMIT_NPROC 可以为调用进程的真实用户ID创建的最大进程数(或更确切地说,在Linux上为线程)。遇到此限制时,将fork(2)失败并显示错误消息EAGAIN

相同pthread_create(3)

EAGAIN资源不足,无法创建另一个线程,或者遇到了系统施加的线程数限制。后一种情况可能以两种方式发生:达到了RLIMIT_NPROC限制setrlimit(2)实际用户ID的进程数量的软资源限制(通过设置);或达到了内核在系统范围内对线程数的限制/proc/sys/kernel/threads-max

为您的用户增加该限制,它应该能够创建更多线程,直到达到其他资源限制。
还是普通的资源耗尽-对于1Mb堆栈和20k线程,您将需要大量RAM。
也可以看看 NPTL将最大线程数限制为65528吗?/proc/sys/vm/max_map_count有时可能会成为问题。

观点:您应该使用-pthread而不是-lpthread编译时请参见gcc--pthread标志的重要性


0

当来自mongo客户端(java)的连接问题被中断(似乎是AWS网络)时,我们遇到了这个问题。将TCP_KEEPALIVE设置为7200(2小时)后,连接池中的连接将在2小时内建立,并且mongod达到975个连接时将死亡。

mongo生产清单建议您使用keepalives的时间要短得多(5分钟)。可以帮助您避免连接限制的设置。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.