我们有一个4服务器ElasticSearch集群,每个服务器都有一个带有16GB ES_HEAP_SIZE的数据/客户端节点和一个带有4GB ES_HEAP_SIZE的专用主节点。对于总共8个节点,其中4个可以执行数据,4个仅作为主节点。每个主机都有24个内核,超线程关闭,256GB内存和超过1TB的SSD。我们通过服务方法运行带有CentOS 6.x 64位的ElasticSearch;从ElasticSearch的YUM repo(服务elasticsearch-node #start等)安装RPM。
问题是我们在数据和主节点上看似随机地出现OOM错误。它们每周发生约2或3次,并且不能直接归因于负载。我们希望为每个主机添加1个以上的数据节点和1个以上的客户端节点,每个主机具有16GB的ES_HEAP_SIZE,但尝试添加它们只会导致OOM几乎立即启动。
这些是错误:
java.lang.OutOfMemoryError: unable to create new native thread
我尝试在/ etc / security / limits中修改ulimit设置:
elasticsearch - nofile 65535
elasticsearch - memlock unlimited
但这没有效果,仍然是OOM,所以它被删除了。
然后我尝试在/ etc / sysconfig / elasticsearch-node#中将MAX_OPEN_FILES = 65535更改为MAX_OPEN_FILES = 262140,但它仍然是OOM'ed。
至于/ etc / sysconfig / elasticsearch-node#:
中的当前设置MAX_OPEN_FILES=65535
MAX_MAP_COUNT=262144
我将4个主机中的每个主机上的vm.swappiness设置为1,而不是启用mlockall。并且在我的sysctl中设置了vm.max_map_count = 262144。
我在elasticsearch启动脚本中添加了一些调试,该脚本将运行的ulimit(ulimit -a)写入文件:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 2066148
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 2066148
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
但我没有看到任何突出的东西。
启用了SElinux,但除了通过SSH或sudo登录时的通知外,审计日志中没有任何内容。
欢迎任何建议。
谢谢!
答案 0 :(得分:1)
错误消息:
java.lang.OutOfMemoryError: unable to create new native thread
表示您的java进程已达到可以启动的线程数限制。
现在,问题是,您的应用程序尝试启动的确切线程数。如果它在千万,这可能不是你想要的。如果它的线程数合理(例如100),可能是因为机器上的限制设置得太低而达到此限制?
阅读this文章了解详情。
另外,您可以在问题中包含以下内容的输出:
cat /proc/sys/kernel/threads-max
修改强>: 这是我为您编写的测试程序,用于查看您的进程线程限制。在你的盒子上运行它。
public class Test {
public static void main(String[] args) {
while(true){
new Thread(new Runnable(){
public void run() {
Thread thread = Thread.currentThread();
System.out.println("RunnableJob is being run by " + thread.getName() + " (" + thread.getId() + ")");
while(true) {
try {
Thread.sleep(100000);
} catch(Exception e) {
}
}
}
}).start();
try {
Thread.sleep(1);
} catch(Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
}