Elasticsearch-07-ES中的緩存


3.7 ES中的緩存

Elasticsearch在運行過程中會使用到各種各樣的緩存,如Query cache、Request cache、page cache、fielddata。這里主要討論Query cache 和 Request cache

3.7.1 Shard Request Cache

1)簡介

顧名思義,這是分片級別的緩存。緩存采用LRU機制,key包含shard、indexreader、查詢請求的信息,value是查詢結果序列化之后的數據。

由於客戶端查詢請求會被序列化之后作為key的一部分,所以有可能同樣的查詢、json內容順序不同等變化都會導致無法命中緩存

由於這是分片級別的緩存,所以當新的段寫入到分片后,原有的緩存將會失效

2)緩存策略

不是所有的查詢請求都會被緩存。在IndicesService#canCache中定義了哪些請求時不能被緩存的。不被緩存的情況有

  • 使用了scroll滾動查詢
  • 查詢類型不是QUERY_THEN_FETCH
  • 帶有分析的查詢,設置了profile屬性
  • 設置不需要緩存
  • 范圍查詢中帶有now的。這種查詢是毫秒級別的,緩存沒有意義
3)配置項與監控api
  • indices.requests.cache.size:設置緩存占用堆空間的大小,默認是1%

  • index.requests.cache.enable:緩存開關

  • GET /_nodes/stats/indices/request_cache?human

3.7.2 Node Query Cache

1)簡介

相比於Shard Request Cache這種分片級別的緩存,Node Query Cache就只緩存filter中過濾的結果。所以,Node Query Cache又被稱為Filter Cache。

Filter查詢和普通查詢最主要的區別就是不會計算評分

它可以緩存不同查詢之間使用到重復數據的部分。比如說張三查詢了近一個月內火腿腸的銷量,李四查詢了近一個月內火腿腸不合格的數量。這兩次查詢的共同之處是時間范圍都是一個月內。而Node Query Cache會在第一次查詢時對近一個月內的數據打上標記,在下一次查詢的時候只去搜索這些打過標記的數據。

這種緩存是Lucene中實現的,ES主要進行的是策略控制。

2)工作原理

Node Query Cache使用位圖這種數據結構來對數據進行標記。首先創建一個大小為maxDoc(文檔數量)的位圖:FixedBitSet。然后在遍歷過程中對命中的文檔在位圖對應位置做標記。例如,[1,2,7]位置的文檔命中了查詢條件,那么對應的位圖則為[1,1,0,0,0,0,1]。當一個查詢中有多個filter條件時,只需要做位運算即可快速准確的找到命中的文檔

3)緩存策略

ES使用UsageTrackingQueryCachingPolicy作為默認的緩存策略。這個策略的主要關注點是:

  • 是不是特定類型的查詢。如term query(精確查詢)、MatchAllDocsQuery、MatchNoDocsQuery。以及子查詢為空的BooleanQuery、DisjunctionMaxQuery
  • 某條 query 的訪問頻率大於等於特定閾值之后,該 query結果才會被緩存。對於訪問頻率,主要分為2類,一類是訪問2次就會被緩存,包括: MultiTermQuery、MultiTermQueryConstantScoreWrapper、TermInSetQuery、PointQuery 在 isCostly方法中定義。其余類型的查詢訪問5次會被緩存。

如何統計某個query的頻率?

Lucene中維護了一個長度為256的環形buffer。每個查詢在被hash之后保存進去。因此,上面的頻率可以理解為最近256次查詢中出現的頻率

4)配置項與監控
  • indices.queries.cache.count,緩存查詢的數量,默認是1w
  • indices.queries.cache.size,緩存占堆內存的大小,默認是10%
  • GET /_nodes/stats/indices/query_cache?human


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM