查詢結果取交集_Elasticsearch 查詢過程中的 prefilter 原理

大家都知道在對索引執行查詢的時候,需要在所有的分片上執行查詢,因為無法知道被查詢的關鍵詞位于哪個分片,對于全文查詢來說誠然如此,然而對于時序型的索引,當你從 my_index-* 中執行 now-3d 的范圍查詢時,可能很多分片上都不存在被查詢的數據范圍,因此 es 從 v5.6 開始引入了 pre-filter 機制:對于 Date 類型的 Range 查詢,在對分片執行搜索之前,先檢查一下分片是否包括被查詢的數據范圍,如果查詢的范圍與分片持有的數據沒有交集,就跳過該分片。

分布式搜索過程原先由兩個階段執行:查詢階段和取回階段,在引入了 pre-filter 之后,分布式搜索過程變成了三個階段:預過濾階段(pre-filter)、查詢階段和取回階段。pre-filter 在查詢階段之前執行。

協調節點收到客戶端的查詢請求后,向本次搜索涉及到的全部分片發送RPC 請求:

indices:data/read/search[can_match]

這次 RPC 請求以 shard 為單位并行發送,沒有并發限制。待查詢的 shard 有多少個,就并發發送多少個 RPC。然后等待全部 RPC 返回響應。

tips
此時發送的 RPC 請求沒有超時限制。事實上,_search 請求的 timeout參數僅在整個分布式搜索的 query 階段進行檢查,并且不包括 PRC 層面,他只在數據節點收到協調節點發來的 RPC 后開始計時,檢查 query 過程是否超時。fetch 階段的 RPC,以及數據節點對 fetch 請求的處理均沒有超時檢查。

節點收到請求后,判斷請求的范圍和待查詢的分片是否存在交集,返回是或否,然后協調節點跳過不存在交集的分片,向其他分片發送下一階段(查詢階段)的請求。

本次查詢跳過了多少分片可以通過查詢結果中的?skipped?字段看到,如:

"_shards":{
"total": 130,
"successful": 130,
"skipped": 129,
"failed": 0
}

同時也來看一下手冊對 skipped 字段的解釋:

skipped
(Integer) Number of shards that skipped the request because a lightweight check helped realize that no documents could possibly match on this shard. This typically happens when a search request includes a range filter and the shard only has values that fall outside of that range.

什么情況下會執行 pre-filter

pre-filter 并不會在所有查詢過程中執行,在 v7.4中,需要同時滿足以下條件,才會執行 pre-filter :

  • 待查詢的分片數大于 128(pre_filter_shard_size指定)

  • 聚合請求不要求訪問所有 doc。即非 Global Aggregation 或?"min_doc_count" 不為0

另外,非 Date 類型的數值查詢雖然也會走 pre-filter流程,但內部不會去判斷范圍,雖然協調節點也會發送 can_match 的 RPC,但數據節點的響應會在 MappedFieldType#isFieldWithinQuery 中直接返回相交,所以沒有分片會被 skip,未來這方面可能會有擴展。

pre-filter 實現原理

數據節點判斷某個 Range 查詢與分片是否存在交集,依賴于 Lucene 的一個重要特性:PointValues 。在早期的版本中,數值類型在 Lucene 中被轉換成字符串存入倒排索引,但是由于范圍查詢效率比較低,從 Lucene 6.0開始,對于數值類型使用 BKD-Tree 來建立索引,內部實現為 PointValues。PointValues原本用于地理位置場景,但它在多維、一維數值查詢上的表現也很出色,因此原先的數值字段(IntField,LongField,FloatField,DoubleField)被替換為(IntPoint,LongPoint,FloatPoint,DoublePoint)

關于 BKD-Tree 的性質請參閱其他資料,暫且只需要知道 Lucene為每個字段單獨建立索引,對于數值字段生成 BKD-Tree,一個新的 segment 生成時會產生一個新的.dim和.dii文件。最重要的,可以獲取到這個 segment 中數值字段的最大值和最小值,為 pre-filter 提供了基礎。當 segment 被 reader 打開的時候,Lucene 內部的 BKDReader 會將最大值和最小值讀取出來保存到類成員變量,因此每個 segment 中,每個數值字段的最大最小值都是常駐 JVM 內存的。

既然每個 segment 記錄了數值字段的取值范圍,獲取shard 級別的范圍就輕而易舉:PointValues.getMaxPackedValue(),PointValues.getMinPackedValue(),函數遍歷全部的 segment 分別計算最大值和最小值,然后根據查詢條件判斷是否存在交集,在 DateFieldMapper.DateFieldType#isFieldWithinQuery 函數中:

