Elasticsearch性能調優之索引寫入性能優化

1和2,適合的是,你的es java client程序,可以採取批量寫的場景
3,比較通用的,比較合適的是,你對於寫入數據到可以讀到能夠接受比較大的延遲
4,一次性批量導入數據的場景
5/6/7/8/9,通用型,儘量都去做到

1/2/3/4,都是有各自適用的場景,如果場景合適,就儘量用,因爲對性能的提升都是很明顯的

5/6/7/8/9,其中通用,儘量去優化你的集羣,但是其中最重要的,就是3塊,filesystem cache更大的內存,給index buffer最充足的內存,一個是用SSD固態硬盤

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的數據量。

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,可以先禁止refresh和replica複製,將index.refresh_interval設置爲-1,將index.number_of_replicas設置爲0即可。這可能會導致我們的數據丟失,因爲沒有refresh和replica機制了。但是不需要創建segment file,也不需要將數據replica複製到其他的replica shasrd上面去。此時寫入的速度會非常快,一旦寫完之後,可以將refresh和replica修改回正常的狀態。

5、禁止swapping交換內存

可以將swapping禁止掉,有的時候,如果要將es jvm內存交換到磁盤,再交換回內存,大量磁盤IO,性能很差

6、給filesystem cache更多的內存

filesystem cache被用來執行更多的IO操作,如果我們能給filesystem cache更多的內存資源,那麼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%,如果我們給jvm heap分配10gb內存,那麼這個index buffer就有1gb,對於兩個shard共享來說,是足夠的了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章