Elasticsearch5.4常見問題總結
最近項目中用到了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常見問題總結