Ser*_*kov 8 linux multithreading
我的服务器一直在运行 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);
}
Run Code Online (Sandbox Code Playgroud)
并且再次重复这种情况,作为 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
Run Code Online (Sandbox Code Playgroud)
这是 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
Run Code Online (Sandbox Code Playgroud)
内核最大线程数:
bash-4.1$ cat /proc/sys/kernel/threads-max
118940
Run Code Online (Sandbox Code Playgroud)
SELinux 被禁用。不知道如何解决这个奇怪的问题......可能有人会吗?
Mat*_*Mat 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 标志的意义。
归档时间: |
|
查看次数: |
27448 次 |
最近记录: |