1. 程式人生 > >ElasticSearch教程——深入剖析Document寫入原理以及優化操作

ElasticSearch教程——深入剖析Document寫入原理以及優化操作

ElasticSearch彙總請檢視:ElasticSearch教程——彙總篇

 

初始寫入流程

(1)資料寫入buffer
(2)commit point
(3)buffer中的資料寫入新的index segment
(4)等待在os cache中的index segment被fsync強制刷到磁碟上
(5)新的index sgement被開啟,供search使用
(6)buffer被清空

每次commit point時,會有一個.del檔案,標記了哪些segment中的哪些document被標記為deleted了
搜尋的時候,會依次查詢所有的segment,從舊的到新的,比如被修改過的document,在舊的segment中,會標記為deleted,在新的segment中會有其新的資料

 

 

優化寫入流程實現NRT近實時(filesystem cache,refresh)

現有流程的問題,每次都必須等待fsync將segment刷入磁碟,才能將segment開啟供search使用,這樣的話,從一個document寫入,到它可以被搜尋,可能會超過1分鐘!!!這就不是近實時的搜尋了!!!主要瓶頸在於fsync實際發生磁碟IO寫資料進磁碟,是很耗時的。

寫入流程別改進如下:

(1)資料寫入buffer
(2)每隔一定時間,buffer中的資料被寫入segment檔案,但是先寫入os cache
(3)只要segment寫入os cache,那就直接開啟供search使用,不立即執行commit

資料寫入os cache,並被開啟供搜尋的過程,叫做refresh,預設是每隔1秒refresh一次。也就是說,每隔一秒就會將buffer中的資料寫入一個新的index segment file,先寫入os cache中。所以,es是近實時的,資料寫入到可以被搜尋,預設是1秒。

POST /my_index/_refresh,可以手動refresh,一般不需要手動執行,沒必要,讓es自己搞就可以了

比如說,我們現在的時效性要求,比較低,只要求一條資料寫入es,一分鐘以後才讓我們搜尋到就可以了,那麼就可以調整refresh interval

PUT /my_index
{
  "settings": {
    "refresh_interval": "30s" 
  }
}

 

 

 

優化寫入流程實現durability可靠儲存(translog,flush)

再次優化的寫入流程

(1)資料寫入buffer緩衝和translog日誌檔案
(2)每隔一秒鐘,buffer中的資料被寫入新的segment file,並進入os cache,此時segment被開啟並供search使用
(3)buffer被清空
(4)重複1~3,新的segment不斷新增,buffer不斷被清空,而translog中的資料不斷累加
(5)當translog長度達到一定程度的時候,commit操作發生
  (5-1)buffer中的所有資料寫入一個新的segment,並寫入os cache,開啟供使用
  (5-2)buffer被清空
  (5-3)一個commit ponit被寫入磁碟,標明瞭所有的index segment
  (5-4)filesystem cache中的所有index segment file快取資料,被fsync強行刷到磁碟上
  (5-5)現有的translog被清空,建立一個新的translog

 

基於translog和commit point,如何進行資料恢復

fsync+清空translog,就是flush,預設每隔30分鐘flush一次,或者當translog過大的時候,也會flush

POST /my_index/_flush,一般來說別手動flush,讓它自動執行就可以了

translog,每隔5秒被fsync一次到磁碟上。在一次增刪改操作之後,當fsync在primary shard和replica shard都成功之後,那次增刪改操作才會成功

但是這種在一次增刪改時強行fsync translog可能會導致部分操作比較耗時,也可以允許部分資料丟失,設定非同步fsync translog

PUT /my_index/_settings
{
    "index.translog.durability": "async",
    "index.translog.sync_interval": "5s"
}

 

優化寫入流程實現海量磁碟檔案合併

每秒一個segment file,檔案過多,而且每次search都要搜尋所有的segment,很耗時

預設會在後臺執行segment merge操作,在merge的時候,被標記為deleted的document也會被徹底物理刪除

每次merge操作的執行流程

(1)選擇一些有相似大小的segment,merge成一個大的segment
(2)將新的segment flush到磁碟上去
(3)寫一個新的commit point,包括了新的segment,並且排除舊的那些segment
(4)將新的segment開啟供搜尋
(5)將舊的segment刪除

POST /my_index/_optimize?max_num_segments=1

儘量不要手動執行,讓它自動預設執行就可以了

 

如有疑問可關注左邊公眾號聯絡管理員!!!