Elasticsearch聚合限制內(nèi)存使用

Elasticsearch聚合限制內(nèi)存使用

限制內(nèi)存使用

通常為了讓聚合(或者任何需要訪問字段值的請(qǐng)求)能夠快點(diǎn)厘托,訪問fielddata一定會(huì)快點(diǎn), 這就是為什么加載到內(nèi)存的原因。但是加載太多的數(shù)據(jù)到內(nèi)存會(huì)導(dǎo)致垃圾回收(gc)緩慢, 因?yàn)镴VM試著發(fā)現(xiàn)堆里面的額外空間,甚至導(dǎo)致OutOfMemory異常拓诸。

最讓你吃驚的是,你會(huì)發(fā)現(xiàn)Elaticsearch不是只把符合你的查詢的值加載到fielddata. 而是把index里的所document都加載到內(nèi)存麻昼,甚至是不同的?_type?的document恰响。

邏輯是這樣的,如果你在這個(gè)查詢需要訪問documents X涌献,Y和Z, 你可能在下一次查詢就需要訪問別documents首有。而一次把所有的值都加載并保存在內(nèi)存?燕垃, 比每次查詢都去掃描倒排索引要更方便。

JVM堆是一個(gè)有限制的資源需要聰明的使用井联。有許多現(xiàn)成的機(jī)制去限制fielddata對(duì)堆內(nèi)存使用的影響卜壕。這些限制非常重要,因?yàn)闉E用堆將會(huì)導(dǎo)致節(jié)點(diǎn)的不穩(wěn)定(多虧緩慢的垃圾回收)或者甚至節(jié)點(diǎn)死亡(因?yàn)镺utOfMemory異常)烙常;但是垃圾回收時(shí)間過長(zhǎng)轴捎,在垃圾回收期間鹤盒,ES節(jié)點(diǎn)的性能就會(huì)大打折扣,查詢就會(huì)非常緩慢侦副,直到最后超時(shí)侦锯。

如何設(shè)置堆大小

對(duì)于環(huán)境變量?$ES_HEAP_SIZE?在設(shè)置Elasticsearch堆大小的時(shí)候有2個(gè)法則可以運(yùn)用:

不超過RAM的50%

Lucene很好的利用了文件系統(tǒng)cache,文件系統(tǒng)cache是由內(nèi)核管理的秦驯。如果沒有足夠的文件系統(tǒng)cache空間尺碰,性能就會(huì)變差。

不超過32G

如果堆小于32GB译隘,JVM能夠使用壓縮的指針亲桥,這會(huì)節(jié)省許多內(nèi)存:每個(gè)指針就會(huì)使用4字節(jié)而不是8字節(jié)。

把對(duì)內(nèi)存從32GB增加到34GB將意味著你將有更少的內(nèi)存可用固耘,因?yàn)樗械闹羔樥加昧穗p倍的空間题篷。同樣,更大的堆厅目,垃圾回收變得代價(jià)更大并且可能導(dǎo)致節(jié)點(diǎn)不穩(wěn)定番枚;這個(gè)限制主要是大內(nèi)存對(duì)fielddata影響比較大。

Fielddata大小

參數(shù)?indices.fielddata.cache.size?控制有多少堆內(nèi)存是分配給fielddata璧瞬。當(dāng)你執(zhí)行一個(gè)查詢需要訪問新的字段值的時(shí)候户辫,將會(huì)把值加載到內(nèi)存,然后試著把它們加入到fielddata嗤锉。如果結(jié)果的fielddata大小超過指定的大小?渔欢,為了騰出空間,別的值就會(huì)被驅(qū)逐出去瘟忱。

默認(rèn)情況下奥额,這個(gè)參數(shù)設(shè)置的是無限制?—?Elasticsearch將永遠(yuǎn)不會(huì)把數(shù)據(jù)從fielddata里替換出去。

這個(gè)默認(rèn)值是故意選擇的:fielddata不是臨時(shí)的cache访诱。它是一個(gè)在內(nèi)存里為了快速執(zhí)行必須能被訪問的數(shù)據(jù)結(jié)構(gòu)垫挨,而且構(gòu)建它代價(jià)非常昂貴。如果你每個(gè)請(qǐng)求都要重新加載數(shù)據(jù)触菜,性能就會(huì)很差九榔。

一個(gè)有限的大小強(qiáng)迫數(shù)據(jù)結(jié)構(gòu)去替換數(shù)據(jù)。我們將看看什么時(shí)候去設(shè)置下面的值涡相,首先讓我們看一個(gè)警告:

【warning】

這個(gè)設(shè)置是一個(gè)保護(hù)措施哲泊,而不是一個(gè)內(nèi)存不足的解決方案

