Elasticsearch系列---性能調(diào)優(yōu)最佳實(shí)踐

概要

性能調(diào)優(yōu)是系統(tǒng)架構(gòu)里所有組件必不可少的話題始藕,Elasticsearch也不例外蒲稳,雖說Elasticsearch內(nèi)的默認(rèn)配置已經(jīng)非常優(yōu)秀,但這不表示它就是完美的伍派,必要的一些實(shí)踐我們還是需要了解一下江耀。

開啟慢查詢?nèi)罩?/h3>

慢查詢?nèi)罩臼切阅茉\斷的重要利器,常規(guī)操作是設(shè)置慢查詢的閥值诉植,然后運(yùn)維童鞋每天對慢日志進(jìn)行例行巡查祥国,有特別慢的查詢,立即報(bào)備事件處理晾腔,其余的定期將慢日志的top n取出來進(jìn)行優(yōu)化舌稀。

慢日志的配置在elasticsearch 6.3.1版本下是通過命令配置的,讀操作和寫操作可以單獨(dú)設(shè)置建车,閥值的定義可根據(jù)實(shí)際的需求和性能指標(biāo)扩借,有人覺得5秒慢,有人覺得3秒就不可接受缤至,我們以3秒為例:

PUT /_all/_settings
{
"index.search.slowlog.threshold.query.warn":"3s",
"index.search.slowlog.threshold.query.info":"2s",
"index.search.slowlog.threshold.query.debug":"1s",
"index.search.slowlog.threshold.query.trace":"500ms",

"index.search.slowlog.threshold.fetch.warn":"1s",
"index.search.slowlog.threshold.fetch.info":"800ms",
"index.search.slowlog.threshold.fetch.debug":"500ms",
"index.search.slowlog.threshold.fetch.trace":"200ms",

"index.indexing.slowlog.threshold.index.warn":"3s",
"index.indexing.slowlog.threshold.index.info":"2s",
"index.indexing.slowlog.threshold.index.debug":"1s",
"index.indexing.slowlog.threshold.index.trace":"500ms",
"index.indexing.slowlog.level":"info",
"index.indexing.slowlog.source":"1000"
}

這三段分別表示query查詢潮罪、fetch查詢和index寫入三類操作的慢日志輸出閥值,_all表示對所有索引生效领斥,也可以針對具體的索引嫉到。

同時(shí)在log4j2.properties配置文件中增加如下配置:

# 查詢操作慢日志輸出
appender.index_search_slowlog_rolling.type = RollingFile
appender.index_search_slowlog_rolling.name = index_search_slowlog_rolling
appender.index_search_slowlog_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_search_slowlog.log
appender.index_search_slowlog_rolling.layout.type = PatternLayout
appender.index_search_slowlog_rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %.10000m%n
appender.index_search_slowlog_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_search_slowlog-%d{yyyy-MM-dd}.log
appender.index_search_slowlog_rolling.policies.type = Policies
appender.index_search_slowlog_rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.index_search_slowlog_rolling.policies.time.interval = 1
appender.index_search_slowlog_rolling.policies.time.modulate = true

logger.index_search_slowlog_rolling.name = index.search.slowlog
logger.index_search_slowlog_rolling.level = trace
logger.index_search_slowlog_rolling.appenderRef.index_search_slowlog_rolling.ref = index_search_slowlog_rolling
logger.index_search_slowlog_rolling.additivity = false

# 索引操作慢日志輸出
appender.index_indexing_slowlog_rolling.type = RollingFile
appender.index_indexing_slowlog_rolling.name = index_indexing_slowlog_rolling
appender.index_indexing_slowlog_rolling.fileName = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_indexing_slowlog.log
appender.index_indexing_slowlog_rolling.layout.type = PatternLayout
appender.index_indexing_slowlog_rolling.layout.pattern = [%d{ISO8601}][%-5p][%-25c] %marker%.10000m%n
appender.index_indexing_slowlog_rolling.filePattern = ${sys:es.logs.base_path}${sys:file.separator}${sys:es.logs.cluster_name}_index_indexing_slowlog-%d{yyyy-MM-dd}.log
appender.index_indexing_slowlog_rolling.policies.type = Policies
appender.index_indexing_slowlog_rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.index_indexing_slowlog_rolling.policies.time.interval = 1
appender.index_indexing_slowlog_rolling.policies.time.modulate = true

