使用Bulk請求進行Index
- Bulk請求將產生比單文檔index請求有更好的性能。至於Bulk請求中文檔數量的大小,建議使用單一節點單一分片進行測試,先試試看100個,然后200個,然后400這樣,每次進行翻倍測試,只要速度穩定了,也就是最合適的大小了。但是要注意一下,並不是速度最合適了就OK,因為每次請求總的大小要進行一下控制。並發發送的時候,ES內存壓力會很大,一定要避免每次請求超過幾十兆,即便是這樣插入的性能更好(這個我踩過坑,我這測試超過10M,ES就不接受請求,直接拒絕了)。
使用多個節點或者多線程進行Index
- 一般來說一個線程,即便是使用了Bulk方式進行Index,也無法達到ES集群的瓶頸,所以為了最大限度的利用集群資源,使用多線程或者多進程的方式進行Index是一個很好的選擇。這樣不僅最大程度利用了集群資源,還幫助減少了fsync的成本。(這個fsync是什么 意思我暫時也沒弄明白,后續補充)。
- 要注意一下TOO_MANY_REQUESTS (429) 相應(對應Java Client 則是EsRejectedExecutionException), 這說明ES集群已經跟不上你Index的速度了,使用一些適當的方式限制一下速度吧。(官方文檔說暫停Index一會或者使用隨機指數函數Backoff)。
- 類似Bulk Index 數量,多線程多進程Index也需要進行人工測試,直到找到一個合適線程數或者進程數。
增加refresh interval
- 默認的 index.refresh_interval 是1s,在index的時候如果沒有實時性檢索需求,建議可以設置大一些,比如30S,如果不需要檢索,等index完成才進行檢索的話,可以設置為-1,也就是禁用,等完成index之后在調整回來。
禁用refresh,降低分片副本數
- 如果需要一次index大量數據,最好禁用refresh,也就是將refresh_interval設置為-1,同時index.number_of_replicas 設置為0,也就是不需要副本。盡管這樣會增加一些風險(真的很小很小),也就是在索引的時候可能導致數據丟失,但是這樣可以大幅度增加索引速度,等完成索引后在增加副本,這樣也可以保證數據的可靠性。
禁用Swapping
- 一定確保操作系統禁用了swapping,這對ES性能有很大的提升。
給足夠的內存文件系統緩存
- 你應該分配機器的一半內存給ES使用,用於文件系統的緩存。文件系統緩存用於緩沖I/O操作。
使用系統自動生成id
- 當你index一個document使用特定的id,ES需要去檢查是否在同一個shard存在相同的ID的文檔,這是一個相當昂貴的操作,並且隨着文檔數量的增加,花費呈指數增長。如果使用自動生成id,ES會跳過這個檢查,使得Index速度更快。
使用更快的硬件
- 如果I/O是瓶頸,那么最好考慮為文件系統提供更多內存或者購買更好的服務器。使用SSD硬盤能比一般的硬盤有更好的性能。另外盡量使用本地存儲,不要考慮遠程存儲。也盡可能不要考慮Amazon等虛擬化存儲,盡管比較簡單的使用,但是性能比本地存儲差很多。
- 還有要盡可能冗余副本,以避免節點故障導致數據丟失。也可以用快照備份還原進一步降低數據糗事風險。
Indexing 緩沖大小
如果節點僅僅是大量Index,確保每個分片 indices.memory.index_buffer_size 大於512M,(盡管大於512M沒有什么性能改善)。舉個例子,默認值是10%,也是說如果你設置的jvm大小是10G,那么Index緩沖大小是1G,足以支撐2個shard的大量索引。
禁用 _field_names
- 簡單來說,如果你不需要運行exists查詢,那么你就可以禁用_field_names。