100_es生產(chǎn)集群部署之jvm和服務(wù)器內(nèi)存分配的最佳實踐以及原理分析

100_es生產(chǎn)集群部署之jvm和服務(wù)器內(nèi)存分配的最佳實踐以及原理分析

除了之前講解的一些配置孽江,根據(jù)你的集群環(huán)境特殊的配置讶坯,我們這一講來講解最重要的內(nèi)存的分配,提出一些問題岗屏,生產(chǎn)環(huán)境部署es辆琅,不可避免要回答一個問題漱办,比如我的機器上有64G的內(nèi)存,或者32G的內(nèi)存婉烟,那么一般來說我應(yīng)該分配多少個G的內(nèi)存給es的jvm heap

1娩井、jvm heap分配

es默認會給jvm heap分配2個G的大小,對于幾乎所有的生產(chǎn)環(huán)境來說隅很,這個內(nèi)存都太小了撞牢。如果用這個默認的heap size率碾,那么生產(chǎn)環(huán)境的集群肯定表現(xiàn)不會太好叔营。

有兩個方式來調(diào)節(jié)es中的jvm heap size。最簡單的就是設(shè)置環(huán)境變量所宰,ES_HEAP_SIZE绒尊。當(dāng)es進程啟動的時候,會讀取這個環(huán)境變量的值仔粥,然后設(shè)置為jvm的heap size婴谱。舉例來說,可以這樣來設(shè)置:export ES_HEAP_SIZE=10g躯泰。此外谭羔,還可以在啟動es進程的時候,傳遞一個jvm的option麦向,比如:ES_JAVA_OPTS="-Xms10g -Xmx10g" ./bin/elasticsearch瘟裸,但是要注意-Xms和-Xmx最小和最大堆內(nèi)存一定設(shè)置的一樣,避免運行過程中的jvm heap resize诵竭,那會是一個非常耗時的過程话告。

在老版本的es中,比如es 2.x里面卵慰,一般推薦用ES_HEAP_SIZE環(huán)境變量的方式來設(shè)置jvm heap size沙郭。

在新版本的es中,比如es 5.x里面裳朋,一般推薦在jvm.options文件里面去設(shè)置jvm相關(guān)的參數(shù)病线。

2、將機器上少于一半的內(nèi)存分配給es

一個常見的問題就是將es進程的jvm heap size設(shè)置的過于大了鲤嫡。比如我們有一臺64G的機器氧苍,可能我們甚至想要給es jvm size設(shè)置64G內(nèi)存。但是這是錯誤的泛范。大家可能會覺得說让虐,直接將機器上的可用的內(nèi)存都分配給es jvm heap,性能是絕對高的罢荡,因為大量的數(shù)據(jù)都可以緩存在內(nèi)存里面赡突。

雖然heap對于es來說是非常重要的对扶,jvm heap被es用來存放很多內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)來提供更快的操作性能。但是還有另外一個內(nèi)存的用戶惭缰,那就是lucene浪南。lucene的設(shè)計就是要使用底層的os filesystem cache來緩存數(shù)據(jù)結(jié)構(gòu)。lucene的segment是保存在單獨的文件中的漱受。因為這些segment是不可變的络凿,所以這些文件實際上也從來不會改變。這樣的話昂羡,就可以更好的緩存這些文件絮记,底層的os cache會將hot segment駐留在內(nèi)存中以供更快的訪問。這些segment包括了倒排索引(為了全文檢索)以及正排索引(為了聚合操作)虐先。lucene的性能是嚴重依賴于底層的os的怨愤,但是如果我們給了過多的內(nèi)存到es的jvm heap,那么就沒有足夠的內(nèi)存留給lucene蛹批。這會極大的影響性能撰洗。

這里想告訴大家的是,就是說腐芍,es的性能很大的一塊差导,其實是由有多少內(nèi)存留給操作系統(tǒng)的os cache,供lucene去緩存索引文件猪勇,來決定的设褐。所以說lucene的os cache有多少是非常重要的。

