2017-06-21 82 views
0

我们使用elasticsearch REST Java客户端(我们在Java 7中,因此无法使用普通的elasticsearch Java客户端)与我们的elasticsearch服务器进行交互。除了当我们试图对大约130万个文档进行初始索引时,这一切都可以正常工作。这将运行了一段时间,但我们已经看到了弹性搜索的OutOfMemoryError REST Java客户端通过apache http nio

20/06 21:27:33,153 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) Exception in thread "pool-837116-thread-1" java.lang.OutOfMemoryError: unable to create new native thread 
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at java.lang.Thread.start0(Native Method) 
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at java.lang.Thread.start(Thread.java:693) 
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:334) 
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:194) 
20/06 21:27:33,154 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64) 
20/06 21:27:33,155 ERROR [cid=51][stderr][write:71] (pool-837116-thread-1) at java.lang.Thread.run(Thread.java:724) 

跟在后面几十万的文件被

java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STOPPED 
    at org.apache.http.util.Asserts.check(Asserts.java:46) 
    at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase.ensureRunning(CloseableHttpAsyncClientBase.java:90) 
    at org.apache.http.impl.nio.client.InternalHttpAsyncClient.execute(InternalHttpAsyncClient.java:123) 
    at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:343) 
    at org.elasticsearch.client.RestClient.performRequestAsync(RestClient.java:325) 
    at org.elasticsearch.client.RestClient.performRequest(RestClient.java:218) 
    at org.elasticsearch.client.RestClient.performRequest(RestClient.java:191) 

正如你可以看到Elasticsearch REST客户端使用的Apache HTTP NIO。我发现奇怪的是,nio库正在为每个请求(或连接?)创建一个线程。从上面的日志可以看到线程(pool-837116-thread-1)。还有很多I/O调度程序线程数量越来越多。

虽然活动线程的总数似乎没有太大变化。 因此,似乎并非重复使用线程(或实际上是)为每个连接周期创建新线程。 上传基本上是: 1.创建客户

restClient = RestClient.builder(new HttpHost(host.getHost(),host.getPort(),host.getProtocol())/*,new HttpHost(host.getHost(),host.getPort()+1,host.getProtocol())*/) 
          .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 
           @Override 
           public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 
            return httpClientBuilder 
              .setDefaultCredentialsProvider(credsProvider) 
                       } 
          }).setMaxRetryTimeoutMillis(30000).build(); 
  • 使用JSON体和靠近客户

    尝试{ HttpEntity实体=新NStringEntity(JSON

    发送请求,ContentType.APPLICATION_JSON); 响应indexResponse = restClient.performRequest(“PUT”,endpoint,parameters,entity,header); log.debug(“Response#0#1”,indexResponse,indexResponse.getStatusLine()); log.debug(“Entity#0”,indexResponse.getEntity());

    }finally{ 
         if(restClient!=null){ 
          log.debug("Closing restClient #0", restClient); 
          restClient.close(); 
         } 
        } 
    
  • 这是正常的吗?为什么不是apache nio重用线程?这是弹性搜索REST客户端,apache nio或我的代码的问题吗?我打电话给restClient,不知道我该怎么做。

    我试图设置线程数减少到1个在IO反应堆:

    restClient = RestClient.builder(new HttpHost(host.getHost(),host.getPort(),host.getProtocol())/*,new HttpHost(host.getHost(),host.getPort()+1,host.getProtocol())*/) 
              .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { 
               @Override 
               public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { 
                return httpClientBuilder 
                  .setDefaultCredentialsProvider(credsProvider) 
                  .setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(1).build()); //set to one thread 
               } 
              }).setMaxRetryTimeoutMillis(30000).build(); 
    

    但对于线程的重用并没有改变任何东西。

    +0

    您是使用批量插入还是逐一插入? – jvwilge

    +0

    我找到了OutOfMemoryError的原因。虽然我正在使用try - finally块来关闭客户端,但在该块之外抛出一个异常(块没有涵盖所有的东西哦)。但看起来错误的是创建了这么多的线程(虽然整个线程的数量并没有显着增加)。 – Ben

    +0

    这是一个一个插入,因为我需要确保上传每个数据。它使用与正常索引相同的机制。 – Ben

    回答

    0

    我找到了OutOfMemoryError的原因。虽然我正在使用try - finally块来关闭客户端,但在该块之外抛出一个异常(块没有涵盖所有的东西哦)。但看起来错误的是创建了这么多的线程(虽然整个线程的数量并没有显着增加)。

    相关问题