前言
ES雖然具有較高的性能境输,同樣也比較吃資源,通常調(diào)整節(jié)點(diǎn)內(nèi)存大小禾锤,基本能解決ES常見的性能問(wèn)題
提示:以下是本篇文章正文內(nèi)容
ES性能優(yōu)化之內(nèi)存優(yōu)化
一垛玻、調(diào)整節(jié)點(diǎn)內(nèi)存大小
修改ES節(jié)點(diǎn)實(shí)例GC參數(shù)(Xms)和最大(Xmx)內(nèi)存大小,并且保持值一致泽谨,重啟Elasticsearch服務(wù)璧榄。
單個(gè)EsNode實(shí)例 看具體服務(wù)器內(nèi)存大小調(diào)整,最大推薦31G左右吧雹,不要超過(guò)32G骨杂。
如果EsMaster也有組件或業(yè)務(wù)連接,也需要調(diào)大GC參數(shù)雄卷,不然會(huì)導(dǎo)致內(nèi)存溢出搓蚪,不推薦業(yè)務(wù)連接EsMaster實(shí)例節(jié)點(diǎn)
二、禁用Swapping
大多數(shù)操作系統(tǒng)都盡可能多地為文件系統(tǒng)緩存使用內(nèi)存龙亲,并切換出未使用的應(yīng)用程序內(nèi)存陕凹。這可能導(dǎo)致部分JVM堆被交換到磁盤上悍抑。
對(duì)于性能和節(jié)點(diǎn)的穩(wěn)定性來(lái)說(shuō)鳄炉,這種交換是非常糟糕的,應(yīng)該不惜一切代價(jià)避免搜骡。它可能導(dǎo)致垃圾收集持續(xù)幾分鐘而不是幾毫秒拂盯,這可能導(dǎo)致節(jié)點(diǎn)響應(yīng)緩慢,甚至脫離集群记靡。
Linux/Unix系統(tǒng)中使用mlockall在RAM中鎖定進(jìn)程的地址空間谈竿,阻止Elasticsearch內(nèi)存被交換出去,從而實(shí)現(xiàn)禁用Swapping摸吠。
禁用方式:1. Es使用的服務(wù)器安裝操作系統(tǒng)時(shí)空凸,也不要開啟或配置swap分區(qū)。
2.Elasticsearch > 配置 > 自定義”寸痢。
3.添加新的參數(shù)“bootstrap.memory_lock”呀洲,設(shè)置值為“true”,保存配置并重啟Elasticsearch服務(wù)啼止。
4.使用root用戶登錄任意Elasticsearch數(shù)據(jù)節(jié)點(diǎn)道逗,執(zhí)行如下命令驗(yàn)證是否修改成功。執(zhí)行命令后結(jié)果顯示包含“true”則表示修改成功献烦。
curl -XGET --tlsv1.2 --negotiate -k -u : “https://ip:httpport/_nodes?filter_path=**.mlockall”
三滓窍、垃圾回收器調(diào)整(參考)
配置垃圾回收器,避免內(nèi)存交換巩那,記錄垃圾回收行為日志吏夯,診斷故障
1
JVM內(nèi)存空間主要分為以下區(qū)域:
Eden區(qū)
初次分配的大部分對(duì)象都在該區(qū)域
1
Survivor區(qū)
分為 0區(qū) 和 1區(qū)此蜈,對(duì)Eden區(qū)進(jìn)行垃圾回收仍然存活的對(duì)象
1
老年代
存儲(chǔ)在Survivor區(qū)存貨較長(zhǎng)時(shí)間的對(duì)象
1
持久代
非堆空間,存儲(chǔ)所有JVM自身的數(shù)據(jù)锦亦,如 java類舶替,對(duì)象方法等
1
代碼緩存區(qū)
用來(lái)編譯,存放本地原生代碼
1
3.1打開垃圾回收日志
ElasticSearch.yml配置文件中杠园,默認(rèn)被注釋掉了:
指定了3中日志級(jí)別顾瞪,并分別指定了閾值。
以info級(jí)別的日志配置為例:
如果年輕代垃圾回收過(guò)程耗時(shí)到達(dá)或超過(guò)700毫秒抛蚁,ES就會(huì)寫日志文件陈醒;
如果老年代垃圾回收過(guò)程耗時(shí)到達(dá)或超過(guò)5秒,也會(huì)記錄瞧甩。
日志文件記錄類似如下:
上面日志是關(guān)于ConcurrentMarkSweep垃圾回收器的钉跷,也就是說(shuō),它是關(guān)于老年代的垃圾回收的肚逸。從中可以看出:
總的回收時(shí)間是14.8秒爷辙;在回收前,總共11.9GB空間中有8.6GB被占用朦促,回收后膝晾,被占用空間減少到3.4GB;
接下來(lái)是更詳細(xì)的統(tǒng)計(jì)信息务冕,用來(lái)確定堆內(nèi)存中的各個(gè)部分如代碼緩存區(qū)血当,Eden區(qū),Survivor區(qū)禀忆,老年代臊旭,持久代等的回收處理情況。
3.2使用jstat 檢查垃圾回收器工作狀態(tài)
jstat -gcutil 123456 2000 1000
-gcutil 告知jstat監(jiān)控垃圾回收器工作狀態(tài)箩退;
123456用于表示ES所在的JVM离熏;
2000 表示抽樣間隔,單位是毫秒戴涝;
1000 表示抽樣數(shù)滋戳;
以上例子執(zhí)行耗時(shí)為 33 分鐘(2000*1000/1000/60)
·S0:表示survivor 0區(qū)的使用率,用百分比表示喊括。
·S1:表示survivor 1區(qū)的使用率胧瓜,用百分比表示。
·E:表示Eden區(qū)的使用率郑什,用百分比表示府喳。
·O:表示年老代的使用率,用百分比表示蘑拯。
·YGC:表示年輕代垃圾回收事件的次數(shù)钝满。
·YGCT:表示年輕代垃圾回收耗時(shí)兜粘,單位為秒。
·FGC:表示年老代垃圾回收事件的次數(shù)弯蚜。
·FGCT:表示年老代垃圾回收耗時(shí)孔轴,單位為秒。
·GCT:表示垃圾回收總耗時(shí)碎捺。
現(xiàn)在回到剛才的示例路鹰。如你所見,在第三和第四次抽樣之間JVM對(duì)年輕代執(zhí)行了一次垃圾回收收厨,此次操作耗時(shí)0.001秒(第四次抽樣的YGCT是0.177晋柱,第三次抽樣的YGCT是0.176,兩次YGCT之差為0.001)诵叁。同時(shí)我們可以看到雁竞,Eden區(qū)使用率從83.7%變?yōu)?%,而年老代使用率從9.49%上升為9.51%拧额,這是因?yàn)榇舜尾僮髦幸恍?duì)象從Eden區(qū)遷移到了年老代碑诉。這個(gè)示例同時(shí)也展示了如何對(duì)jstat的輸出進(jìn)行分析。當(dāng)然侥锦,分析工作比較費(fèi)時(shí)进栽,也需要你了解垃圾回收器是如何工作以及明白堆中都存放了什么。盡管如此捎拯,這可能是ElasticSearch故障時(shí)你能用的唯一方法泪幌。
如果你遇到以下情況盲厌,ElasticSearch運(yùn)行不正常署照,或者S0、S1吗浩、E列的值達(dá)到100%建芙,并且垃圾回收工作對(duì)這些堆空間不起作用,那么原因可能是:年輕代太小了懂扼,你需要把它調(diào)大一些(當(dāng)然禁荸,前提是擁有足夠的物理內(nèi)存);內(nèi)存出問(wèn)題了阀湿,比如說(shuō)因?yàn)橐恍┵Y源沒有釋放占用的內(nèi)存而導(dǎo)致內(nèi)存泄露赶熟。還有一種情況,如果年老代使用率達(dá)到100%且垃圾回收器多次嘗試仍無(wú)法釋放它的空間陷嘴,這大概意味著沒有足夠的堆空間讓ElasticSearch節(jié)點(diǎn)正常運(yùn)作了映砖。此時(shí),如果你不想改變索引結(jié)構(gòu)灾挨,就只能通過(guò)增大運(yùn)行ElasticSearch的JVM的堆空間來(lái)解決了(更多JVM參數(shù)信息請(qǐng)參考:http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)邑退。
1.3生成Memory Dump
JVM還擁有把堆空間轉(zhuǎn)儲(chǔ)到文件的能力竹宋。Java允許我們獲取特定時(shí)間點(diǎn)的一個(gè)內(nèi)存快照,并通過(guò)分析快照的存儲(chǔ)內(nèi)容地技,從而發(fā)現(xiàn)問(wèn)題蜈七。你可以使用jmap命令(http://docs.oracle.com/javase/7/docs/technotes/tools/share/jmap.html)去轉(zhuǎn)儲(chǔ)Java進(jìn)程的內(nèi)存。Jmap命令示例如下:
jmap -dump:file=heap.dump 123456
123456表示需要轉(zhuǎn)儲(chǔ)的Java進(jìn)程號(hào)莫矗。
-dump:file=heap.dump指定轉(zhuǎn)儲(chǔ)的目標(biāo)文件為heap.dump飒硅。
我們可以通過(guò)一些特殊的軟件進(jìn)一步分析轉(zhuǎn)儲(chǔ)文件,如jhat(http://docs.oracle.com/javase/7/docs/technotes/tools/share/jhat.html)作谚。
3.3垃圾回收器調(diào)優(yōu)
然而狡相,如果你想了解更多關(guān)于垃圾回收器的信息,如它有哪些選項(xiàng)以及這些選項(xiàng)如何作用到你的程序食磕,建議閱讀這篇偉大的文章:http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html尽棕。盡管該文章是關(guān)于Java 6的,但其中提及的絕大部分選項(xiàng)對(duì)Java 7應(yīng)用同樣適用彬伦。
謹(jǐn)記一件事:盡可能進(jìn)行多次輕量級(jí)垃圾回收操作滔悉,而不是一次性、耗時(shí)很長(zhǎng)的垃圾回收操作单绑。因?yàn)楸3諩lasticSearch程序性能的穩(wěn)定性是第一位的回官,對(duì)ElasticSearch來(lái)說(shuō),垃圾回收應(yīng)該是透明的搂橙。一次重大的垃圾回收操作會(huì)停止全局的垃圾回收事件歉提,在短時(shí)間內(nèi)凍結(jié)ElasticSearch的工作,從而使查詢變慢且短期無(wú)法執(zhí)行索引操作区转。
1.4調(diào)整ElasticSearch中垃圾回收器的工作方式
我們已經(jīng)知道了垃圾回收器如何工作苔巨,也明白了如何診斷垃圾回收過(guò)程中的故障,接下來(lái)可以探討一下如何通過(guò)修改ElasticSearch啟動(dòng)參數(shù)來(lái)調(diào)整垃圾回收器的工作方式废离。參數(shù)的修改方式視ElasticSearch的運(yùn)行方式而定侄泽,目前常見的有兩種:
一種是使用ElasticSearch發(fā)行包自帶的標(biāo)準(zhǔn)啟動(dòng)腳本,
另一種是使用服務(wù)包裝器(service wrapper)蜻韭。
1.4.1 使用標(biāo)準(zhǔn)啟動(dòng)腳本
為了添加額外的JVM參數(shù)悼尾,我們需要把它們加入JAVA_OPTS環(huán)境變量中。例如肖方,要給Linux環(huán)境下的ElasticSearch添加-XX:+UseParNewGC -XX:+UseConcMarkSweepGC啟動(dòng)參數(shù)闺魏,需要執(zhí)行如下命令:
export JAVA_OPTS="-XX:+UseParNewGC -XX:+UseConcMarkSweepGC"
執(zhí)行如下命令以確定參數(shù)是否添加成功:
echo $JAVA_OPTS
在本例中,應(yīng)該會(huì)有如下輸出:
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC
1.4.2 使用服務(wù)包裝器
可以使用Java服務(wù)包裝器(https://github.com/ElasticSearch/ElasticSearch-servicew-rapper)把ElasticSearch包裝成服務(wù)俯画。這種給ElasticSearch添加啟動(dòng)參數(shù)的方法與使用標(biāo)準(zhǔn)啟動(dòng)腳本的方法不同析桥。
我們所需要做的是修改elasticsearch.conf文件,該文件一般位于/opt/ElasticSearch/bin/service/目錄下(如果ElasticSearch安裝目錄是/opt/ElasticSearch)。文件中包含了以下屬性:
第一行負(fù)責(zé)設(shè)置ElasticSearch的堆空間大小烹骨,之后的其他行是附加JVM參數(shù)翻伺。如果需要添加其他參數(shù),只需新增一行wrapper.java.additional沮焕,后面緊跟下一個(gè)可用數(shù)字吨岭,例如:
wrapper.java.additional.10=-server
垃圾回收調(diào)優(yōu)并不是一件一勞永逸的事情。它需要反復(fù)試驗(yàn)峦树,因?yàn)檎{(diào)優(yōu)結(jié)果嚴(yán)重依賴于你的數(shù)據(jù)辣辫、查詢和各種組合環(huán)境。在ElasticSearch出故障的時(shí)候要勇于改變和調(diào)優(yōu)魁巩,在做出改變后也要繼續(xù)觀察急灭、監(jiān)控ElasticSearch的運(yùn)行狀況。
總結(jié)
ES調(diào)整節(jié)點(diǎn)內(nèi)存大小基本可以解決大部分問(wèn)題