天天看點

Elasticsearch 緩存機制

1. 節點查詢緩存(Node Query Cache)

官方文檔簡介

查詢緩存負責緩存查詢的結果。每個節點有一個查詢緩存,由所有分片共享。緩存執行LRU回收政策:當緩存滿時,将回收最近最少使用的資料,為新資料讓路。無法檢視正在緩存的内容。

查詢緩存隻緩存在

filter

上下文中使用的查詢。

詳細介紹

緩存資料結構

緩存分為兩個級别,分别為

Query

Segment

,是以使用的資料結構是一個Map

<Query, Map<Segment, DocIdSet>>

DocIdSet

則使用的是

BitSet

參數說明

indices.queries.cache.size

: 控制

Filter

緩存的記憶體大小,預設為

10%

。接受百分比值(如

5%

)或精确值(如

512mb

)。

indices.queries.cache.count

: 在官方文檔并沒有寫,這是一個節點級别的配置,可以在

elasticsearch.yml

中配置,控制緩存的總數量。如果緩存文檔數量達到了該值,即使緩存大小還沒有達到上限,也沒有辦法再利用了。值得注意的是,如果一個查詢在本節點涉及到多個Segment,那麼實際的cache_size将會是本值與Segment數量的乘積。

indices.queries.cache.all_segments

: 用于是否在所有

Segment

上啟用緩存,預設是

false

,不會對文檔數小于

100000

并且小于整個索引大小的

3%

的Segment進行緩存。

index.queries.cache.enabled

: 控制是否啟用查詢緩存。接受

true

(預設值)或

false

可以被緩存的查詢語句要求

  • 對于

    TermQuery

    MatchAllDocsQuery

    等這種查詢都不被緩存。當

    BooleanQuey

    的位元組點為空時不會被緩存,當

    Dis Max Query

    Disjuncts

    為空時不會被緩存。
  • 對于曆史查詢次數有要求,對于消耗高昂的

    Query

    隻需要

    2

    次就加入緩存,其他的預設是

    5

    次,對于

    BooleanQuery

    DisjunctionMaxQuery

    次數為

    4

    次。

什麼樣的Segment會被緩存

Segment

中文檔數大于

100000

或者大于整個是以大小的

3%

。如果想要索引所有段,可以設定

indices.queries.cache.all_segments

新索引的文檔,緩存會失效或者重新建構嗎

緩存不會失效,而是通過判斷文檔是否符合

Query

的條件,如果符合條件的話則會将文檔加入到

BitSet

中。

案例

檢視ES查詢緩沖情況

傳回結果query_cache部分

"query_cache": {
  "memory_size": "2.5gb",
  "memory_size_in_bytes": 2690321531,
  "total_count": 83881663356,
  "hit_count": 37834074368,
  "miss_count": 46047588988,
  "cache_size": 118427,
  "cache_count": 42784311,
  "evictions": 42665884
}
           

從目前的

query_cache

看,

evictions

cache_size

的360倍,說明

cache_size

過小,導緻緩存倍頻繁淘汰,導緻緩存命中比例較小,可以适當調大

indices.queries.cache.size

大小和

indices.queries.cache.count

2. 字段資料緩存(Field data Cache)

主要用于

sort

以及

aggs

的字段。這會把字段的值加載到記憶體中,以便于快速通路。

field data cache

的建構非常昂貴,是以最好能配置設定足夠的記憶體以保障它能長時間處于被加載的狀态。或者在建立索引時預見到某字段會被用于排序和聚合,而設定文檔值,避免使用

field data cache

一定要注意資料模組化,對于不合理的字段啟用

field data cache

代價非常大,而且性能特别差!

indices.fielddata.cache.size

: 用來控制緩存的大小,支援兩種格式,一種是百分數(代表占節點

heap

的百分比),另一種是精确值(如

10gb

),預設是無限。

3. 分片請求緩存(Shard Request Cache)

Shard

級别的緩存。預設的主要用于緩存

size=0

的請求(

aggs

suggestions

,還有就是

hits.total

)。

每當分片索引

refresh

的時候,如果資料發生了實際變化,那麼緩存就會自動失效。是以

refresh

時間越長,那麼緩存的時間也就越長。緩存采用的也是

LRU

淘汰政策。

緩存是以請求的

JSON

Key

來進行存儲的,那麼也就是說,當同樣含義的不同形式的請求将無法識别緩存。

索引級别禁用緩存

index.requests.cache.enable

: 這個參數用來控制是否啟用分片級别的緩存,預設是

false

請求時禁用緩存

通過

url

傳參方式

request_cache=false

主要的緩存配置

indices.requests.cache.size

用來控制緩存在

heap

中的大小,預設是

1%

4. 索引緩存(Indexing Buffer)

用于緩存新索引的資料,用于緩存新索引的資料,當空間填滿之後,會将資料寫到磁盤上成為一個新的段。它被劃分為節點上的所有分片。以下設定為靜态設定,必須在叢集中的每個資料節點上配置:

indices.memory.index_buffer_size

: 接受百分比或位元組大小值。預設值為

10%

,這意味着配置設定給節點的堆總量的

10%

将被用作跨所有分片共享的索引緩沖區大小。

indices.memory.min_index_buffer_size

: 如果

index_buffer_size

被指定為一個百分比,那麼這個設定可以用來指定一個絕對的最小值。預設為

48mb

indices.memory.max_index_buffer_size

: 如果

index_buffer_size

被指定為一個百分比,那麼這個設定可以用來指定一個絕對最大值。預設為無限。

繼續閱讀