如果你沒有足夠的內(nèi)存區(qū)保存你的fielddata到內(nèi)存里,Elasticsearch將會(huì)經(jīng)常性的從磁盤重新加載數(shù)據(jù)催蝗,并且驅(qū)逐別的數(shù)據(jù)區(qū)騰出空間切威。這種數(shù)據(jù)的驅(qū)逐會(huì)導(dǎo)致嚴(yán)重的磁盤I/O,并且在內(nèi)存里產(chǎn)生大量的垃圾丙号,這個(gè)會(huì)在后面被垃圾回收先朦。

假設(shè)你在索引日志缰冤,每天使用給一個(gè)新的索引。通常情況下你只會(huì)對(duì)過去1天或者2天的數(shù)據(jù)感興趣喳魏。即使你把老的索引數(shù)據(jù)保留著棉浸,你也很少查詢它們。盡管如此截酷,使用默認(rèn)的設(shè)置涮拗, 來自老索引的fielddata也不會(huì)被清除出去!fielddata會(huì)一直增長(zhǎng)直到它觸發(fā)fielddata circuit breaker --參考斷路器--它將阻止你繼續(xù)加載fielddata迂苛。

在那個(gè)時(shí)候你被卡住了三热。即使你仍然能夠執(zhí)行訪問老的索引里的fielddata的查詢, 你再也不能加載任何新的值了三幻。相反就漾,我們應(yīng)該把老的值清除出去給新的值騰出空間。

為了防止這種情景念搬,通過在config/elasticsearch.yml文件里加上如下的配置給fielddata 設(shè)置一個(gè)上限:

indices.fielddata.cache.size: ?40%

當(dāng)然可以設(shè)置成堆大小的百分比抑堡,也可以是一個(gè)具體的值,比如 8gb朗徊;通過適當(dāng)?shù)脑O(shè)置這個(gè)值首妖,最近被訪問的fielddata將被清除出去,給新加載的數(shù)據(jù)騰出空間爷恳。

在網(wǎng)上你可能會(huì)看到另外一個(gè)設(shè)置參數(shù):?indices.fielddata.cache.expire?有缆。千萬不要使用這個(gè)設(shè)置!這個(gè)設(shè)置高版本已經(jīng)廢棄温亲。

這個(gè)設(shè)置告訴Elasticsearch把比過期時(shí)間老的數(shù)據(jù)從fielddata里驅(qū)逐出去棚壁,而不管這個(gè)值是否被用到。

這對(duì)性能是非痴恍椋可怕的?袖外。驅(qū)逐數(shù)據(jù)是有代價(jià)的,并且這個(gè)有目的的高效的安排驅(qū)逐數(shù)據(jù)并沒有任何真正的收獲魂务。

沒有任何理由去使用這個(gè)設(shè)置曼验;我們一點(diǎn)也不能從理論上制造一個(gè)假設(shè)的有用的情景。現(xiàn)階段存 在只是為了向后兼容粘姜。我們?cè)谶@個(gè)書里提到這個(gè)設(shè)置是因?yàn)檫@個(gè)設(shè)置曾經(jīng)在網(wǎng)絡(luò)上的各種文章里 被作為一個(gè) ``性能小竅門'' 被推薦過鬓照。

記住永遠(yuǎn)不要使用它,就ok相艇!

監(jiān)控fielddata

監(jiān)控fielddata使用了多少內(nèi)存以及是否有數(shù)據(jù)被驅(qū)逐是非常重要的。大量的數(shù)據(jù)被驅(qū)逐會(huì)導(dǎo)致嚴(yán)重的資源問題以及不好的性能纯陨。

Fielddata使用可以通過下面的方式來監(jiān)控:

對(duì)于單個(gè)索引使用 {ref}indices-stats.html[indices-stats?API]:

GET /_stats/fielddata?fields=*

對(duì)于單個(gè)節(jié)點(diǎn)使用 {ref}cluster-nodes-stats.html[nodes-stats?API]:

GET /_nodes/stats/indices/fielddata?fields=*

或者甚至單個(gè)節(jié)點(diǎn)單個(gè)索引

GET /_nodes/stats/indices/fielddata?level=indices&fields=*

通過設(shè)置??fields=*?內(nèi)存使用按照每個(gè)字段分解了.

斷路器(breaker)

聰明的讀者可能已經(jīng)注意到fielddata大小設(shè)置的一個(gè)問題坛芽。fielddata的大小是在數(shù)據(jù)被加載之后才校驗(yàn)的留储。如果一個(gè)查詢嘗試加載到fielddata的數(shù)據(jù)比可用的內(nèi)存大會(huì)發(fā)生什么情況?答案是不客觀的:你將會(huì)獲得一個(gè)OutOfMemory異常咙轩。

Elasticsearch包含了一個(gè)?fielddata斷路器?获讳,這個(gè)就是設(shè)計(jì)來處理這種情況的。斷路器通過檢查涉及的字段(它們的類型活喊,基數(shù)丐膝,大小等等)來估計(jì)查詢需要的內(nèi)存。然后檢查加 載需要的fielddata會(huì)不會(huì)導(dǎo)致總的fielddata大小超過設(shè)置的堆的百分比钾菊。

