1. 程式人生 > >Elasticsearch5.4常見問題總結

Elasticsearch5.4常見問題總結

pan tran ddt pool 添加 需要 pri eric 操作


  最近項目中用到了Elasticsearch5.4(ES)是比較新的一個版本,使用的過程中出現了很多的問題,很是頭疼,但是問題最終還是解決掉了。

問題一:ESClient獲取慢,並且不能獲取Client:failed to create a child event loop

  由於業務的需要沒上傳一批文件都要加一次ES索引,每加一次索引都要獲取連接然後操作,尤其是大批量的時候,獲取的次數顯然非常多,而且出現這個問題的主要原因在於我們在循環頻繁的操作ES,比如一批文件100個,我們就要獲取100次,為了降低ES Client獲取的時間,最終采取了一個方案,那就是在服務啟動的時候初始化連接,一次性獲取,然後在後邊直接調用,整個批次文件上傳完成後,最後添加ES索引,而不是一個文件一個文件的去添加了。這種方式顯然不需要每個批次都獲取連接,大大提升了執行效率。


首先,我們在服務啟動的時候,在啟動類中初始化靜態ES Client:

private static ElasticSearchUtil ElasticSearchUtil=new ElasticSearchUtil();

public static TransportClient client=ElasticSearchUtil.getClient();

然後在用到的時候直接調用:
Client client=Main.client;
這樣可以大大減少ES Client的連接次數,從而提升效率。
ES代碼如下:

public TransportClient getClient() {
String[] ipArr 
= configUtil.getValue("ESIP").split(","); Settings settings = Settings.builder().put("thread_pool.generic.core",5)     .put("thread_pool.generic.max", 10)     .put("processors", 5)     .put(Constants.ESCLUSTERNAME,configUtil.getValue("clusterName")).build();


TransportClient client
= new PreBuiltTransportClient(settings);
for (String ip : ipArr) { TransportAddress address = new InetSocketTransportAddress   (InetAddresses.forString(ip),9300); client.addTransportAddresses(address); }   return client; }

問題2:內存溢出:java.lang.OutOfMemory:unable to create new native thread

  在項目開發過程中,發生內存溢出是很讓人頭疼的一件事,在使用ES的過程中,就遇到了,而且很頻繁,尤其是在大批量壓力測試的時候根本進行不下去,從jvm內存調優方面想了很多辦法,沒有什麽效果,問題依然得不到解決,最後在看源碼的時候,發現了一個原因,和報錯異常結合來看,這是由與ES在使用過程中,自動創建了大量的線程,超出了系統的容納量,所以導致了內存溢出,研究源碼的時候發現:ES創建的線程數是可以通過設置來控制的。下面是默認的ES創建線程數:

thread_pool.generic.core=默認值---4
thread_pool.generic.max=默認值--
min(512,max(4*processor數,128))
processor數=CPU的processor數

  我們的CPU是10核40線程
  從計算結果來看,如果使用默認值的話,ES可以創建的線程數是一個很大的數值,這遠遠超出了系統本身的容納數,主要是調整setting的數值,經過調整,我們將ES的默認值改變如下:

Settings settings = Settings.builder().put("thread_pool.generic.core",5)
.put("thread_pool.generic.max", 10)
.put("processors", 5)    .put(Constants.ESCLUSTERNAME,configUtil.getValue("clusterName")).build();
這是之前的
Settings settings = Settings.builder().put("thread_pool.generic.core",5)
.put(Constants.ESCLUSTERNAME,configUtil.getValue("clusterName")).build();

經過測試,ES創建了很少的線程數,並且滿足我們的開發需求,再也沒有出現過內存溢出的問題了。

Elasticsearch5.4常見問題總結