c2ccb1841897f0742811de86d983b880.png

既然數值類型都可以獲取分片級別的范圍,為什么 pre-filter 只在 Date 類型的Range 查詢里實現了,而其他的數值類型的 Range 查詢不會走 pre-filter 流程?原因也非常簡單,只有 Date 類型的數值確定是遞增的,其他數值類型未必。對于非遞增的數值字段,其數據會散布到 my_index-* 的每個分片上,因此 pre-filter 也就沒有必要了。如果你有另外一個遞增的數值字段,目前也沒有配置的方式來使用 pre-filter。

題外話:BKD-Tree 的每個節點都記錄了節點自己的maxPackedValue、minPackedValue

Lucenene 內部查詢的也會按照 segment file 級別跳過

現在我們忘掉 es,討論數值類型查詢在 Lucene 內部的實現。

HBase 的寫入模型和 Lucene 類似,先寫內存,然后刷盤生成 HFile,HFile 合并成大文件。由于 HBase 使用時間戳作為數據版本號,因此每個 HFile 都記錄了時間范圍。因此查詢的時候如果指定時間范圍,就可以過濾掉大量的 HFile 不用查詢。這么優秀的操作在 Lucene 中也必不可少。

在一個 Lucene 索引中可能有很多 segment,Lucene遍歷所有的 segment 進行處理,在對每個 segment 的 weight.bulkScorer過程中,BKDReader.intersect函數根據相交情況決定收集符合條件的 docid,如果查詢條件和 segment 沒有交集,就什么都不做。

c4a0f47f7d24d82182775e07fceb5868.png

因此當對數值類型查詢的時候,不在范圍的 segment 會直接跳過,Lucene 內部稱為:CELL_OUTSIDE_QUERY

但是,段合并的時候目前還不會考慮按時間臨近的方式進行合并,因此借鑒 HBase 的思想按照時間臨近的段進行合并有助于降低數值類型的范圍查詢耗時。

思考

既然 Lucene 對數值類型有 segment 級別的skip,Elasticsearch 實現的分片層面的 pre-filter 還有必要存在嗎?他可以讓搜索延遲更低么?我們實際測試來說話。過程如下:

生產集群有 filebeat-* 索引,數據為 nginx 日志,大約8T,有180個shard,11227個 segment,分布在3個節點。

step1:我們對 date 字段執行一個不會命中的查詢,讓他走 pre-filter 流程:

POST filebeat-7.4.2-*/_search
{
"size":0,
"query": {
"range": {
"@timestamp": {
"gte": "2021-01-01",
"lte":"2022-01-01"
}
}
}
}

返回結果摘要如下,整個過程執行了31ms:

