天天看點

elasticsearch5.3.0 bulk index 性能調優實踐

導語: 騰訊雲CDN上每天産生大量回源日志,回源日志通常用在問題定位的時候比較有用。這裡使用filebeat+logstash+elasticsearch的方案收集、存儲日志資料并提供查詢。目前的使用場景裡,每天有70億條日志需要存儲,屬于寫多讀少的場景。本文整理了在搭建elasticsearch叢集的時候需要注意的配置項,通過對這些配置項的調整,期望提高elasticsearch寫入的性能。

master node: 3台

data node: TS60*10

client node: 2台

未進行配置優化之前,ES叢集負載非常高,主要表現在磁盤IO上,寫入的qps在2萬/s左右

為了提高寫入的性能,筆者搜集了官方文檔以及一些資料,有如下優化措施。

優化點: 減少重新整理頻率,降低潛在的寫磁盤性能損耗

官網解釋: How often to perform a refresh operation, which makes recent changes to the index visible to search. Defaults to 1s. Can be set to -1 to disable refresh.

優化點: 減少寫磁盤的頻率

<code>python { "index": { "translog": { "flush_threshold_size": "1gb", "sync_interval": "30s", "durability": "async" } } }</code>

Lucene隻有在commit的時候才會把之前的變更持久化存儲到磁盤(每次操作都寫到磁盤的話,代價太大),在commit之前如果出現故障,上一次commit之後的變更都會丢失

為了防止資料丢失,Lucene會把變更操作都記錄在translog裡,在出現故障的時候,從上次commit起記錄在translog裡的變更都可以恢複,盡量保證資料不丢失

Lucene的flush操作就是執行一次commit,同時開始記錄一個新的translog,是以translog是用來記錄從上次commit到下一次commit之間的操作的

flush操作的頻率是通過translog的大小控制的,當translog大小達到一定值的時候就執行一次flush,對應參數為index.translog.flush_threshold_size,預設值是512mb,這裡調整為1gb,減少flush的次數

translog本身是檔案,也需要存儲到磁盤,它的存儲方式通過index.translog.durability和index.translog.sync_interval設定。預設情況下,index.translog.durability=request,意為每次請求都會把translog寫到磁盤。這種設定可以降低資料丢失的風險,但是磁盤IO開銷會較大

這裡采用異步方式持久化translog,每隔30秒寫一次磁盤

優化點: 放開merge操作,加快合并,防止因為merge滞後導緻index操作被限速

1.4的文檔關于這個參數的解釋:

index操作首先會生成很多小的segment,會有異步邏輯合并(merge)這些segment

merge操作比較消耗IO,當系統IO性能比較差的時候,merge會影響查詢和索引的性能。

index.store.throttle.type和index.store.throttle.max_bytes_per_sec可以在節點級或者index級限制merge操作消耗的磁盤帶寬,防止因為merge導緻磁盤高負載,影響其他操作

另一篇關于ES2.x index調優的文章裡講到,如果不關心查詢的性能,可以把index.store.throttle.type設為none,意為不對merge操作限速

這個參數預設配置是針對merge操作限制使用磁盤帶寬20MBps

優化點: 減少并發并發merge對磁盤的消耗

index由多個shard組成,每個shard又分成很多segment,segment是index資料存儲的最小機關

執行索引操作時,ES會先生成小的segment

segment比較多的時候會影響搜尋性能(要查詢很多segment),ES有離線的邏輯對小的segment進行合并,優化查詢性能。但是合并過程中會消耗較多磁盤IO,會影響查詢性能

index.merge.scheduler.max_thread_count控制并發的merge線程數,如果存儲是并發性能較好的SSD,可以用系統預設的max(1, min(4, availableProcessors / 2)),普通磁盤的話設為1

優化點: 降低被動寫磁盤的可能性

該配置項指定了用于索引操作的記憶體大小,索引的結果先存在記憶體中,緩存空間滿了的話,緩存的内容會以segment為機關寫到磁盤。顯然,增大緩存空間大小可以降低被動寫磁盤的頻率

index refresh(不确定有沒有寫磁盤,待确認)

Lucene flush

translog persistant

index buffer不足導緻被動寫磁盤

segment merge

關于segment merge有兩個調整,(1)減少并發merge的線程數,(2)放開merge的磁盤帶寬限制。這裡猜測是因為,merge操作是要做的,但是并發的merge比較耗磁盤IO,折中的方案是減少并發,加強單線程merge

以上配置全部用上之後,叢集負載瞬間降低了,但是不清楚是哪個配置,或者哪些配置的影響比較大,下面通過測試确認了這些配置的影響

使用現網流量進行測試

将上述全部優化項啟用的時候作為基準,分别禁用單個優化項,觀察ES寫入性能和叢集負載

對比組

時間

qps

負載

說明

基準

14:30~15:00

61685

3

-

并發merge線程數設為預設(15:09)

15:30~16:00

64831

剛修改配置qps有個小凸尖,随後平穩

禁用translog優化(16:07)

16:12~16:22

18399

39

qps暴跌,負載猛增

refresh interval使用預設值1s(16:28)

16:31~17:01

57012

5

qps比基準微降,負載微曾

開啟merge限流(17:05)

17:10~17:20

61862

2.5

和基準持平

按照所有優化項開啟的設定,使用python api開啟多線程向ES叢集發起bulk index請求,同時觀察kibana monitor界面,發現index qps達到30w/s,随後叢集很快挂掉。

以上測試可以看到

translog優化禁用的時候叢集負載最高,寫入性能最差

index refresh操作對寫入的性能略有影響

segment merge對寫入性能影響非常小

以上歡迎各位交流,有不合理的地方歡迎指正[抱拳]