logger.index_indexing_slowlog.name = index.indexing.slowlog.index
logger.index_indexing_slowlog.level = trace
logger.index_indexing_slowlog.appenderRef.index_indexing_slowlog_rolling.ref = index_indexing_slowlog_rolling
logger.index_indexing_slowlog.additivity = false

重啟elasticsearch實(shí)例后,就能在/home/esuser/esdata/log目錄中看到生成的兩個(gè)日志文件了月洛。

優(yōu)化實(shí)踐建議

基本使用規(guī)范

  1. 搜索結(jié)果不要返回過大的結(jié)果集

過大的結(jié)果集會(huì)占用大量的IO資源和帶寬何恶,速度肯定快不了,Elasticsearch是一個(gè)搜索引擎嚼黔,最理想的搜索是精準(zhǔn)查詢或次精準(zhǔn)查詢细层,最關(guān)心的是排在前面的少數(shù)結(jié)果惜辑,而不是所有結(jié)果,優(yōu)化搜索條件疫赎,控制搜索結(jié)果數(shù)量是高性能的前提盛撑。

如果真有大批量的數(shù)據(jù)查詢,建議使用scroll api捧搞。

  1. 避免超大的document

http.max_context_length的默認(rèn)值是100mb抵卫,如果你一次document寫入時(shí),document的內(nèi)容不能超過100mb胎撇,否則es就會(huì)拒絕寫入介粘。雖然你可以修改此配置,但不建議這么做晚树,es底層的lucene引擎還是有一個(gè)2gb的最大限制姻采。

過大的document會(huì)占用非常多的資源,從任何方面考慮都不建議题涨,如果業(yè)務(wù)需求真有非常大的內(nèi)容偎谁,如對書的內(nèi)容搜索总滩,建議按章節(jié)纲堵、按段落進(jìn)行拆分存儲(chǔ)。

  1. 避免稀疏的數(shù)據(jù)

document的設(shè)計(jì)會(huì)從根本上影響索引的性能闰渔,稀疏數(shù)據(jù)是一個(gè)典型的不良設(shè)計(jì)席函,浪費(fèi)存儲(chǔ)空間,影響讀寫性能冈涧。

下面有一些document結(jié)構(gòu)設(shè)計(jì)的建議:

  • 避免將沒有任何關(guān)聯(lián)性的數(shù)據(jù)寫入同一個(gè)索引

沒有關(guān)聯(lián)性的數(shù)據(jù)茂附,意味著數(shù)據(jù)結(jié)構(gòu)也不相同,硬生生放在同一個(gè)索引督弓,會(huì)導(dǎo)致index數(shù)據(jù)非常稀疏营曼,建議是將這些數(shù)據(jù)放在不同的索引中。

  • 對document的結(jié)構(gòu)進(jìn)行統(tǒng)一規(guī)范化

document的結(jié)構(gòu)愚隧、命名盡可能統(tǒng)一規(guī)范處理蒂阱,同樣是創(chuàng)建時(shí)間字段,避免有的叫timestamp狂塘,有的叫create_time录煤,盡可能統(tǒng)一。

  • 對某些field禁用norms和doc_values

如果一個(gè)field不需要考慮其相關(guān)度分?jǐn)?shù)荞胡,那么可以禁用norms妈踊,如果不需要對一個(gè)field進(jìn)行排序或者聚合,那么可以禁用doc_values字段泪漂。

服務(wù)器層級(jí)

硬件資源是性能最硬核的部分廊营,硬件好歪泳,起點(diǎn)就高。

  1. 用更快的硬件資源

