es的forcemerge——按照天分割


歸並線程配置

segment 歸並的過程,需要先讀取 segment,歸並計算,再寫一遍 segment,最后還要保證刷到磁盤。可以說,這是一個非常消耗磁盤 IO 和 CPU 的任務。所以,ES 提供了對歸並線程的限速機制,確保這個任務不會過分影響到其他任務。

在 5.0 之前,歸並線程的限速配置 indices.store.throttle.max_bytes_per_sec 是 20MB。對於寫入量較大,磁盤轉速較高,甚至使用 SSD 盤的服務器來說,這個限速是明顯過低的。對於 Elastic Stack 應用,社區廣泛的建議是可以適當調大到 100MB或者更高。

# curl -XPUT http://127.0.0.1:9200/_cluster/settings -d'
{
    "persistent" : {
        "indices.store.throttle.max_bytes_per_sec" : "100mb"
    }
}'

5.0 開始,ES 對此作了大幅度改進,使用了 Lucene 的 CMS(ConcurrentMergeScheduler) 的 auto throttle 機制,正常情況下已經不再需要手動配置 indices.store.throttle.max_bytes_per_sec 了。官方文檔中都已經刪除了相關介紹,不過從源碼中還是可以看到,這個值目前的默認設置是 10240 MB。

歸並線程的數目,ES 也是有所控制的。默認數目的計算公式是: Math.min(3, Runtime.getRuntime().availableProcessors() / 2)。即服務器 CPU 核數的一半大於 3 時,啟動 3 個歸並線程;否則啟動跟 CPU 核數的一半相等的線程數。相信一般做 Elastic Stack 的服務器 CPU 合數都會在 6 個以上。所以一般來說就是 3 個歸並線程。如果你確定自己磁盤性能跟不上,可以降低index.merge.scheduler.max_thread_count 配置,免得 IO 情況更加惡化。

歸並策略

歸並線程是按照一定的運行策略來挑選 segment 進行歸並的。主要有以下幾條:

  • index.merge.policy.floor_segment 默認 2MB,小於這個大小的 segment,優先被歸並。
  • index.merge.policy.max_merge_at_once 默認一次最多歸並 10 個 segment
  • index.merge.policy.max_merge_at_once_explicit 默認 forcemerge 時一次最多歸並 30 個 segment。
  • index.merge.policy.max_merged_segment 默認 5 GB,大於這個大小的 segment,不用參與歸並。forcemerge 除外。

根據這段策略,其實我們也可以從另一個角度考慮如何減少 segment 歸並的消耗以及提高響應的辦法:加大 flush 間隔,盡量讓每次新生成的 segment 本身大小就比較大。

forcemerge 接口

既然默認的最大 segment 大小是 5GB。那么一個比較龐大的數據索引,就必然會有為數不少的 segment 永遠存在,這對文件句柄,內存等資源都是極大的浪費。但是由於歸並任務太消耗資源,所以一般不太選擇加大 index.merge.policy.max_merged_segment 配置,而是在負載較低的時間段,通過 forcemerge 接口,強制歸並 segment。

# curl -XPOST http://127.0.0.1:9200/logstash-2015-06.10/_forcemerge?max_num_segments=1

由於 forcemerge 線程對資源的消耗比普通的歸並線程大得多,所以,絕對不建議對還在寫入數據的熱索引執行這個操作。這個問題對於 Elastic Stack 來說非常好辦,一般索引都是按天分割的。更合適的任務定義方式,請閱讀本書稍后的 curator 章節。


免責聲明!

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



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