一般建議的是埠对,將50%的內(nèi)存分配給es jvm heap络断,然后留50%的內(nèi)存給os cache。留給os cache的內(nèi)存是不會不使用的项玛,lucene會將剩下的內(nèi)存全部用光貌笨,用來cache segment file。如果我們沒有對任何分詞的text field進行聚合操作襟沮,那么我們就不需要使用fielddata锥惋,我們甚至可以考慮給os cache更多的內(nèi)存,因為fielddata是要用jvm heap开伏。如果我們給jvm heap更少的內(nèi)存膀跌,那么實際上es的性能反而會更好,因為更多的內(nèi)存留給了lucene用os cache提升索引讀寫性能固灵,同時es的jvm heap的gc耗時會更少捅伤。

es部署的機器上,內(nèi)存是如何分配的巫玻,如何使用的丛忆,如何決定我們的操作系統(tǒng)的祠汇,我們該如何給jvm和os cache分配內(nèi)存

3、不要給jvm分配超過32G內(nèi)存

還有另外一個原因不要將過多的內(nèi)存分配給es的jvm heap熄诡。如果heap小于32G的化可很,jvm會用一種技術(shù)來壓縮對象的指針,object pointer凰浮。在java中我抠,所有的對象都會被分配到heap中,然后被一個pointer給引用袜茧。object pointer會指向heap中的對象菜拓,引用的是二進制格式的地址。

對于32位的系統(tǒng)來說惫周,jvm最大的heap size就是4G尘惧,解釋一下康栈,32位递递,0和1值,0和1在32位的組合是2^32次方的字節(jié)啥么,除以1024就是多少k登舞,再除以1024就是多少mb,再除以1024就是多少gb悬荣,最后算下來就是4G菠秒。對于64位的系統(tǒng)來說,heap size可以更大氯迂,但是64位的object pointer會耗費更多的空間践叠,因為object pointer更大了。比浪費更多內(nèi)存空間更惡劣的是嚼蚀,過大的object pointer會在cpu禁灼,main memory和LLC、L1等多級緩存間移動數(shù)據(jù)的時候轿曙,吃掉更多的帶寬弄捕。

所以jvm用了一種技術(shù),叫做compressed oops來解決object pointer耗費過大空間的問題导帝。這個技術(shù)的核心思想是守谓,不要讓object pointer引用內(nèi)存中的二進制地址,而是讓object pointer引用object offset您单。這就意味著32位的pointer可以引用400萬個對象斋荞,而不是400萬字節(jié)。這也意味著虐秦,使用32位的pointer平酿,最大的heap大小可以到32G讯檐。此時只要heap size在32G以內(nèi),jvm就會自動啟用32位的object pointer染服,因為32位的對象指針别洪,足夠引用32G的內(nèi)存了,就可以用32位的pointer替代64位的pointer柳刮。但是32位的pointer比64位的pointer可以耗費更少的內(nèi)存耗費挖垛。

如果你給jvm heap分配的內(nèi)存小于32G,此時jvm會自動使用32位的object pointer秉颗,同時是讓pointer指向?qū)ο蟮膐ffset痢毒,32位的object pointer就足以引用32G的內(nèi)存,同時32位的pointer占用的內(nèi)存空間很少蚕甥,對cpu和memory之間移動數(shù)據(jù)的帶寬開銷也很少哪替。這個過程就叫做compressed oops。

但是一旦我們越過了32G這個界限菇怀,就是給jvm heap分配了超過32G的內(nèi)存凭舶,比較坑了。就沒有辦法用32位的pointer+引用object offset的模式了爱沟,因為32位的pointer最多引用32G的內(nèi)存帅霜,超過了32G,就沒法用32位pointer呼伸。不用32位pointer身冀,就只能用64位pointer,才能引用超過32G的內(nèi)存空間括享。此時pointer就會退回到傳統(tǒng)的object pointer引用對象的二進制地址的模式搂根,此時object pinter的大小會急劇增長,更多的cpu到內(nèi)存的帶寬會被占據(jù)铃辖,更多的內(nèi)存被耗費剩愧。實際上,不用compressed oops時澳叉,你如果給jvm heap分配了一個40~50G的內(nèi)存的可用空間隙咸,實際上被object pointer可能都要占據(jù)十幾G的內(nèi)存空間,可用的空間量成洗,可能跟使用了compressed oops時的32GB內(nèi)存的可用空間五督,20多個G,幾乎是一樣的瓶殃。

