Elasticsearch 5.x 源碼分析(12)對類似枚舉數(shù)據(jù)的搜索異常慢的一種猜測

2017-1-9 更新:
https://elasticsearch.cn/article/446
why this happened? 攜程的兄弟給出了答案,看來結(jié)論是一致的就是number在構(gòu)造scorer時辙芍,實際上是構(gòu)造一個巨大的bitset并在上面生成一個迭代器系瓢。而keyword 在做鏈表時有跳表查詢顯然找docid要快好多训裆。
根源就在于Lucene 6.0 對于存儲number類型是用k-d tree 造成的田轧。

看來攜程的高手看Lucene還是看的很深推沸,需要努力學(xué)習(xí)涩蜘!

最后貼出作者給出的結(jié)論刮萌,如果一定要用number建索引而又不用range操作的驮配,趕緊升級到5.4 吧:

小結(jié):
在ES5.x里,一定要注意數(shù)值類型是否需要做范圍查詢,看似數(shù)值壮锻,但其實都是做Term或者Terms匹配的琐旁,應(yīng)該定義為keyword字段。
如果RangeQuery的結(jié)果集很大猜绣,并且還需要和其他更加selective的查詢條件做AND的灰殴,應(yīng)該升級到ES5.4+,該版本在底層引入的indexOrDocValuesQuery掰邢,可以極大提升該場景下RangeQuery的查詢速度牺陶。


最近因為一個索引的數(shù)據(jù)量日益暴增,達到8辣之,9億掰伸,因此相應(yīng)的慢查詢也開始顯現(xiàn),針對其中幾種查詢更是慢的離譜怀估。
查看了一下這個慢查詢的搜索條件其實也很簡單狮鸭,而且,簡單到離譜多搀,其中有這么兩個條件查詢歧蕉,這兩個字段的mapping都是short 類型,在沒有這兩個條件的查詢康铭,延遲是可以接受的惯退,仍然能保持200ms級以內(nèi),而 is_deleted 則去到數(shù)百毫秒从藤,is_warmup則是暴增到1~3s 不等蒸痹。


這就有點奇怪了,首先docs 數(shù)一樣呛哟,這兩個typemapping 都是short,而且值都是只有0匿沛,1扫责,2這樣數(shù)種枚舉值,那為什么這種條件的查詢這么慢呢逃呼?而且還不一樣鳖孤?
當(dāng)時自己這個問題看了大半天是無果, 做了一些假設(shè)性的猜測也就作罷抡笼, 今天好基友“聶風(fēng)”同學(xué)找上門苏揣,說這幾天也遇到同類的問題,也是百思不得其解推姻,突然吊起胃口平匈,又回過頭來思考這個疑難雜癥,想一看究竟。

網(wǎng)上有好一些有共同病患的增炭,可惜還沒有官方回答忍燥,先mark下來說不定我寫完我的猜測官方就給解答了 -_-

Elastic對類似枚舉數(shù)據(jù)的搜索性能優(yōu)化

Why my search slow?


線索一:這兩個term其實和Query的order無關(guān)

我們首先肯定會覺得這兩個term的查詢肯定是結(jié)果集太大了,所以并沒有基于其他更小范圍的filter之后做隙姿,而是并行來做梅垄,并且因為結(jié)果集很大,所以撈的時間非常大输玷;是的队丝,我首先就是這個想法,后來當(dāng)我打開了profile:true看到了結(jié)果欲鹏,表示我的猜測錯了机久!
下面是我打開了profile 的分析結(jié)果:



從上面的分析得出,其實耗時并不是因為它并行走了索引去撈了超大量的數(shù)據(jù)導(dǎo)致貌虾,也不是消耗在打分上吞加,更不是消耗在什么合并運算上,偏偏是消耗在一個build_scorer 的過程里尽狠。

這里的build_scorer 究竟是什么咚咚呢衔憨?
忘了說,我的這個慢查詢都是塞在 filter里的袄膏,不是不打分的么践图,沒看到Result的score都是0? 那和score 有半毛錢關(guān)系沉馆?
那就先挖出這個scorer的解釋先:

https://www.elastic.co/guide/en/elasticsearch/reference/master/_profiling_queries.html

build_scorer

This parameter shows how long it takes to build a Scorer for the query. A Scorer is the mechanism that iterates over matching documents generates a score per-document (e.g. how well does "foo" match the document?). Note, this records the time required to generate the Scorer object, not actually score the documents. Some queries have faster or slower initialization of the Scorer, depending on optimizations, complexity, etc. This may also showing timing associated with caching, if enabled and/or applicable for the query

留意一下高亮那兩句码党,就是說耗時是耗在了構(gòu)建 一個叫Scorer Object 的東西上,并且這個東西的耗時程度取決于優(yōu)化的程度(這里我理解就是建完index之后有沒有做一些index的優(yōu)化斥黑,比如force merge揖盘, blablabla 。锌奴。兽狭。)
好了,這個Scorer Object 一看就是Lucene的東西鹿蜀,所以現(xiàn)在暫時先不深入箕慧,再挖一下其他有用的東西。


線索二: number 字段的term操作其實都是轉(zhuǎn)換成range查詢

不知道上面的截圖大家留意到一個細(xì)節(jié)沒有茴恰,[0-0] [1-1] ,對颠焦,其實這是一個range查詢