在預(yù)算范圍內(nèi)露筒,能用SSD固態(tài)硬盤就不要選用機(jī)械硬盤夹囚;

CPU主頻、核數(shù)當(dāng)然是強(qiáng)大到預(yù)算上限邀窃;

內(nèi)存單機(jī)上限64GB荸哟,加機(jī)器加到?jīng)]錢為止;

盡量使用本地存儲(chǔ)系統(tǒng)瞬捕,不要用NFS等網(wǎng)絡(luò)存儲(chǔ)鞍历,畢竟硬盤便宜。

  1. 給filesystem cache更多的內(nèi)存

Elasticsearch的搜索嚴(yán)重依賴于底層的filesystem cache肪虎,如果所有的數(shù)據(jù)都能夠存放在filesystem cache中劣砍,那么搜索基本上是秒級(jí)。

由于實(shí)際情況的限制扇救,最佳的情況下刑枝,就是你的機(jī)器的內(nèi)存,至少可以容納你的總數(shù)據(jù)量的一半迅腔。

要達(dá)到最佳情況有兩個(gè)辦法:一個(gè)是砸錢装畅,買更多機(jī)器,加更大內(nèi)存沧烈;另一種是精簡document數(shù)據(jù)掠兄,只把需要搜索的field放進(jìn)es內(nèi),filesystem cache就能存下更多的document锌雀,可以提高內(nèi)存的利用率蚂夕。剩余的其他字段,可以放在redis/mysql/hbase/hapdoop做二級(jí)加載腋逆。

  1. 禁止swapping交換內(nèi)存

將swapping禁止掉婿牍,如果es jvm內(nèi)存交換到磁盤,再交換回內(nèi)存惩歉,會(huì)造成大量磁盤IO等脂,性能很差。

Elasticsearch層級(jí)

  1. index buffer

在高并發(fā)寫入場景柬泽,我們可以將index buffer調(diào)大一些慎菲,indices.memory.index_buffer_size,這個(gè)可以調(diào)節(jié)大一些锨并,這個(gè)值默認(rèn)是jvm heap的10%露该,這個(gè)index buffer大小,是所有的shard公用的第煮,這個(gè)值除以shard數(shù)量解幼,算出來平均每個(gè)shard可以使用的內(nèi)存大小抑党,一般建議對于每個(gè)shard最多給512mb。

  1. 禁止_all field

_all field會(huì)將document中所有field的值都合并在一起進(jìn)行索引撵摆,很占用磁盤空空間底靠,實(shí)際上用處卻不大,生產(chǎn)環(huán)境最好禁用_all field特铝。

  1. 使用best_compression

_source field和其他field很占用磁盤空間暑中,建議對其使用best_compression進(jìn)行壓縮。

  1. 用最小的最合適的數(shù)字類型

es支持4種數(shù)字類型:byte鲫剿,short鳄逾,integer,long灵莲。如果最小的類型就合適雕凹,那么就用最小的類型,節(jié)省磁盤空間政冻。

  1. 禁用不需要的功能

對于需要進(jìn)行聚合和排序的field枚抵,我們才建立正排索引;
對于需要進(jìn)行檢索的field明场,我們才建立倒排索引汽摹;
對于不關(guān)心doc分?jǐn)?shù)的field,我們可以禁用掉norm榕堰;
對于不需要執(zhí)行phrase query近似匹配的field竖慧,那么可以禁用位置這個(gè)屬性;

  1. 不要用默認(rèn)的動(dòng)態(tài)string類型映射

默認(rèn)的動(dòng)態(tài)string類型映射會(huì)將string類型的field同時(shí)映射為text類型以及keyword類型嫌套,大多數(shù)情況我們只需要使用其中一種逆屡,剩下的都是浪費(fèi)磁盤空間,例如踱讨,id field這種字段可能只需要keyword魏蔗,而body field可能只需要text field。

所以是使用keyword和text在設(shè)計(jì)時(shí)就應(yīng)該區(qū)分清楚痹筛,而不是全盤保存莺治。

  1. 預(yù)熱filesystem cache