因此充包,即使我們有很多內(nèi)存,但是還是要分配給heap在32GB以內(nèi),否則的話浪費更多的內(nèi)存基矮,降低cpu性能淆储,而且會讓jvm回收更大的heap。

綜上所述家浇,如果你給jvm heap分配超過32G的內(nèi)存本砰,實際上是沒有什么意義的,因為用64位的pointer钢悲,1/3的內(nèi)存都給object pointer給占據(jù)了点额,這段內(nèi)存空間就浪費掉了。還不如分配32G以內(nèi)莺琳,啟用compressed oops还棱,可用空間跟你分配50個G的內(nèi)存,是一樣的惭等。

所以也正是因為32G的限制珍手,一般來說,都是建議說辞做,如果你的es要處理的數(shù)據(jù)量上億的話琳要,幾億,或者十億以內(nèi)的規(guī)模的話凭豪,建議焙蹭,就是用64G的內(nèi)存的機器比較合適晒杈,有個5臺嫂伞,差不多也夠了。給jvm heap分配32G拯钻,留下32G給os cache帖努。

4、在32G以內(nèi)的話具體應(yīng)該設(shè)置heap為多大粪般?

這個是根據(jù)具體情況而定的拼余,不是固定死的,根據(jù)不同的jvm和平臺而變亩歹。一般而言匙监,將jvm heap size設(shè)置為31G比較安全一些。主要是要確保說小作,你設(shè)置的這個jvm heap大小亭姥,可以讓es啟用compressed oops這種優(yōu)化機制。此外顾稀,可以給jvm option加入-XX:+PrintFlagsFinal达罗,然后可以打印出來UseCompressedOops是否為true。這就可以讓我們找到最佳的內(nèi)存設(shè)置静秆。因為可以不斷調(diào)節(jié)內(nèi)存大小粮揉,然后觀察是否啟用compressed oops巡李。

舉例來說,如果在mac os上啟動一個java 1.7扶认,同時將heap size設(shè)置為32600mb侨拦,那么compressed oops是會開啟的;但是如果設(shè)置為32766m辐宾,compressed oops就不會開啟阳谍。相反的是,使用jdk 1.8的化螃概,分配32766m矫夯,compressed oops是會開啟的,設(shè)置為32767m吊洼,就不會開啟训貌。所以說,這個東西不是固定的冒窍。根據(jù)不同的操作系統(tǒng)以及jvm版本而定递沪。

在es啟動日志中,我們可以查看compressed oops是否開啟综液,比如下面的字樣:[2015-12-16 13:53:33,417][INFO ][env] [Illyana Rasputin] heap size [989.8mb], compressed ordinary object pointers [true]款慨。

5、對于有1TB內(nèi)存的超大內(nèi)存機器該如何分配谬莹?

如果我們的機器是一臺超級服務(wù)器檩奠,內(nèi)存資源甚至達到了1TB,或者512G附帽,128G埠戳,該怎么辦?首先es官方是建議避免用這種超級服務(wù)器來部署es集群的蕉扮,但是如果我們只有這種機器可以用的話整胃,我們要考慮以下幾點:

(1)我們是否在做大量的全文檢索?考慮一下分配4~32G的內(nèi)存給es進程喳钟,同時給lucene留下其余所有的內(nèi)存用來做os filesystem cache屁使。所有的剩余的內(nèi)存都會用來cache segment file,而且可以提供非常高性能的搜索奔则,幾乎所有的數(shù)據(jù)都是可以在內(nèi)存中緩存的蛮寂,es集群的性能會非常高