這個線索只是讓我覺得有點點意外,其實本身并無太大的價值往枣,不過也是一個思路吧伐庭,就是以后什么樣的值采用number來保存粉渠。換句話說,就是當(dāng)對number的操作很慢的時候似忧,首先得想如何提高range的性能渣叛。
關(guān)于這個課題我最后再講。


線索三:沒有線索了盯捌,老老實實看代碼吧淳衙!

首先看看這個時間是怎么來的:


ProfileWeight.java

從上面的說明結(jié)合得出,時間的跨度就是來生成這個scorer上饺著,Weight 類型是一個基類箫攀,有多個實現(xiàn),由于我還未曾系統(tǒng)的去讀完整個Lucene的源碼幼衰,所以這里我也只能猜了靴跛,大家都知道,Lucene 把所有的查詢會轉(zhuǎn)換成一顆格式化的包含各種類型查詢的樹渡嚣,而這個Weight樹我理解就是用來做合并和打分用的梢睛。
那由于這個是一個term查詢,那我們就去看看TermWeightscorer方法


從代碼上看识椰,也就是說绝葡,當(dāng)做某個field的檢索的時候,其實Lucene會初始化一個這個field 的termEnum 這種東西腹鹉,并且會調(diào)用postings 獲取PostingsEnum
那這個PostingsEnum 又是什么鬼藏畅,我大概了解就是一種結(jié)果docs 的迭代器的抽象,已被到時在Lucene的結(jié)果樹里可以快速做合并功咒,運算之用

那么再對比一下愉阎,PostingsEnum的 普通term的倒排和number的倒排的實現(xiàn)類應(yīng)該是完全不同的邏輯實現(xiàn)的




好,那我猜測構(gòu)造慢因該就是做這個postings 慢了力奋,因為它有各自的實現(xiàn)榜旦,如果涉及到docs 的指針的迭代,那么大家都知道景殷,Lucene的倒排指向的docs 映射是用BitSet去實現(xiàn)的章办,那么到現(xiàn)在為止就可以猜測,要初始化一個類似LongBitSet這種東西滨彻,跟我這個number的本身的稀疏程度是否有關(guān)?


我的一種猜測

至此挪蹭,我的一個猜測就是如果number類型的條件結(jié)果集很大的時候亭饵,要構(gòu)造一個某種BitSet的scorer 其實是挺費勁的(像官方文檔說說,還和其他很多因素相關(guān))但是如何解釋同樣是number梁厉,為什么 is_warmup 要比is_deleted還要再慢幾倍呢辜羊?我猜測是不同docs的這個值的稀疏程度有關(guān)踏兜,當(dāng)然要回答這個還要繼續(xù)深入Lucene的代碼,我這里就不再繼續(xù)drill down了

結(jié)論

好了八秃,其實要解決這個問題很簡單碱妆,如果是枚舉類型的數(shù)字的話,mapping 用keyword 就好了昔驱,其實回顧官方文檔的時候疹尾,官方文檔也清楚列明了的,如果你是不做range操作的可枚舉出的數(shù)字的話,比如map 的keyset骤肛,最好還是用keyword纳本。


后話

恰巧看到一篇blog有提到官方其實一直在努力加快 number的range搜索,具體大家可以讀讀, 貌似這個優(yōu)化增加到 ES5.4 以后的版本了

https://www.elastic.co/blog/better-query-planning-for-range-queries-in-elasticsearch

接下來看有機會debug一下Lucene的部分代碼腋颠,希望大家提出自己的看法繁成,各抒己見,就拍哪里錯了誤導(dǎo)了大家淑玫;好了巾腕,洗洗睡了!

參考文獻:
https://www.compose.com/articles/how-scoring-works-in-elasticsearch/
https://qbox.io/blog/optimizing-search-results-in-elasticsearch-with-scoring-and-boosting
https://www.elastic.co/guide/cn/elasticsearch/guide/current/scoring-theory.html
https://toutiao.io/posts/4mwfeo/preview
http://www.scienjus.com/elasticsearch-function-score-query/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末絮蒿,一起剝皮案震驚了整個濱河市尊搬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌歌径,老刑警劉巖毁嗦,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異回铛,居然都是意外死亡狗准,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門茵肃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腔长,“玉大人,你說我怎么就攤上這事验残±谈剑” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵您没,是天一觀的道長鸟召。 經(jīng)常有香客問我,道長氨鹏,這世上最難降的妖魔是什么欧募? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮仆抵,結(jié)果婚禮上跟继,老公的妹妹穿的比我還像新娘种冬。我一直安慰自己,他們只是感情好舔糖,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布娱两。 她就那樣靜靜地躺著,像睡著了一般金吗。 火紅的嫁衣襯著肌膚如雪十兢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天辽聊,我揣著相機與錄音纪挎,去河邊找鬼。 笑死跟匆,一個胖子當(dāng)著我的面吹牛异袄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玛臂,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼烤蜕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迹冤?” 一聲冷哼從身側(cè)響起讽营,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泡徙,沒想到半個月后橱鹏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡堪藐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年莉兰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片礁竞。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡糖荒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出模捂,到底是詐尸還是另有隱情捶朵,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布狂男,位于F島的核電站综看,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏岖食。R本人自食惡果不足惜寓搬,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望县耽。 院中可真熱鬧句喷,春花似錦、人聲如沸兔毙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澎剥。三九已至锡溯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哑姚,已是汗流浹背祭饭。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叙量,地道東北人倡蝙。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像绞佩,于是被迫代替她去往敵國和親寺鸥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

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