如果我們重啟了Elasticsearch,那么filesystem cache是空的帚稠,每次數(shù)據(jù)查詢時(shí)再加載數(shù)據(jù)進(jìn)filesystem cache谣旁,我們可以先對一些數(shù)據(jù)進(jìn)行查詢,提前將一些常用數(shù)據(jù)加載到內(nèi)存滋早,待真實(shí)客戶使用時(shí)榄审,可以直接使用內(nèi)存數(shù)據(jù),響應(yīng)就很快了杆麸。

代碼研發(fā)層級(jí)

  1. 多使用bulk做寫入

我們使用Java作為客戶端時(shí)搁进,寫入操作全部利用bulk api來完成浪感。

  1. 使用多線程將數(shù)據(jù)寫入

  2. document使用自動(dòng)生成的id

手動(dòng)給document設(shè)置一個(gè)id,那么es需要每次都去確認(rèn)一下那個(gè)id是否存在饼问,這個(gè)過程是比較耗費(fèi)時(shí)間的影兽。如果我們使用自動(dòng)生成的id,那么es就可以跳過這個(gè)步驟莱革,寫入性能會(huì)更好承璃。

對于關(guān)系型數(shù)據(jù)庫中的表id栓始,可以作為es document的一個(gè)field存入。

  1. 重視document結(jié)構(gòu)設(shè)計(jì)

業(yè)務(wù)研發(fā)的重中之重,好的document結(jié)構(gòu)會(huì)帶來非常優(yōu)秀的性能表現(xiàn)尖啡。

  1. 避免使用script腳本

  2. 充分利用緩存

時(shí)間查詢時(shí),不要使用now這種函數(shù)斤彼,應(yīng)該在客戶端把時(shí)間轉(zhuǎn)換成規(guī)范的格式范抓,再到Elasticsearch里查詢,這樣能提高緩存的使用率拇砰。

小結(jié)

本篇介紹了Elasticsearch性能調(diào)優(yōu)的常見實(shí)踐方法梅忌,從服務(wù)器、實(shí)例再到代碼層級(jí)除破,可以作為參考牧氮,但性能調(diào)優(yōu)沒有約定俗成的方法,需要反復(fù)的驗(yàn)證瑰枫,僅供參考踱葛,謝謝

專注Java高并發(fā)、分布式架構(gòu)光坝,更多技術(shù)干貨分享與心得尸诽,請關(guān)注公眾號(hào):Java架構(gòu)社區(qū)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市盯另,隨后出現(xiàn)的幾起案子性含,更是在濱河造成了極大的恐慌,老刑警劉巖鸳惯,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件商蕴,死亡現(xiàn)場離奇詭異,居然都是意外死亡芝发,警方通過查閱死者的電腦和手機(jī)绪商,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辅鲸,“玉大人格郁,你說我怎么就攤上這事。” “怎么了理张?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵赫蛇,是天一觀的道長。 經(jīng)常有香客問我雾叭,道長悟耘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任织狐,我火速辦了婚禮暂幼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘移迫。我一直安慰自己旺嬉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布厨埋。 她就那樣靜靜地躺著邪媳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荡陷。 梳的紋絲不亂的頭發(fā)上雨效,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音废赞,去河邊找鬼徽龟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛唉地,可吹牛的內(nèi)容都是我干的据悔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼耘沼,長吁一口氣:“原來是場噩夢啊……” “哼极颓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起耕拷,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對情侶失蹤讼昆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后骚烧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡闰围,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年赃绊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羡榴。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碧查,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情忠售,我是刑警寧澤传惠,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站稻扬,受9級(jí)特大地震影響卦方,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泰佳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一盼砍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逝她,春花似錦浇坐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至臀晃,卻和暖如春跌宛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背积仗。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工疆拘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寂曹。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓哎迄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親隆圆。 傳聞我的和親對象是個(gè)殘疾皇子漱挚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354