Số lượng chủ đề tối đa của Linux


8

máy chủ của tôi đã chạy với Amazon Ec2 linux. Tôi có một máy chủ mongodb bên trong. Máy chủ mongodb đã chạy quá tải, và thật không may, tôi đã gặp phải sự cố với nó: /

Như đã biết, mongodb tạo ra luồng mới cho mọi kết nối máy khách và điều này đã hoạt động tốt trước đó. Tôi không biết tại sao, nhưng MongoDB không thể tạo hơn 975 kết nối trên máy chủ với tư cách là người dùng không có đặc quyền (nó chạy dưới một người dùng mongod). Nhưng khi tôi chạy nó với tư cách là người dùng root, nó có thể xử lý tới 20000 kết nối (giới hạn bên trong mongodb). Nhưng, các nghiên cứu sâu hơn cho thấy, vấn đề đó không phải là máy chủ MongoDB, mà là bản thân linux.

Tôi đã tìm thấy một chương trình đơn giản, kiểm tra số lượng kết nối tối đa:

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

Và khâu được lặp lại một lần nữa, với tư cách là người dùng root, tôi có thể tạo khoảng 32k luồng, với tư cách là người dùng không có đặc quyền (người dùng mongod hoặc ec2) khoảng 1000.

Đây là một ulimit cho người dùng 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

Đây là một ulimit cho người dùng 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

Chủ đề tối đa hạt nhân:

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

SELinux bị vô hiệu hóa. Không biết làm thế nào để giải quyết vấn đề kỳ lạ này ... Có thể, có ai đó không?

Câu trả lời:


12

Vấn đề của bạn là max user processesgiới hạn.

Từ getrlimit(2)trang người đàn ông:

RLIMIT_NPROC Số lượng tiến trình tối đa (hoặc chính xác hơn là trên Linux, các luồng) có thể được tạo cho ID người dùng thực của quá trình gọi. Khi gặp giới hạn này, fork(2)không thành công với lỗi EAGAIN.

Tương tự cho pthread_create(3):

EAGAINKhông đủ tài nguyên để tạo một luồng khác hoặc giới hạn áp đặt của hệ thống đối với số lượng luồng đã gặp phải. Trường hợp thứ hai có thể xảy ra theo hai cách: đã đạt đến RLIMIT_NPROCgiới hạn tài nguyên mềm (được đặt qua setrlimit(2)), giới hạn số lượng quy trình cho ID người dùng thực; hoặc giới hạn toàn hệ thống của kernel về số lượng luồng /proc/sys/kernel/threads-max, đã đạt được.

Tăng giới hạn đó cho người dùng của bạn và nó sẽ có thể tạo thêm các luồng cho đến khi đạt đến các giới hạn tài nguyên khác.
Hoặc cạn kiệt tài nguyên đơn giản - đối với ngăn xếp 1Mb và luồng 20k, bạn sẽ cần rất nhiều RAM.
Xem thêm NPTL mũ tối đa chủ đề tại 65528? : /proc/sys/vm/max_map_countcó thể trở thành một vấn đề tại một số điểm.

Điểm phụ: bạn nên sử dụng -pthreadthay vì -lpthread. Xem gcc - tầm quan trọng của cờ -pthread khi biên dịch .


0

Chúng tôi gặp vấn đề này khi sự cố kết nối từ máy khách mongo (java) bị gián đoạn (có vẻ như do mạng AWS). Với TCP_KEEPALIVE được đặt thành 7200 (2 giờ), các kết nối trong nhóm kết nối sẽ tích hợp trong cửa sổ 2 giờ này và mongod sẽ chết khi chạm 975 kết nối.

Danh sách kiểm tra sản xuất mongo cho thấy các khoản giữ thời gian thấp hơn nhiều (5 phút); cũng sẽ giúp bạn tránh giới hạn kết nối.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.