天天看點

Elasticsearch索引的基本操作(8)-索引緩存、refresh、flush等操作

1、緩存清理

通過緩存清理的API _cache/clear,需要使用POST方法執行,可以清理指定索引或整個叢集的緩存。

清除單個索引的緩存,操作如下:

POST /new_index/_cache/clear

{}

清除多個索引的緩存,操作如下:

POST /new_index,new_index_2/_cache/clear

{}

清除整個叢集的緩存,操作如下:

POST /_cache/clear

{}

預設不帶要清理的緩存類型參數的情況下,會清理指定索引的所有緩存,也可以通過指定要清理的緩存類型如query, fielddata 或request這些URL參數,并給其設定值true,以達到清除指定緩存的目的,操作如下:

#清除query的緩存

POST /new_index/_cache/clear?query=true

{}

#清除fielddata的緩存

POST /new_index/_cache/clear?fielddata=true

{}

#清除request的緩存

POST /new_index/_cache/clear?request=true

{}

2、flush操作

通過flush重新整理操作,使用GET或POST方法調用_flush API,確定原來隻保留在事務日志(transaction log)中的資料,得以真正的儲存到Lucene索引中。在預設情況下,Elasticsearch會根據自動觸發重新整理,通常使用者不需要直接調用該操作。不過在一些特殊場景之下手動觸發也可以提高效率,如需要重新開機整個叢集,手動執行flush将資料全部寫入到索引中,對後面資料的恢複的速度也有提高,因為索引不需要再從事務日志提取資料用于恢複索引。

重新整理操作可以一次性隻重新整理單個索引,也可以重新整理多個索引,多個索引之間以英文逗号“,”分隔,也可以重新整理所有索引。

重新整理單個索引,操作如下:

GET /new_index/_flush

重新整理多個索引,操作如下:

GET /new_index,new_index_2/_flush

重新整理全部索引,操作如下:

GET /_flush

預設情況下,如果指定索引的某些分片正在執行重新整理操作,則針對這些分片的重新整理操作會抛出異常。可以通過參數對重新整理操作的情況做相應的控制,如下表所示:

參數名稱 說明
wait_if_ongoing

如果設定為true,如有另外一個重新整理操作正在執行,則目前重新整理操作将會阻塞,直到另一個重新整理操作執行完後才執行。

預設為false,如果執行時另外一個重新整理操作正在執行,會以異常的方式執行。

force 設定是否強制執行重新整理,預設不會強制重新整理,隻會在索引有發生變化時執行重新整理。通過強制執行可以增加事務日志的ID,即使索引沒有變化。

3、refresh操作

refresh操作是Elasticsearch實作準實時搜尋和高效率搜尋的保證,通過refresh操作将buffer隊列中的資料寫入到位于OS Cache(OS Cache本身是一塊記憶體區域,操作的速度非常塊)的segment中,這樣存儲資料的segment就可以被搜尋調用了,而不用等到通過耗時的fsync将資料寫入到硬碟中。

Elasticsearch預設執行資料寫入緩存的時間間隔是1秒,這也是Elasticsearch稱為準實時搜尋引擎的來由,根據不同的應用場景,該值可通過settings中的index.refresh_interval參數進行調整。

在Index、Update、Delete、Get和Bulk等操作中,都支援Refresh參數,它支援以下的值:

  1. 空字元串或true:重新整理更改到緩存中,待其執行成功傳回時,被重新整理的更改就可以被搜尋到,重新整理涉及的分片隻是更改發生的主分片和相應的副分片,并不一定是整個索引。

如果頻率的執行refresh=true這樣的操作,可能會導出生成很多很多小的段檔案,這也會給後

期段檔案的合并增加處理時間,因而除了更改被立即搜尋到優點,可能會導緻以下幾個不足:

  1. 生成過多的、小的段檔案;
  2. 搜尋會由于過多的小的段檔案存在,影響搜尋效率;
  3. 後期段檔案的合并,也會增加處理時間;

