segment 歸併的過程,須要先讀取 segment,歸併計算,再寫一遍 segment,最後還要保證刷到磁盤。能夠說,這是一個很是消耗磁盤 IO 和 CPU 的任務。因此,ES 提供了對歸併線程的限速機制,確保這個任務不會過度影響到其餘任務。服務器
在 5.0 以前,歸併線程的限速配置 indices.store.throttle.max_bytes_per_sec
是 20MB。對於寫入量較大,磁盤轉速較高,甚至使用 SSD 盤的服務器來講,這個限速是明顯太低的。對於 Elastic Stack 應用,社區普遍的建議是能夠適當調大到 100MB或者更高。curl
# 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 狀況更加惡化。url
歸併線程是按照必定的運行策略來挑選 segment 進行歸併的。主要有如下幾條:線程
根據這段策略,其實咱們也能夠從另外一個角度考慮如何減小 segment 歸併的消耗以及提升響應的辦法:加大 flush 間隔,儘可能讓每次新生成的 segment 自己大小就比較大。code
既然默認的最大 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 章節。接口