生產環境使用elasticsearch遇到的一些問題以及解決方法(不斷更新)
阿新 • • 發佈:2019-01-05
1.由gc引起節點脫離叢集
因為gc時會使jvm停止工作,如果某個節點gc時間過長,master ping3次(zen discovery預設ping失敗重試3次)不通後就會把該節點剔除出叢集,從而導致索引進行重新分配。
解決方法:
(1)優化gc,減少gc時間。(2)調大zen discovery的重試次數(es引數:ping_retries)和超時時間(es引數:ping_timeout)。後來發現根本原因是有個節點的系統所在硬碟滿了。導致系統性能下降。
2.out of memory錯誤
因為預設情況下es對欄位資料快取(Field Data Cache)大小是無限制的,查詢時會把欄位值放到記憶體,特別是facet查詢,對記憶體要求非常高,它會把結果都放在記憶體,然後進行排序等操作,一直使用記憶體,直到記憶體用完,當記憶體不夠用時就有可能出現out of memory錯誤。
解決方法:
(1)設定es的快取型別為Soft Reference,它的主要特點是據有較強的引用功能。只有當記憶體不夠的時候,才進行回收這類記憶體,因此在記憶體足夠的時候,它們通常不被回收。另外,這些引 用物件還能保證在Java丟擲OutOfMemory 異常之前,被設定為null。它可以用於實現一些常用圖片的快取,實現Cache的功能,保證最大限度的使用記憶體而不引起OutOfMemory。在es的配置檔案加上index.cache.field.type:
soft即可。
(2)設定es最大快取資料條數和快取失效時間,通過設定index.cache.field.max_size: 50000來把快取field的最大值設定為50000,設定index.cache.field.expire: 10m把過期時間設定成10分鐘。
3.無法建立本地執行緒問題
es恢復時報錯: RecoverFilesRecoveryException[[index][3] Failed to transfer [215] files with total size of [9.4gb]]; nested: OutOfMemoryError[unable to create new native thread]; ]]
剛開始以為是檔案控制代碼數限制,但想到之前報的是too many open file這個錯誤,並且也把資料改大了。查資料得知一個程序的jvm程序的最大執行緒數為:虛擬記憶體/(堆疊大小*1024*1024),也就是說虛擬記憶體越大或堆疊越小,能建立的執行緒越多。重新設定後還是會報那這錯,按理說可建立執行緒數完全夠用了的,就想是不是系統的一些限制。後來在網上找到說是max user processes的問題,這個值預設是1024,這個引數單看名字是使用者最大開啟的程序數,但看官方說明,就是使用者最多可建立執行緒數,因為一個程序最少有一個執行緒,所以間接影響到最大程序數。調大這個引數後就沒有報這個錯了。
解決方法:
(1)增大jvm的heap記憶體或降低xss堆疊大小(預設的是512K)。
(2)開啟/etc/security/limits.d/90-nproc.conf,把soft nproc 1024這行的1024改大就行了。
4.叢集狀態為黃色時併發插入資料報錯
[7]: index [index], type [index], id [1569133], message [UnavailableShardsException[[index][1] [4] shardIt, [2] active : Timeout waiting for [1m], request: [email protected]]]
這是錯誤資訊,當時叢集狀態為黃色,即副本沒有分配。當時副本設定為2,只有一個節點,當你設定的副本大於可分配的機器時,此時如果你插入資料就有可能報上面的錯,因為es的寫一致性預設是使用quorum,即quorum值必須大於(副本數/2+1),我這裡2/2+1=2也就是說要要至少插入到兩份索引中,由於只有一個節點,quorum等於1,所以只插入到主索引,副本找不到從而報上面那個錯。
解決方法:(1)去掉沒分配的副本。(2)把寫一致性改成one,即只寫入一份索引就行。
5.設定jvm鎖住記憶體時啟動警告
當設定bootstrap.mlockall: true時,啟動es報警告Unknown mlockall error 0,因為linux系統預設能讓程序鎖住的記憶體為45k。
解決方法:設定為無限制,linux命令:ulimit -l unlimited
6.錯誤使用api導致叢集卡死
其實這個是很低階的錯誤。功能就是更新一些資料,可能會對一些資料進行刪除,但刪除時同事使用了deleteByQuery這個介面,通過構造BoolQuery把要刪除資料的id傳進去,查出這些資料刪除。但問題是BoolQuery最多隻支援1024個條件,100個條件都已經很多了,所以這樣的查詢一下子就把es叢集卡死了。
解決方法:用bulkRequest進行批量刪除操作。
7.org.elasticsearch.transport.RemoteTransportException: Failed to deserialize exception response from stream
原因:es節點之間的JDK版本不一樣
解決方法:統一JDK環境
參考資料:
參考資料: