有足够的RAM和ulimits ElasticSearch OOM有问题

时间:2015-04-16 17:41:24

标签: java linux elasticsearch jvm

我们有一个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登录时的通知外,审计日志中没有任何内容。

欢迎任何建议。

谢谢!

1 个答案:

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

}