Elasticsearch 架構原理—— 新數據寫入過程

前言

在分佈式日誌服務架構中,我們只需要將logstash的output指向ES就可以了,但是,寫入的數據是如何變成Elasticsearch裏可以被檢索和聚合的索引內容的呢?本文重點介紹數據在寫入Elasticsearch索引流程中發生的具體操作。重點在於其中segment、buffer和translog三部分對實時性和性能方面的影響。

動態更新的Lucene索引

Lucene對於新收到的數據寫入到新的索引文件裏。Lucene把每次生成的倒排索引,叫做一個segment,然後另外使用一個commit文件,記錄索引內所有的segment。而生成segment的數據來源則是放在內存中的buffer,也就是說,動態更新過程如下:

  1. 當前索引有3個segment可用;
  2. 新接收的數據進入內存buffer;
  3. 內存buffer刷到磁盤,生成一個新的segment,commit文件同步更新。

利用磁盤緩存實現的準實時檢索

上面的內容中,內存buffer刷入磁盤,但是不可避免的問題就是寫磁盤太慢了。對於我們的日誌服務來說,如果要進行一些實時性統計,這個速度是不能接受的。所以,在內存buffer刷入磁盤的處理中,還有一箇中間狀態:

  1. 內存buffer生成一個新的segment,刷到文件系統緩存中,Lucene即可檢索這個新的segment。
  2. 文件系統緩存真正同步到磁盤上,commit文件更新。

其實就是多加了一步文件系統緩存。Elasticsearch中默認1s中刷新一次。如果覺得間隔時間還是很短,可以調用/_refresh接口來修改。
不過對於日誌場景來說,我們更需要的是更快的寫入性能,所以我們最好是通過/_settings接口或者定製template的方式,加大refresh_intereval參數:

curl -XPOST http://127.0.0.1:9200/logstash-lms-2019.02.19/_settings -d'{"refresh_interval":"10s"}'

如果是導入歷史數據的場合,甚至可以直接關閉。

索引數據一致性保證——translog提供的磁盤同步控制

refres只是寫到文件系統緩存,如果最後一步寫入到磁盤期間發生了錯誤、硬件故障燈問題,數據會丟失嗎?
這裏有另一個控制機制。Elasticsearch在把數據寫入到內存buffer的同時,其實還另外記錄了一個translog日誌。
refres發生時,translog日誌文件依舊保持原樣。如果期間發生異常,Elasticsearch會從commit位置開始,恢復整個translog文件中的記錄,保證數據一致性。
等到真正吧segment刷新到磁盤,commit文件更新後,translog纔會清空,即flush操作。
Elasticsearch默認30分鐘flush一次,或者translog文件>512M時會主動flush。可以通過以下參數進行設置:

index.translog.flush_threshold_period
index.translog.flush_threshold_size
#控制每收到多少條數據後flush一次
index.translog.flush_threshold_ops
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章