1. 程式人生 > >ES索引寫入效能優化

ES索引寫入效能優化

1、用bulk批量寫入

你如果要往es裡面灌入資料的話,那麼根據你的業務場景來,如果你的業務場景可以支援讓你將一批資料聚合起來,一次性寫入es,那麼就儘量採用bulk的方式,每次批量寫個幾百條這樣子。

bulk批量寫入的效能比你一條一條寫入大量的document的效能要好很多。但是如果要知道一個bulk請求最佳的大小,需要對單個es node的單個shard做壓測。先bulk寫入100個document,然後200個,400個,以此類推,每次都將bulk size加倍一次。如果bulk寫入效能開始變平緩的時候,那麼這個就是最佳的bulk大小。並不是bulk size越大越好,而是根據你的叢集等環境具體要測試出來的,因為越大的bulk size會導致記憶體壓力過大,因此最好一個請求不要傳送超過10mb的資料量。

先確定一個是bulk size,此時就儘量是單執行緒,一個es node,一個shard,進行測試。看看單執行緒最多一次性寫多少條資料,效能是比較好的。

2、使用多執行緒將資料寫入es

單執行緒傳送bulk請求是無法最大化es叢集寫入的吞吐量的。如果要利用叢集的所有資源,就需要使用多執行緒併發將資料bulk寫入叢集中。為了更好的利用叢集的資源,這樣多執行緒併發寫入,可以減少每次底層磁碟fsync的次數和開銷。首先對單個es節點的單個shard做壓測,比如說,先是2個執行緒,然後是4個執行緒,然後是8個執行緒,16個,每次執行緒數量倍增。一旦發現es返回了TOO_MANY_REQUESTS的錯誤,JavaClient也就是EsRejectedExecutionException。此時那麼就說明es是說已經到了一個併發寫入的最大瓶頸了,此時我們就知道最多隻能支撐這麼高的併發寫入了。

3、增加refresh間隔

預設的refresh間隔是1s,用index.refresh_interval引數可以設定,這樣會其強迫es每秒中都將記憶體中的資料寫入磁碟中,建立一個新的segment file。正是這個間隔,讓我們每次寫入資料後,1s以後才能看到。但是如果我們將這個間隔調大,比如30s,可以接受寫入的資料30s後才看到,那麼我們就可以獲取更大的寫入吞吐量,因為30s內都是寫記憶體的,每隔30s才會建立一個segment file。

4、禁止refresh和replia

如果我們要一次性載入大批量的資料進es,可以先禁止refreshreplia複製,將index.refresh_interval

設定為-1,將index.number_of_replicas設定為0即可。這可能會導致我們的資料丟失,因為沒有refresh和replica機制了。但是不需要建立segment file,也不需要將資料replica複製到其他的replica shasrd上面去。此時寫入的速度會非常快,一旦寫完之後,可以將refreshreplica修改回正常的狀態

5、禁止swapping交換記憶體

如果要將es jvm記憶體交換到磁碟,再交換回記憶體,大量磁碟IO,效能很差

6、給filesystem cache更多的記憶體

filesystem cache被用來執行更多的IO操作,如果我們能給filesystemcache更多的記憶體資源,那麼es的寫入效能會好很多。

7、使用自動生成的id

如果我們要手動給es document設定一個id,那麼es需要每次都去確認一下那個id是否存在,這個過程是比較耗費時間的。如果我們使用自動生成的id,那麼es就可以跳過這個步驟,寫入效能會更好。對於你的業務中的表id,可以作為es document的一個field。

8、用效能更好的硬體

我們可以給filesystem cache更多的記憶體,也可以使用SSD替代機械硬碟,避免使用NAS等網路儲存,考慮使用RAID 0來條帶化儲存提升磁碟並行讀寫效率,等等。

9、index buffer

如果我們要進行非常重的高併發寫入操作,那麼最好將index buffer調大一些,indices.memory.index_buffer_size,這個可以調節大一些,設定的這個index buffer大小,是所有的shard公用的,但是如果除以shard數量以後,算出來平均每個shard可以使用的記憶體大小,一般建議,但是對於每個shard來說,最多給512mb,因為再大效能就沒什麼提升了。es會將這個設定作為每個shard共享的index buffer,那些特別活躍的shard會更多的使用這個buffer。預設這個引數的值是10%,也就是jvm heap的10%,如果我們給jvmheap分配10gb記憶體,那麼這個index buffer就有1gb,對於兩個shard共享來說,是足夠的了。