白话Elasticsearch02- 结构化搜索之filter执行原理bitset机制与caching机制
文章目錄
- 概述
- 步驟
- Step1 在倒排索引中查找搜索串,獲取document list
- Step2 為每個在倒排索引中搜索到的結果,構建一個bitset .
- Step3 遍歷每個過濾條件對應的bitset,優先從最稀疏的開始搜索,查找滿足所有條件的document
- Step4 caching bitset,跟蹤query,在最近256個query中超過一定次數的過濾條件,緩存其bitset
- Step5 filter大部分情況下來說,在query之前執行,先盡量過濾掉盡可能多的數據
- Step6 如果document有新增或修改,那么cached bitset會被自動更新
- Step7 以后只要是有相同的filter條件的,會直接來使用這個過濾條件對應的cached bitset
概述
繼續跟中華石杉老師學習ES,第二篇
課程地址: https://www.roncoo.com/view/55
白話Elasticsearch01- 使用term filter來搜索數據中演示了 term filter的用法,這里我們來剖析下執行原理
步驟
在倒排索引中查找搜索串,獲取document list
為每個在倒排索引中搜索到的結果,構建一個bitset .
遍歷每個過濾條件對應的bitset,優先從最稀疏的開始搜索,查找滿足所有條件的document
caching bitset,跟蹤query,在最近256個query中超過一定次數的過濾條件,緩存其bitset。對于小segment(<1000,或<3%),不緩存bitset。
filter大部分情況下來說,在query之前執行,先盡量過濾掉盡可能多的數據
如果document有新增或修改,那么cached bitset會被自動更新
以后只要是有相同的filter條件的,會直接來使用這個過濾條件對應的cached bitset
接下來逐條來說一下過程
Step1 在倒排索引中查找搜索串,獲取document list
舉個例子 , 上節中用到的 postDate字段,假設有3條數據,在document1 、document2、document3中的分布情況
| 2017-01-01 | 存在 | 存在 | – |
| 2017-02-02 | – | 存在 | 存在 |
| 2017-03-03 | 存在 | 存在 | 存在 |
filter : 2017-02-02
比如:
GET /forum/article/_search {"query": {"constant_score": {"filter": {"term": {"postDate": "2017-02-02"}}}} }發現2017-02-02 對應的 document list 為 doc2 和 doc3 ,這樣就完成了第一步,取到了document list
Step2 為每個在倒排索引中搜索到的結果,構建一個bitset .
這個地方很關鍵,非常重要。
上一步中,獲取到了 document list , ES 會 根據這些document list 構建一個 bitset .
啥是bitset ? bitset是一個二進制的數組, 數組的每個元素要么是0要么是1 , 0 表示不匹配,1 表示匹配。
剛才filter 2017-02-02 的 document list就可以表示為 [0,1,1]
表示
doc1 —>0 , 不匹配該filter
doc2—>1 ,匹配該filter
doc3----> ,匹配該filter
也就是說 這個filter,在整個document中(假設該document只有3條記錄),對應的bitset就是 [0,1,1]
使用二進制數組來標識有什么好處呢? ES本著使用盡可能簡單的su數據結構來實現復雜的功能,節省空間,提高性能。
Step3 遍歷每個過濾條件對應的bitset,優先從最稀疏的開始搜索,查找滿足所有條件的document
在一個search請求中,可以有多個filter條件,每個filter條件都會對應一個bitset。
再獲取到每個filter對應的bitset后 ,遍歷每個filter條件對應的bitset,先從最稀疏的開始遍歷。
啥叫稀疏? 舉個例子
[0, 0, 0, 1, 0, 0]
[0, 1, 0, 1, 0, 1]
上面兩個filter對應的匹配結果狀況,第一個比較稀疏(不匹配的較多,因為0表示不匹配,也就是0越多越稀疏)
先遍歷比較稀疏的bitset,就可以先過濾掉盡可能多的數據
遍歷所有的bitset,找到匹配所有filter條件的doc
舉個例子請求:filter,postDate=2017-01-01,userID=1
postDate: [0, 0, 1, 1, 0, 0]
userID: [0, 1, 0, 1, 0, 1]
遍歷完兩個bitset之后,找到的匹配所有條件的doc,第4個doc均為1 ,均匹配這兩個filter ,就是doc4
就可以將document作為結果返回給client了
Step4 caching bitset,跟蹤query,在最近256個query中超過一定次數的過濾條件,緩存其bitset
比如postDate=2017-01-01這個條件的filter,對應的bitset[0, 0, 1, 1, 0, 0],可以緩存在內存中,這樣下次如果再有這個條件過來的時候,就不用重新掃描倒排索引,反復生成bitset,直接在內存中獲取該filter對應的bitset即可,這樣做可以大幅度提升性能。
在最近的256個filter中,有某個filter超過了一定的次數,次數不固定,就會自動緩存這個filter對應的bitset
filter針對小segment獲取到的結果,可以不緩存,多小的segment算小segment呢? segment記錄數<1000,或者segment大小<index總大小的3%
不緩存小segment的理由:
- 1.segment數據量很小,此時哪怕是掃描也很快;
- 2.segment會在后臺自動合并,小segment很快就會跟其他小segment合并成大segment,此時就緩存也沒有什么意義,segment很快就消失了
filter比query的好處就在于會caching,但是之前不知道caching的是什么東西,實際上并不是一個filter返回的完整的doc list數據結果。而是filter bitset緩存起來。下次不用掃描倒排索引了。
Step5 filter大部分情況下來說,在query之前執行,先盡量過濾掉盡可能多的數據
query:是會計算doc對搜索條件的relevance score,還會根據這個score去排序
filter:只是簡單過濾出想要的數據,不計算relevance score,也不排序
Step6 如果document有新增或修改,那么cached bitset會被自動更新
舉個例子
我們的article document中有4條數據,postDate=2017-01-01這個filter對應的bitset為 [0, 0, 1, 0] , 第三條數據符合這個條件
我們又新增了一條數據,article document加上id=5 ,postDate=2017-01-01,會自動更新到postDate=2017-01-01這個filter的bitset中,全自動,緩存會自動更新。postDate=2017-01-01的bitset就自動變為了[0, 0, 1, 0, 1]
如果我們修改了數值呢? 假設修改document,id=1為postDate=2016-12-30,修改為postDate-2017-01-01,此時也會自動更新bitset,變為[1, 0, 1, 0, 1]
Step7 以后只要是有相同的filter條件的,會直接來使用這個過濾條件對應的cached bitset
以后只要是有相同的filter條件的,會直接來使用這個過濾條件對應的cached bitset
總結
以上是生活随笔為你收集整理的白话Elasticsearch02- 结构化搜索之filter执行原理bitset机制与caching机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 白话Elasticsearch01- 结
- 下一篇: 白话Elasticsearch03- 结