{
"took" : 31,
"timed_out" : false,
"_shards" : {
"total" : 180,
"successful" : 180,
"skipped" : 179,
"failed" : 0},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"}}

step2:現在加上 ?pre_filter_shard_size=1000 參數重新查詢,其他條件不變,讓查詢過程不走 pre-filter,返回結果如下,整個過程執行了31ms,可見沒什么區別:

{
"took" : 23,
"timed_out" : false,
"_shards" : {
"total" : 180,
"successful" : 180,
"skipped" : 0,
"failed" : 0},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"}}}

step3:最后我們對 long 字段執行 range 查詢,這樣也不走 pre-filter 流程:

POST filebeat-7.4.2-*/_search?size=0
{
"query": {
"range": {
"nginx.bytes.body_sent": {
"gte": -2,
"lte":-1
}
}
}
}

這次查詢執行了50ms,還是在一個數據級。

{
"took" : 50,
"timed_out" : false,
"_shards" : {
"total" : 180,
"successful" : 180,
"skipped" : 0,
"failed" : 0},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"}}}

因此 pre-filter并不會降低查詢延遲,在和官方聊過之后,他們的想法是 pre-filter 最主要的作用不是降低查詢延遲,而是 pre-filter 階段可以不占用search theadpool,減少了這個線程池的占用情況。個人感覺這個收益并不大。不過未來會在這個階段做更多的查詢優化, 例如7.6中放出的 #49092,#48681

特別感謝:陸徐剛@螞蟻

基于:Elasticsearch 7.4 & 7.6

參考

https://github.com/elastic/elasticsearch/pull/25658
https://www.amazingkoala.com.cn/Lucene/Search/2020/0427/135.html
https://lucene.apache.org/core/6_2_1/core/org/apache/lucene/index/PointValues.html
http://www.nosqlnotes.com/technotes/searchengine/lucene-invertedindex-3/
https://www.jianshu.com/p/39eb0d66d082
https://cloud.tencent.com/developer/article/1366835
https://www.elastic.co/guide/en/elasticsearch/reference/current/release-notes-7.6.0.html#

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530048.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530048.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530048.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機專業人畢業設計外文翻譯,計算機專業畢業設計外文翻譯.doc

《計算機專業畢業設計外文翻譯.doc》由會員分享,提供在線免費全文閱讀可下載,此文檔格式為doc,更多相關《計算機專業畢業設計外文翻譯.doc》文檔請在天天文庫搜索。1、近幾年來,隨著計算機的普及和建筑電子產業的發展…

語音識別插件_AnsweringMachine XS: 越獄理由之二,iPhone 電話語音答錄機

Apps & Tweaks| Jailbreak Guide| iDevicesTweak:AnsweringMachine XSVersion:XSRepo:http://limneos.net/iOS Support:12-13Price:3.99iOS 開發人員 Elias Limneos 開發了電話輔助系列插件,AnsweringM…

怎么在計算機里找到CF里保存的視頻,電腦怎么查看穿越火線錄制保存視頻?操作方法...

在Win10電腦上玩穿越火線,遇到精彩時刻我們都會錄制下,好跟朋友分享,但是在Win10電腦上穿越火線錄制保存之后的視頻,在哪看呢?有很多用戶都不知道怎么在Win10電腦查看這個穿越火線錄制保存的視頻,這個的話&#xff0c…

ironpython this_IronPython sys._getframe not found

問題Im currently building a program in C# which will call functions in provided python script files.Some of these script files calls _getframe() in sys, which results in the error:System.MissingMemberException: module object has no attribute_getframe(Since…

計算機賬務處理流程圖,賬務處理流程圖

手工業務流程圖賬務處理流程主要有 5 種形式:記賬憑證核算形式、科目匯總表核算形式、匯總記賬憑證核算形式、日記總賬核算形式、和多欄式日記賬核算形式。不同的賬務處理流程其差別主要體現在登記總賬的方法和依據不同,其中科目匯總表核算形式最為常見&…

css滑動門的用處,CSS滑動門是什么?有什么用處?[web前端培訓]

在制作網頁導航時,經常會碰到導航欄長度不同,但背景相同的情形。此時如果通過拉伸背景圖的方式來適應文本內容,就會造成背景圖變形。在制作網頁時,為了使各種特殊形狀的背景能夠自適應元素中的文本內容,并且不會變形&a…

vue 父鏈和子組件索引_vuejs填坑-父子組件之間的訪問

有時候我們需要父組件訪問子組件,子組件訪問父組件,或者是子組件訪問根組件。1. 父組件訪問子組件 $children或$ref$children 返回所有子組件的實例,是一個數組顯示兩個組件的信息{{ msg }}{{ msg }}Vue.component(child1, {template: #child…

python多線程爬取多個網頁_python多線程爬取網頁

#-*- encoding:utf8 -*-‘‘‘Created on 2018年12月25日author: Administrator‘‘‘from multiprocessing.dummy import Pool as plimport csvimport requestsfrom lxml import etreedef spider(url):header {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WO…

layui 分頁ajax,實現Ajax異步的layui分頁

頁面代碼:人才推薦姓名學歷技能經驗住址聯系方式 ${res}${data}于千萬年之中時間的無涯的荒野里…時間的無涯的荒野里…--%>js代碼//加載完成$(function(){var sherchkey${positioninfo.name};savePosition();//保存修改方法getPeopleList(1,5,sherchkey);//獲取人才列表// …

Gen系列服務器,新計算、新體驗 | 新華三全新HPE Gen10系列服務器響徹“云”端

數字經濟時代的數據中心正在加速向云計算融合,用戶將面臨傳統架構與云架構并存的混合IT模式。如何既擁有專有數據中心對數據完全可控以及對關鍵業務充分優化的優勢,又能擁有云計算的靈活彈性?如何有效利舊并滿足混合IT架構的需求?…

python 異常處理 變量_Python基礎入門:從變量到異常處理

一 . 條件語句1.if-else 語句當if語句后的條件結果表達式為假&#xff0c;則執行else 語句后的代碼。如若輸入數字非666&#xff0c;則會輸出“猜錯了&#xff0c;小姐姐現在心里想的為666“2.if 語句支持嵌套hi6 hi>2 執行 if hi>7 6<7 所以無輸出hi1 hi<2 執行 p…

web系統四層結構中服務器端,基于.NET平臺構建四層B/S結構的動態網站

摘要&#xff1a;Web是基于Internet技術的一種應用層服務,具有后臺數據庫支持的n層B&#xff0f;S結構已經成為動態Web應用的主流。雖然動態網站開發工作的主要是進行服務器端應用程序的開發,但是B&#xff0f;S結構動態Web的應用要涉及瀏覽器、Web服務器、服務器端應用程序、數…

收藏功能_微軟Edge獲得了新的收藏夾菜單、PDF功能等

作為其今年早些時候概述的戰略的一部分&#xff0c;微軟Edge現在正在向所有Windows 10 PC推出。與經典的Edge不同&#xff0c;Chromium Edge與任何特定的Windows更新無關&#xff0c;但微軟又開始為該瀏覽器進行了一系列令人興奮的改進。新的Edge基于Chromium&#xff0c;它還帶…

服務器LIMIT是什么信號,Postfix添加milter-limit配置方案

[安裝環境]操作系統&#xff1a;CentOS 5.6MAT&#xff1a;POSTFIX2.8.4安裝之前必須保證POSTFIX能正常收發信如果已經安裝過Berkeley Db3以上版本可以不安裝新的DB(但是注意引入db.so)[安裝步驟]1、milter-limit-0.14.tar.gz及libsnert-1.71.6.tar.gz包的獲取方法需要創建一個…

數據存儲方式_視頻監控系統的數據存儲方式的概念及應用

DAS&#xff1a;直連存儲&#xff0c;直連式存儲與服務器主機之間的連接通常采用SCSI連接&#xff0c;SCSI通道是IO瓶頸;服務器主機SCSI ID資源有限&#xff0c;能夠建立的SCSI通道連接有限。無論直連式存儲還是服務器主機的擴展&#xff0c;從一臺服務器擴展為多臺服務器組成的…

ubuntu18 防火墻關閉_Ubuntu 18.04 關閉及開啟防火墻

Ubuntu 內建使用 UFW (Uncomplicated Firewall) 作為防火墻管理工具, 一般情況下都會開啟防火墻, 但有些特殊情況, 例如測試環境需要關閉防火墻作測試, 或者對網絡設定進行除錯等。以下是在 Ubuntu 18.04 關閉防火墻的方法。首先檢查目前防火墻是否已經開啟, 執行以下指令:$ su…

vue從url中獲取token并加入到 請求頭里_輕流amp;amp;企業微信——獲取打卡數據...

企業微信開放了打卡應用的api&#xff0c;功能包括查詢打卡數據&#xff0c;能獲取到用戶、地點、時間、打卡類型等信息&#xff0c;在輕流中可以基于以上數據做一段時間內的遲到/事假等統計&#xff0c;以及更深層數據處理&#xff0c;方便管理。第一步&#xff1a;獲取access…

單片機串口通信學號顯示_觸摸屏與單片機串口通信測試

工業現場在使用觸摸屏的時候&#xff0c;與第三方控制器進行通信連接的時候&#xff0c;一般都是使用成熟的通信協議進行通信連接。而這些協議的實現過程&#xff0c;觸摸屏廠商也已經在編程環境中進行了封裝集成&#xff0c;對于使用的工程師來說&#xff0c;通信的數據交換過…

2020筆記本性價比之王_2020輕薄本性價比之王_2020輕薄本哪款好

隨著科技的進步&#xff0c;如今筆記本的功能愈發強大&#xff0c;接聽電話、開展商務會議等&#xff0c;因此現在人們對于筆記本電腦的依賴程度愈發明顯。厚重的商務本和游戲本顯然不適合隨身攜帶&#xff0c;因此輕薄本的出現受到白領們的廣泛吹捧&#xff0c;那么2020哪款輕…

scp命令默認傳輸速度多大_每天一個linux命令(60):scp命令

scp是secure copy的簡寫&#xff0c;用于在Linux下進行遠程拷貝文件的命令&#xff0c;和它類似的命令有cp&#xff0c;不過cp只是在本機進行拷貝不能跨服務器&#xff0c;而且scp傳輸是加密的。可能會稍微影響一下速度。當你服務器硬盤變為只讀 read only system時&#xff0c…