(2)是否在做大量的排序或者聚合操作?聚合操作是不是針對數(shù)字应狱、日期或者未分詞的string共郭?如果是的化,那么還是給es 4~32G的內(nèi)存即可,其他的留給es filesystem cache除嘹,可以將聚合好用的正排索引写半,doc values放在os cache中

(3)如果在針對分詞的string做大量的排序或聚合操作?如果是的化尉咕,那么就需要使用fielddata叠蝇,這就得給jvm heap分配更大的內(nèi)存空間。此時不建議運行一個節(jié)點在機器上年缎,而是運行多個節(jié)點在一臺機器上悔捶,那么如果我們的服務(wù)器有128G的內(nèi)存,可以運行兩個es節(jié)點单芜,然后每個節(jié)點分配32G的內(nèi)存蜕该,剩下64G留給os cache。如果在一臺機器上運行多個es node洲鸠,建議設(shè)置:cluster.routing.allocation.same_shard.host: true堂淡。這會避免在同一臺物理機上分配一個primary shard和它的replica shard。

6扒腕、swapping

如果頻繁的將es進程的內(nèi)存swap到磁盤上绢淀,絕對會是一個服務(wù)器的性能殺手。想象一下瘾腰,內(nèi)存中的操作都是要求快速完成的皆的,如果需要將內(nèi)存頁的數(shù)據(jù)從磁盤swap回main memory的化,性能會有多差蹋盆。如果內(nèi)存被swap到了磁盤费薄,那么100微秒的操作會瞬間變成10毫秒,那么如果是大量的這種內(nèi)存操作呢怪嫌?這會導(dǎo)致性能急劇下降义锥。

因此通常建議徹底關(guān)閉機器上的swap,swapoff -a岩灭,如果要永久性關(guān)閉,需要在/etc/fstab中配置

如果沒法完全關(guān)閉swap赂鲤,那么可以嘗試調(diào)低swappiness至噪径,這個值是控制os會如何將內(nèi)存swap到磁盤的。這會在正常情況下阻止swap数初,但是在緊急情況下找爱,還是會swap。一般用sysctl來設(shè)置泡孩,vm.swappiness = 1车摄。如果swappiness也不能設(shè)置,那么就需要啟用mlockall,這就可以讓我們的jvm lock住自己的內(nèi)存不被swap到磁盤上去吮播,在elasticsearch.yml中可以設(shè)置:bootstrap.mlockall: true变屁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市意狠,隨后出現(xiàn)的幾起案子粟关,更是在濱河造成了極大的恐慌,老刑警劉巖环戈,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闷板,死亡現(xiàn)場離奇詭異,居然都是意外死亡院塞,警方通過查閱死者的電腦和手機遮晚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拦止,“玉大人鹏漆,你說我怎么就攤上這事〈葱梗” “怎么了艺玲?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鞠抑。 經(jīng)常有香客問我饭聚,道長,這世上最難降的妖魔是什么搁拙? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任秒梳,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘避归。我一直安慰自己取董,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布兴垦。 她就那樣靜靜地躺著,像睡著了一般字柠。 火紅的嫁衣襯著肌膚如雪探越。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天窑业,我揣著相機與錄音钦幔,去河邊找鬼。 笑死常柄,一個胖子當(dāng)著我的面吹牛鲤氢,可吹牛的內(nèi)容都是我干的搀擂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼卷玉,長吁一口氣:“原來是場噩夢啊……” “哼哨颂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起揍庄,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤咆蒿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚂子,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沃测,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年食茎,在試婚紗的時候發(fā)現(xiàn)自己被綠了蒂破。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡别渔,死狀恐怖附迷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哎媚,我是刑警寧澤喇伯,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站拨与,受9級特大地震影響稻据,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜买喧,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一捻悯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧淤毛,春花似錦今缚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至查牌,卻和暖如春事期,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纸颜。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绎橘,地道東北人胁孙。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓唠倦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涮较。 傳聞我的和親對象是個殘疾皇子稠鼻,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容