如果估計(jì)的查詢大小超過限制帅矗,斷路器就會(huì)觸發(fā)并且查詢會(huì)被拋棄返回一個(gè)異常。這個(gè)發(fā)生在數(shù)據(jù)被加載之前煞烫,這就意味著你不會(huì)遇到OutOfMemory異常浑此。

Elasticsearch擁有一系列的斷路器,所有的這些都是用來保證內(nèi)存限制不會(huì)被突破:

indices.breaker.fielddata.limit

這個(gè)?fielddata?斷路器限制fielddata的大小為堆大小的60%滞详,默認(rèn)情況下凛俱。

indices.breaker.request.limit

這個(gè)?request?斷路器估算完成查詢的其他部分要求的結(jié)構(gòu)的大小,比如創(chuàng)建一個(gè)聚集通料饥, 以及限制它們到堆大小的40%蒲犬,默認(rèn)情況下。

indices.breaker.total.limit

這個(gè)total斷路器封裝了?request?和?fielddata?斷路器去確保默認(rèn)情況下這2個(gè) 使用的總內(nèi)存不超過堆大小的70%岸啡。

斷路器限制可以通過文件?config/elasticsearch.yml?指定原叮,也可以在集群上動(dòng)態(tài)更新:

PUT /_cluster/settings

{

"persistent" : {

"indices.breaker.fielddata.limit" : 40% (1)

}

}

這個(gè)限制設(shè)置的是堆的百分比。

最好把斷路器設(shè)置成一個(gè)相對(duì)保守的值凰狞。記住fielddata需要和堆共享?request?斷路器篇裁, 索引內(nèi)存緩沖區(qū),過濾器緩存赡若,打開的索引的Lucene數(shù)據(jù)結(jié)構(gòu)达布,以及各種各樣別的臨時(shí)數(shù)據(jù) 結(jié)構(gòu)。所以默認(rèn)為相對(duì)保守的60%逾冬。過分樂觀的設(shè)置可能會(huì)導(dǎo)致潛在的OOM異常黍聂,從而導(dǎo)致整 個(gè)節(jié)點(diǎn)掛掉。

從另一方面來說身腻,一個(gè)過分保守的值將會(huì)簡(jiǎn)單的返回一個(gè)查詢異常产还,這個(gè)異常會(huì)被應(yīng)用處理。 異赤痔耍總比掛掉好脐区。這些異常也會(huì)促使你重新評(píng)估你的查詢:為什么單個(gè)的查詢需要超過60%的 堆空間。

斷路器和Fielddata大小

在?Fielddata大小部分我們談到了要給fielddata大小增加一個(gè)限制去保證老的不使用 的fielddata被驅(qū)逐出去她按。indices.fielddata.cache.size?和?indices.breaker.fielddata.limit?的關(guān)系是非常重要的牛隅。如果斷路器限制比緩沖區(qū)大小要小炕柔,就會(huì)沒有數(shù)據(jù)會(huì)被驅(qū)逐。為了能夠 讓它正確的工作媒佣,斷路器限制必須比緩沖區(qū)大小要大匕累。

我們注意到斷路器是和總共的堆大小對(duì)比查詢大小,而不是和真正已經(jīng)使用的堆內(nèi)存區(qū)比較默伍。 這樣做是有一系列技術(shù)原因的(比如欢嘿,堆可能看起來是滿的,但是實(shí)際上可能正在等待垃圾 回收也糊,這個(gè)很難準(zhǔn)確的估算)炼蹦。但是作為終端用戶,這意味著設(shè)置必須是保守的显设,因?yàn)樗?和整個(gè)堆大小比較框弛,而不是空閑的堆比較。

Elasticsearch權(quán)威指南筆記捕捂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瑟枫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子指攒,更是在濱河造成了極大的恐慌慷妙,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件允悦,死亡現(xiàn)場(chǎng)離奇詭異膝擂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)隙弛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門架馋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人全闷,你說我怎么就攤上這事叉寂。” “怎么了总珠?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵屏鳍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我局服,道長(zhǎng)钓瞭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任淫奔,我火速辦了婚禮山涡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己鸭丛,他們只是感情好霍殴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著系吩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪妒蔚。 梳的紋絲不亂的頭發(fā)上穿挨,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音肴盏,去河邊找鬼科盛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛菜皂,可吹牛的內(nèi)容都是我干的贞绵。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼恍飘,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼榨崩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起章母,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤母蛛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后乳怎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體彩郊,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年蚪缀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秫逝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡询枚,死狀恐怖违帆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哩盲,我是刑警寧澤前方,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站廉油,受9級(jí)特大地震影響惠险,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抒线,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一班巩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦抱慌、人聲如沸逊桦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽强经。三九已至,卻和暖如春寺渗,著一層夾襖步出監(jiān)牢的瞬間匿情,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工信殊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炬称,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓涡拘,卻偏偏與公主長(zhǎng)得像玲躯,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鳄乏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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