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

そして、sutuationが再度繰り返され、rootユーザーとして約32kのスレッドを作成でき、非特権ユーザー(mongodまたはec2-user)として約1000作成できます。

これはrootユーザーの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) 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が無効になっています。この奇妙な問題を解決する方法がわかりません...おそらく、誰かがしますか?

回答:


12

あなたの問題はmax user processes限界です。

getrlimit(2)manページから:

RLIMIT_NPROC 呼び出しプロセスの実際のユーザーIDに対して作成できるプロセス(Linuxでは正確にはスレッド)の最大数。この制限にfork(2)達すると、エラーで失敗しますEAGAIN

同じpthread_create(3)

EAGAIN別のスレッドを作成するためのリソースが不十分であるか、またはスレッド数のシステムによる制限が発生しました。後者のケースは2つの方法で発生する可能性があります。実際のユーザーIDのプロセス数を制限するRLIMIT_NPROC(を介して設定されるsetrlimit(2))ソフトリソース制限に達した。または、スレッド数に関するカーネルのシステム全体の制限に/proc/sys/kernel/threads-max達しました。

ユーザーのその制限を増やし、他のリソース制限に達するまで、より多くのスレッドを作成できるはずです。
または、単純なリソース枯渇-1Mbスタックと20kスレッドの場合、大量のRAMが必要になります。NPTLが最大スレッド数を65528に制限する
ことも参照してください/proc/sys/vm/max_map_countある時点で問題になる可能性があります。

補足:の-pthread代わりに使用する必要があります-lpthreadコンパイル時の-pthreadフラグのgccの意味を参照してください。


0

mongoクライアント(java)からの接続の問題が中断されると、この問題が発生しました(AWSネットワークによると思われます)。TCP_KEEPALIVEが7200(2時間)に設定されている場合、接続プール内の接続はこの2時間のウィンドウ内で構築され、mongodが975の接続に到達すると停止します。

mongoプロダクションチェックリストは、はるかに短い時間(5分)のキープアライブを提案しています。接続制限の回避にも役立つ設定。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.