ELK-20180412-讓我們愉快地做 ES 性能調優吧

調優好多次,次次都達不到理想狀態,這次有不一樣的收穫,記錄一下,以示慶祝!

調優分兩個大致的方向吧,一個是對 ELK 集羣進行調優,其中包括 ES 的性能調優,Logstash 數據讀入時調用 bulk API 時的一些參數調優。另一方面,對數據本身的 mappings,field 做調優,遠比想象中效率要提高很多。

應用場景

KFK -> Logstash -> ES

官方建議

本文主要參考官方性能調優,Tune for indexing speedTune for disk usage。實驗環境中部署的是5.5.2,但是基本各版本的調優策略沒有大的變動。我主要需要做的是 index 的調優,所以對 search 性能上有所取捨和犧牲也很正常。

常規的如下,官方鏈接說的很清晰了,本文不細講。

  1. Use bulk requests
  2. Use multiple workers/threads to send data to Elasticsearch
  3. Increase the refresh interval
  4. Disable refresh and replicas for initial loads
  5. Disable swapping
  6. Give memory to the filesystem cache
  7. Use auto-generated ids
  8. Use faster hardware
  9. Indexing buffer size
  10. Additional optimizations
  • Disable the features you do not need
  • Don’t use default dynamic string mappings
  • Disable _all
  • Use best_compression
  • Use the smallest numeric type that is sufficient

詳細說一下,調優過程中特別有感觸的幾條。

Auto generated id 可以省很多時間

讓 ID 自增加,而不是生成 ID 再塞進 ES 集羣,可以不用增加 ES 查詢 ID 唯一性的負擔。當然這個地方也是一個取捨,如果你的業務對於唯一性要求很高,同時對於 index 的時間性能上要求不高,那麼這條索引策略就不是必需的了。

Disable _all 不只是省空間而已

在模版內把所有字段的 _all 都 disable 之後,明顯速度提升 30%。考慮到字段越多,這個 disable _all 的效果應該越明顯。

curl -XPUT http://ES_URL:9200/ES_INDEX/ -d '
{
  "mappings": {
    "ES_TYPE": {
      "_all": {
        "enabled": false   
      }
    }
  }
}'

或者用 template 設置:

"mappings": {
  "_default_": {
    ...
    "_all": {
      "norms": false,
      "enabled": false
    },
    ...
  }
}

如圖:
mappings

影響 Logstash Bulk API Indexing 速度的因素

名稱 字段 輸入/輸出 默認值
Flush size flush_size Output
Flush interval idle_flush_time Output 默認1s
Batch size -b pipeline.batch.size Input 默認125
Worker num -w pipeline.workers Input 默認CPU cores
輸出到es pipeline.output.workers Output 默認1

其中 pipeline.workers * batch_size / flush_size = Logstash 調用 Bulk API 的次數。 flush_size 和 batch_size 和 LS_HEAP_SIZE 是有關係的,並且單次 batch_size 官方建議維持在 10-15M 之間,超過 20M 的多個 document,會被拆分;超過 20M 的單個 document 將被獨立 output 到 ES。

想要知道到底怎樣的 batch_size 和 flush_size 合適,官方給出的建議是,依次等量遞增的嘗試。一般來說,flush_size 不宜超過 pipeline.workers * batch_size 的大小,太大對調優沒有作用。
pipeline.output.workers 這個參數調優的時候,基本沒啥特別貢獻,改日閱讀源碼再來參詳。

其實無非兩種方式,在 logstash 工作的時候,他會等 flush_size 滿了,output 給 ES。那麼如果這個 pool 一直不滿,那麼他就會等到 flush_interval 期滿,把未滿的 pool 中的數據,output 給 ES。

其他

調高 refresh interval

默認 1s,如果業務上對實時性要求沒有那麼高的話,可以調整至 30s。refresh interval 是爲了數據可被搜索到。

index.refresh_interval: 30s

調高 translog interval

translog interval 是爲了保證數據已經成功落盤。

index.translog.sync_interval: 30s
index.translog.durability: async

Logstash 去除無用字段

# in Logstash instance conf
filter {
  mutate {    
    remove_field => "message"
  }
}

pipeline.workers 和 consumer_threads 區別

# in Logstash instance conf
input {  
  kafka {  
    bootstrap_servers => "KFK_SERVERS"
    topics => ["TOPIC"]
    auto_offset_reset => "latest"
    group_id => "GROUP_ID"
    consumer_threads => 1
    codec => "json"
  }
}

事實上 workers 是進程,consumer_threads 是線程,所以建議在本身硬件條件有限制的時候,使用線程。因爲無論是進程還是線程,一個 KFK partition 只能對應一個消費者。一個消費者可以消費多個 KFK partition 中的數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章