天天看點

[ElasticSearch2.x]Filter之Cache

過濾器(Filter)的核心實際是采用一個

bitset

記錄與過濾器比對的文檔。當Elasticsearch确定一個bitset可能會在将來被重用時,它将被直接緩存在記憶體中供以後使用。一旦緩存,這些

bitset

可以在使用相同查詢的任何地方重複使用,而無需再次重新評估整個查詢。

這些緩存的bitset是非常“機智”的:它們是增量更新的。 在索引新文檔時,隻需要将那些新文檔添加到現有的

bitset

中,而不必一遍一遍地重新計算全部已經緩存的過濾器(rather than having to recompute the entire cached filter over and over. )。 過濾器與系統的其餘部分都是實時的,不需要擔心緩存過期問題。

https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB0184dc8c66cd53d476344d728a1e1049%3Fmethod%3Ddownload%26read%3Dtrue#1-%E7%8B%AC%E7%AB%8B%E7%9A%84%E6%9F%A5%E8%AF%A2%E7%BC%93%E5%AD%98query-caching 1. 獨立的查詢緩存(Query Caching)

屬于一個查詢元件的

bitsets

獨立于搜尋請求的其他部分(The bitsets belonging to a query component are independent from the rest of the search request)。 這意味着,一旦緩存,可以在多個搜尋請求中重複使用查詢。 它不依賴于它所存在的查詢上下文。 這樣使得緩存可以加速查詢中經常使用的部分,而不會在較少或易變部分浪費開銷。

類似地,如果單個搜尋請求重複使用相同的非評分查詢,則其緩存的

bitset

可以重用于單個搜尋請求内的所有執行個體。

我們來看看下面這個示例查詢,它查找以下任何一個電子郵件:

  • 在收件箱中,且沒有被讀過的
  • 不在 收件箱中,但被标注重要的
GET /inbox/emails/_search
{
  "query": {
      "constant_score": {
          "filter": {
              "bool": {
                 "should": [
                    { "bool": {
                          "must": [
                             { "term": { "folder": "inbox" }}, 
                             { "term": { "read": false }}
                          ]
                    }},
                    { "bool": {
                          "must_not": {
                             "term": { "folder": "inbox" } 
                          },
                          "must": {
                             "term": { "important": true }
                          }
                    }}
                 ]
              }
            }
        }
    }
}           

使用SQL語句描述:

SELECT emails
FROM inbox
WHERE (folder='inbox' and read = false) or (folder != 'inbox' and important = true)           

上面兩個查詢是相同的,并且将使用相同的

bitset

盡管一個inbox子句是一個must子句,另一個是一個must_not子句,但是這兩個子句本質上是一樣的。如果這個特定

term

查詢先前已被緩存過,那麼盡管這兩個子句使用不同樣式的布爾邏輯,也都将受益于緩存表示(If this particular term query was previously cached, both instances would benefit from the cached representation despite being used in different styles of boolean logic)。

這點與查詢表達式的組合性很好的相關聯。 可以輕松地移動過濾查詢,或在搜尋請求中的多個位置重複使用相同的查詢。 這對開發人員來說不僅友善,而且具有直接的性能優勢。

https://note.youdao.com/md/preview/preview.html?file=%2Fyws%2Fapi%2Fpersonal%2Ffile%2FWEB0184dc8c66cd53d476344d728a1e1049%3Fmethod%3Ddownload%26read%3Dtrue#2-%E8%87%AA%E5%8A%A8%E7%BC%93%E5%AD%98autocaching-behavior 2. 自動緩存(Autocaching Behavior)

在舊版本的Elasticsearch中,預設行為是緩存可緩存的所有内容。 這通常意味着系統緩存的

bitset

太冒進,在清理緩存時會給性能帶來沖擊。 此外,許多過濾器可以非常快速地進行評估,但是緩存(從緩存重用)的速度要慢的多。 這些過濾器沒有必要進行緩存,因為再次重新執行過濾器都比從緩存重用快。

檢查一個反向索引是非常快的,但是絕大多數查詢元件卻很少使用它(Inspecting the inverted index is very fast and most query components are rare.)。例如 在 "user_id"字段上的

term

 過濾 :如果有上百萬的使用者,每個具體的使用者 ID 出現的機率都很小。那麼為這個過濾器緩存

bitsets

 就不是很合算,因為緩存的結果在重用之前很可能就被剔除了。

這種緩存流失(cache churn )可能會對性能造成嚴重影響。 更糟糕的是,開發人員很難确定哪些元件具有良好的緩存行為,哪些元件的緩存行為沒有用處。

為了解決這個問題,Elasticsearch會根據使用頻率自動緩存查詢。 如果一個非評分查詢在最近的256次查詢中使用了多次(取決于查詢類型),則該查詢是被候選緩存。但是,并不是所有段都保證緩存

bitset

。 隻有擁有超過10,000個文檔的分段(或占文檔總數的3%以上)将緩存

bitset

。 因為小段可以快速的搜尋和合并,是以在這種情況下緩存

bitset

是沒有意義的。

一旦緩存,非評分計算的

bitset

會一直駐留在緩存中直到它被剔除。剔除規則是基于 LRU 的:一旦緩存滿了,最近最少使用的過濾器會被剔除。

原文:

https://www.elastic.co/guide/en/elasticsearch/guide/current/filter-caching.html#_autocaching_behavior https://www.elastic.co/guide/en/elasticsearch/guide/current/filter-caching.html#_autocaching_behavior