A. 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共享來說,是足夠的了。