Elasticsearch中數據是如何存儲的?
使用Elasticsearch的時候,我們常常需要關注數據存儲在Elasticsearch中的存儲容量。下面,我們來了解一下Elasticsearch中的數據是如何存儲。
一、Elasticsearch索引結構
Elasticsearch對外提供的是index的概念,可以類比為MySQL DB,用戶查詢是在index上完成的,每個index由若干個shard組成,以此來達到分布式可擴展的能力。比如下圖是一個由10個shard組成的index。

shard是Elasticsearch數據存儲的最小單位,index的存儲容量為所有shard的存儲容量之和。Elasticsearch集群的存儲容量則為所有index存儲容量之和。
一個shard就對應了一個lucene的library。對于一個shard,Elasticsearch增加了translog的功能,類似于HBase WAL,是數據寫入過程中的中間數據,其余的數據都在lucene庫中管理的。
所以,Elasticsearch索引使用的存儲內容主要取決于lucene中的數據存儲。
二、lucene數據存儲
下面了解一下lucene的基本概念。
1. lucene基本概念
- segment : lucene內部的數據是由一個個segment組成的,寫入lucene的數據并不直接落盤,而是先寫在內存中,經過了refresh間隔,lucene才將該時間段寫入的全部數據refresh成一個segment,segment多了之后會進行merge成更大的segment。lucene查詢時會遍歷每個segment完成。由于lucene 寫入的數據是在內存中完成,所以寫入效率非常高。但是也存在丟失數據的風險,所以Elasticsearch基于此現象實現了translog,只有在segment數據落盤后,Elasticsearch才會刪除對應的translog。
- doc : doc表示lucene中的一條記錄。
- field :field表示記錄中的字段概念,一個doc由若干個field組成。
- term :term是lucene中索引的最小單位,某個field對應的內容如果是全文檢索類型,會將內容進行分詞,分詞的結果就是由term組成的。如果是不分詞的字段,那么該字段的內容就是一個term。
- 倒排索引(inverted index): lucene索引的通用叫法,即實現了term到doc list的映射。

- 正排數據:搜索引擎的通用叫法,即原始數據,可以理解為一個doc list。
- doc values:Elasticsearch中的列式存儲的名稱,Elasticsearch除了存儲原始數據、倒排索引,還存儲了一份doc values,用作分析和排序。doc values 的存在是因為倒排索引只對某些操作是高效的。 倒排索引的優勢在于查找包含某個項的文檔,而對于從另外一個方向的相反操作并不高效,即:確定哪些項是否存在單個文檔里,聚合需要這種次級的訪問模式。

2. lucene文件內容
lucene包的文件是由很多segment文件組成的,segments_xxx文件記錄了lucene包下面的segment文件數量。每個segment會包含如下的文件。


一份數據寫入Elasticsearch 會產生多份數據用于不同查詢方式,會比原數據占用更多磁盤空間。
對照上面的lucene文件表,進行簡要歸納:
- 存儲原文_source的文件.fdt .fdm .fdx;
- 存儲倒排索引的文件.tim .tip .doc;
- 用于聚合排序的列存文件.dvd .dvm;
- 全文檢索文件.pos .pay .nvd .nvm等;
- 加載到內存中的文件有.fdx .tip .dvm;
其中.tip占用內存最大,而.fdt、.tim、.dvd文件占用磁盤最大。
























