問題:當有大量數據提交到Elasticsearch時,怎么優化處理效率?
回答:
批量提交
當有大量數據提交的時候,建議采用批量提交。
比如在做 ELK 過程中 ,Logstash indexer 提交數據到 Elasticsearch 中 ,batch size 就可以作為一個優化功能點。但是優化 size 大小需要根據文檔大小和服務器性能而定。
像 Logstash 中提交文檔大小超過 20MB ,Logstash 會請一個批量請求切分為多個批量請求。
如果在提交過程中,遇到 EsRejectedExecutionException 異常的話,則說明集群的索引性能已經達到極限了。這種情況,要么提高服務器集群的資源,要么根據業務規則,減少數據收集速度,比如只收集 Warn、Error 級別以上的日志。
優化硬件
優化硬件設備一直是最快速有效的手段。
- 在經濟壓力能承受的范圍下, 盡量使用固態硬盤 SSD。SSD 相對於機器硬盤,無論隨機寫還是順序寫,都較大的提升。
- 磁盤備份采用 RAID0。因為 Elasticsearch 在自身層面通過副本,已經提供了備份的功能,所以不需要利用磁盤的備份功能,同時如果使用磁盤備份功能的話,對寫入速度有較大的影響。
增加 Refresh 時間間隔
為了提高索引性能,Elasticsearch 在寫入數據時候,采用延遲寫入的策略,即數據先寫到內存中,當超過默認 1 秒 (index.refresh_interval)會進行一次寫入操作,就是將內存中 segment 數據刷新到操作系統中,此時我們才能將數據搜索出來,所以這就是為什么 Elasticsearch 提供的是近實時搜索功能,而不是實時搜索功能。
當然像我們的內部系統對數據延遲要求不高的話,我們可以通過延長 refresh 時間間隔,可以有效的減少 segment 合並壓力,提供索引速度。在做全鏈路跟蹤的過程中,我們就將 index.refresh_interval 設置為 30s,減少 refresh 次數。
同時,在進行全量索引時,可以將 refresh 次數臨時關閉,即 index.refresh_interval 設置為 -1,數據導入成功后再打開到正常模式,比如 30s。
減少副本數量
Elasticsearch 默認分片數量為 5個,雖然這樣會提高集群的可用性,增加搜索的並發數,但是同時也會影響寫入索引的效率。
在索引過程中,需要把更新的文檔發到分片上,等分片節點生效后在進行返回結束。使用 Elasticsearch 做業務搜索的時候,建議分片數目還是設置為 5 個,但是像內部 ELK 日志系統、分布式跟蹤系統中,完全可以將副本數目設置為 1 個。