因而頻繁使用refresh=true這樣的操作,需要仔細考慮,以免得不償失。

  1. wait_for:等待自動重新整理操作的發生,通常該操作不會執行主動重新整理,然後再響應。refresh=wait_for請求通常隻影響其本身,不會影響其它的請求。使用refresh=wait_for的注意事項:
  1. refresh=wait_for會等到重新整理發生後才會響應,過多的使用會導緻索引的操作效率被降低,直接的展現就是TPS上不去;
  2. 不要同時發起過多的refresh=wait_for請求,可将其通過将多個請求合并為單個bulk請求,Elasticsearch會并行處理這些請求,直到所有的請求都執行成功且等到被重新整理後,再統一傳回;
  3. refresh=wait_for的監聽隊列是有長度限制,其受限于系統中參數index.max_refresh_listeners的配置值的影響,預設是1000,如果由于過多的refresh=wait_for請求導緻該除列滿了,則新的wait_for請求不能夠放在該監聽隊列中,就隻能夠立即傳回。由于Elasticsearch對wait_for的設計理念是隻要傳回了就表示已經重新整理了,因而此時就會在傳回前立即觸發重新整理操作,在響應的字段中會增加“"forced_refresh": true”這樣的内容。
  1. false:這個是refresh的預設值,表示不執行重新整理操作,更新的可見由系統自行排程refresh的邏輯控制。

refresh操作可操作單個索引,也可以操作多個索引,多個索引之間以英文逗号“,”分隔,也可以操作所有索引。

refresh單個索引,操作如下:

GET /new_index/_refresh

refresh多個索引,操作如下:

GET /new_index,new_index_2/_refresh

refresh全部索引,操作如下:

GET /_refresh

響應如下:

{

  "_shards" : {

    "total" : 4,

    "successful" : 3,

    "failed" : 0

  }

}

結果顯示需要重新整理操作的分片總共是4個,成功重新整理了3個,失敗了0個,還有1個副本沒有重新整理,是因為目前分片副本處理待配置設定的狀态。将該索引的副本數減少1個後再執行refresh操作,總分片數就變成3個了。

​​​​​​​4、索引強制合并

強制合并的功能為強制合并一個或多個索引,目的是通過索引合并達到減少段的數量,通過POST方法執行_forcemerge API。

強制合并請求在沒有執行完成之前,請求會一直被阻塞,直到執行完成才會傳回,如果期間該HTTP請求由于網絡或者其它原因被斷開,合并請求将繼續在背景執行,直到完成或發生異常結束。如果已經有強制合并正在執行,後續發起的強制合并請求将被會阻塞,直到目前正在執行的合并請求執行完後才執行。

強制合并應該隻針對隻讀索引執行,因為針對可寫的索引執行強制合并,可能會導緻非常大的段檔案生成(每段大于5Gb),且後續的合并政策會自動忽略這樣的大檔案,由于這些檔案後續不能夠執行合并操作,可能導緻該檔案中都是被删除了的文檔,最終導演目前分片中存在非常大的段檔案。

強制合并可以操作單個索引,也可以操作多個索引,多個索引之間以英文逗号“,”分隔,也可以操作所有索引。

強制合并單個索引,操作如下:

POST /new_index/_forcemerge

{}

強制合并多個索引,操作如下:

POST /new_index,new_index_2/_forcemerge

{}

強制合并全部索引,操作如下:

POST /_forcemerge

{}

響應如下:

{

  "_shards" : {

    "total" : 3,

    "successful" : 3,

    "failed" : 0

  }

}

響應顯示待處理的總分片數為3個,成功處理3個,失敗為0個。

上面的示例都沒有帶參數,強制合并API可以接收一些參數,用于調整其行為。

強制合并的參數

參數名稱 說明
max_num_segments 設定需要合并的段數。如果需要整個索引完全合并,則将該值設定為1。預設情況下會檢查合并操作是否需要執行,如果需要才執行,否則就不執行。
only_expunge_deletes

合并過程是否僅操作哪些包含了被删除文檔的段,将這些段中未辨別為删除的内容放到一個新建立的段中,然後将這些包含了被删除文檔的段全部删除。

注:這不會覆寫index.merge.policy.expunge_deletes_allowed門檻值。

flush 是否應在強制合并後執行重新整理,預設為true。

繼續閱讀