溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何分析Elasticsearch中奇怪的查詢命中數(shù)問(wèn)題

發(fā)布時(shí)間:2021-12-10 11:33:41 來(lái)源:億速云 閱讀:610 作者:柒染 欄目:大數(shù)據(jù)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)如何分析Elasticsearch中奇怪的查詢命中數(shù)問(wèn)題,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

業(yè)務(wù)部門(mén)反饋,在某個(gè)月份的索引中,當(dāng)查詢條件不變,僅添加一個(gè)索引前綴到請(qǐng)求中后,搜索返回的命中數(shù)量反而降低,如下圖所示,從索引 skylay*_alarm-2020.02* 中查詢時(shí),命中結(jié)果總數(shù) total為49條

?

如何分析Elasticsearch中奇怪的查詢命中數(shù)問(wèn)題

但是當(dāng)添加了一個(gè)索引前綴 skylar*_alarm-2020.01* ,從 skylay*_alarm-2020.02*,skylar*_alarm-2020.01* 兩組索引一起查詢時(shí),命中結(jié)果總數(shù)居然降低為15條了:

如何分析Elasticsearch中奇怪的查詢命中數(shù)問(wèn)題

?

按照常規(guī)理解,添加一個(gè)索引到查詢條件中,命中結(jié)果集只可能更多,不應(yīng)該降低,仔細(xì)觀察返回結(jié)果,發(fā)現(xiàn) _shards 中的 skipped 非常多,這點(diǎn)很可疑,感覺(jué)多半與他有關(guān)。

分析

分析查詢問(wèn)題,首先想到的就是 profile 一把,在請(qǐng)求體中添加 "profile": true, 可惜沒(méi)看到有價(jià)值的東西,然后 google 一把,看有沒(méi)有其他人遇到 skipped 問(wèn)題,發(fā)現(xiàn)在社區(qū)中很多人問(wèn)到 skipped相關(guān)問(wèn)題,基本沒(méi)有人回復(fù),唯一有價(jià)值的答復(fù)如下:

Are shards skipped when a range query does not create hits

Yes, there is a pre-flight search phase called the can match search phase that removes all shards from a search request that a query can not match (e.g., if a range query does not overlap with the range of values for a shard). This feature exists since 5.6.

這段內(nèi)容大致是說(shuō)從5.6版本開(kāi)始,在真正的查詢開(kāi)始之前根據(jù)某些條件跳過(guò)不會(huì)匹配到的分片,例如范圍查詢過(guò)程中,某些分片的值不在查詢區(qū)間。

除此之外再無(wú)更多內(nèi)容,只能從源碼層面繼續(xù)分析。函數(shù)AbstractSearchAsyncAction#buildSearchResponse 負(fù)責(zé)構(gòu)建查詢返回結(jié)果,skipped數(shù)量取決于這個(gè)類中的一個(gè)計(jì)數(shù)器,繼續(xù)向上翻,找到將分片標(biāo)記為 skip 的地方CanMatchPreFilterSearchPhase#getIterator:

private GroupShardsIterator<SearchShardIterator> getIterator(...) {
   for (SearchShardIterator iter : shardsIts) {
       if (possibleMatches.get(i++)) {
           iter.reset();
       } else {
           //標(biāo)記為 skip,查詢的時(shí)候不會(huì)去查
           iter.resetAndSkip();
       }
   }
   return shardsIts;
}

由于需要優(yōu)先解決線上問(wèn)題,暫時(shí)先不分析分片被設(shè)置為 skip 都會(huì)有哪些條件,CanMatchPreFilterSearchPhase這個(gè)階段只有滿足一定條件時(shí)才會(huì)執(zhí)行,也就是說(shuō)如果不走這個(gè)階段就不會(huì)去檢查分片要不要被 skip。檢查條件在 TransportSearchAction#shouldPreFilterSearchShards中實(shí)現(xiàn),在此不再貼代碼,總結(jié)起來(lái)常見(jiàn)條件包括下面幾個(gè),滿足下列條件之一時(shí),不走 CanMatchPreFilterSearchPhase (暫且稱為“預(yù)過(guò)濾”)流程。

  • 查詢中帶有 Global Aggregation 

  • 查詢中帶有聚合,并且聚合中設(shè)置了:"min_doc_count": 0

  • 待查詢的分片數(shù)小于 128,由查詢參數(shù) pre_filter_shard_size指定。

  • 查詢中使用了 Suggester

解決

找到了可以跳過(guò)“預(yù)過(guò)濾”的條件,問(wèn)題解決問(wèn)題就比較簡(jiǎn)單,有兩種方式不影響現(xiàn)有業(yè)務(wù):

  • 對(duì)于含有聚合請(qǐng)求的查詢,可以在聚合請(qǐng)求中添加 "min_doc_count": 0

  • 對(duì)于不含聚合請(qǐng)求的查詢,可以在請(qǐng)求中調(diào)整pre_filter_shard_size參數(shù),讓他大于待查詢的分片數(shù),

    例如:_search?pre_filter_shard_size=1000

當(dāng)然,也可以統(tǒng)一使用 pre_filter_shard_size 參數(shù)。到此問(wèn)題解決了,skipped 分片消失:

如何分析Elasticsearch中奇怪的查詢命中數(shù)問(wèn)題

在 ES 使用過(guò)程中需要看代碼才能解決問(wèn)題的時(shí)候比較少,但是關(guān)于查詢過(guò)程中分片 skipped 的原理在官方文檔中沒(méi)有具體說(shuō)明,甚至在手冊(cè)中沒(méi)有解釋這個(gè)字段的含義。這次業(yè)務(wù)方使用的 ES 版本為5.6.12,不確定新版本的 ES 是否也存在類似問(wèn)題,未來(lái)抽時(shí)間在新版本上分析一下“預(yù)過(guò)濾”的原理。

上述就是小編為大家分享的如何分析Elasticsearch中奇怪的查詢命中數(shù)問(wèn)題了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI