問題背景
ES使用bulk寫入時每批次的大小對性能有什么影響?設置每批次多大為好?
一般來說,在Elasticsearch中,使用bulk API進行批量寫入時,每批次的大小對性能有著顯著的影響。具體來說,當批量請求的大小增加時,寫入性能通常會提高,因為減少了網絡往返時間和磁盤I/O次數。然而,如果批量請求過大,會導致節點上的內存壓力增大,進而影響其他請求的性能,甚至可能導致節點崩潰。
實測方案與結果
我在虛擬機環境實測了7種不同批次的大小,從500到10000都有。
結果如下表:
索引消耗的時間與批次大小數據圖示:
- 最慢的10000條每批,吞吐量是18078/秒。
- 最快是8000條每批,吞吐量是18218/秒。
這圖看著很唬人,實際上設定不同的批次大小對寫入性能的影響微乎其微,圖中所示的數據索引時間單位是毫秒。
表中,程序運行時間單位是秒,即便是觀察程序運行總時間,也都是幾秒之差。因為波動太小,因此不具有實際調優意義,只能作為一個數據參考。
當然,對于生產環境也可以通過實驗來確定最佳的批量大小。可以從較小的批量開始(例如5MB),然后逐漸增加批量大小,觀察寫入性能的變化。當性能開始下降時,說明批量大小已經過大,應該減小批量大小。通常,一個好的起點是將每批次的數據量設置在5MB到15MB之間。
補充測試
那么將批次大小分別設置為10萬,和10呢?取兩個較為極端的值。
- 超大的10萬級別:運行了149秒,變慢的趨勢有所抬頭!
- 很小10級別:**運行了641秒,明顯變慢!果然,批次太小的確是浪費資源!**不過一般也沒有開發人員會設置成這個值。
批次大小設置為極小值10的時候,數據反映了另外一個事實,那就是批量寫入比單條寫入快了不止一倍!
最終所有測試索引都有100萬條數據,數據存儲空間大小也幾乎一致:
結論
經過計算,上述7種單批次大小的100萬數據吞吐量差異最大只有千分之7,可以說是完全沒有差異了,極端值才會顯著降低性能。