ElasticSearch 索引的存儲機制推演

更好的文章格式,可參考: https://www.yuque.com/terencexie/geekartt/es-index-store

ElasticSearch 做爲開源的搜索引擎,須要依賴的一個重要數據結構就是 inverted index(倒排索引)。inverted index 一般龐大、且創建過程至關耗時,因而,如何存儲 inverted index 就變成了一件極爲要緊的事情。node

顯然,inverted index 不能簡單地被放在 memory 中,它還必須作對應的持久化,讓這些已經創建的 inverted index 能夠被複用。ElasticSearch 是基於 Lucene 來構建的,在 Lucene 的世界裏,inverted index 就是存放於 disk 的一塊 immutable 的 segment。數據結構

因而,關於 ElasticSearch inverted index 的存放問題,就轉換爲了「如何可以高效地存儲 disk 文件 segment」。工具

既然是 disk file,那麼最直觀的優化方式即是使用 memory 來作批量堆積,經過累積 data batch 來節省 disk I/O overhead。因而,ElasticSearch 引入了 in-memory buffer 來暫存每一個 doc 對應的 inverted index。當這些 doc inverted index 累積到必定量後,就能夠從 in-memory buffer 刷到 disk 了。學習

另外一方面,在 Lucene 的世界裏,一切「搜索」行爲,都依賴於 disk segment,沒有 disk segment 就沒有對應的「可搜索」。優化

如此,如上圖所示,「索引的建立」和「索引的可搜索」之間出現了 time gap(這是 ElasticSearch 被稱爲 near realtime search engine 的緣由)。顯然,咱們的下一個目標,就是要儘量地縮短這個 time gap。ui

一個馬上能被聯想到的工具是 OS(operating system)提供的 disk page cache。disk page cache 也是 OS 爲了優化 disk I/O 所作出的努力,其指導思想同 ElasticSearch 引入 in-memory buffer 是同樣的,都是但願經過 data 的批量累積,來儘量地減小 disk I/O。搜索引擎

但 disk page cache 不一樣與用戶本身建立的 memory buffer 的地方是,一旦 data 被放入了 disk page cache,它對整個 OS 來說,從 「概念上」 就能夠被當作是一個真正的 disk file 了(雖然它實際不是,還在 memory 中)。因而,放入 disk page cache 的 inverted index,天然就能夠被當作是 disk segment,對於 ElasticSearch 來說,它就是「可搜索」的!spa

而且,因爲 disk page cache 畢竟是在 memory 中,從 in-memory buffer 到 disk page cache 所須要的時間,將會遠遠少於從 in-memory buffer 到 disk segment 的時間。server

因而,經過引入 disk page cache,咱們縮短了 ElasticSearch 從「建立索引」到「索引可搜索」的時間,也便是讓它更接近於 realtime。引入了 disk page cache 以後的兩段 data pipeline,分別對應了 ElasticSearch 的兩個重要 API:索引

  • 從 in-memory buffer 到 disk page cache 的過程,對應 ElasticSearch 的 refresh() API,默認 1s 觸發一次;
  • 從 disk page cache 到 disk 的過程,則對應 ElasticSearch 的 flush() API,默認 30min 觸發一次。

在這樣的結構下,咱們不由要問,若是 disk page cache 的內容還未被 flush 到 disk,而此時所在的 server 出現了 power off 等極端異常狀況,那麼這部分保存於 disk page cache 的 data 是否會丟失?!

固然是會的!

因而,ElasticSearch 又引入了 disk page cache 的一個臨時 disk backup:translog,用於持久化當前 disk page cache 中的內容。

能夠看到,雖然 translog 的本意是將 disk page cache 中的 inverted index 作持久化備份,但它本身做爲 OS 的 file,一樣須要經歷 disk page cache(translog 的 disk page cache,而不是 inverted index 的 disk page cache)到 disk 的過程。默認 translog 本身從 disk page cache 到 disk 的持久化,是 5s 一次。

因爲 translog 僅僅是 inverted index 在 disk page cache 的臨時備份,當 ElasticSearch 觸發了 flush() API 時,對應的 translog 就會被清空。由於它臨時部分的 data 在此時已經被真正持久化到了 disk,因而就再也不須要這個臨時的 disk backup 了。

如此,ElasticSearch 就將 data lost 減低到 translog 的 5s,即:最多可能會丟失 5s 的數據。

幸運的是,ElasticSearch 還有 replica node 這樣的 data backup,即使是在某個 node 上丟失了 5s 的數據,還可以從其它的 replica node 上將數據取回來。因而這就進一步下降了 data lost 的機率(固然,理論上仍是存在 data lost 的可能性,但只要下降到工程上可接納的機率之下就能夠了。工程上永遠沒有百分之百的保障,只有可接受的精度範圍)。

如此,咱們便將整個 ElasticSearch 的機制給傳串起來了。整個機制圍繞着如何高效地存儲 disk segment 來展開:

  • 爲了下降 disk I/O 的 overhead,引入了 in-memory
  • 爲了下降「建立索引」和「索引可搜索」的 time gap,而引入了 disk page cache。
  • 爲了對 disk page cache 作臨時備份,而引入了 translog

在技術的學習中,咱們每每會面臨各類繁雜的「知識點」,它們既不容易記憶,也不利於咱們掌握其背後的宏觀 intuition。因而,探尋出一條知足人類認知規律、以極少的假設推演出其它部分的路徑,就成了要訣所在。

相關文章
相關標籤/搜索