天天看點

ElasticSearch: Index 和 Type 的差別

對于 ES 的新使用者來說,有一個常見的問題:要存儲一批新的資料時,應該在已有 index 裡建立一個 type,還是給它建立一個 index?要想回答這個問題,我們必須先了解這兩者是怎麼實作的。

過去,我們為了讓 ES 更容易了解,經常用關系型資料庫做一個比喻: index 就像關系型資料庫裡的 database, type 就像 database 裡的 table。但是這并不正确。由于兩種資料庫存儲資料的方式是如此不同,任何比喻都是沒有意義的。這種比喻往往會導緻對 type 的濫用。

Index 是什麼

Index 存儲在多個分片中,其中每一個分片都是一個獨立的 Lucene Index。這就應該能提醒你,添加新 index 應該有個限度:每個 Lucene Index 都需要消耗一些磁盤,記憶體和檔案描述符。是以,一個大的 index 比多個小 index 效率更高:Lucene Index 的固定開銷被攤分到更多文檔上了。

另一個重要因素是你準備怎麼搜尋你的資料。在搜尋時,每個分片都需要搜尋一次, 然後 ES 會合并來自所有分片的結果。例如,你要搜尋 10 個 index,每個 index 有 5 個分片,那麼協調這次搜尋的節點就需要合并 5x10=50 個分片的結果。這也是一個你需要注意的地方:如果有太多分片的結果需要合并,或者你發起了一個結果巨大的搜尋請求,合并任務會需要大量 CPU 和記憶體資源。這是第二個讓 index 少一些的理由。

Type 是什麼

使用 type 允許我們在一個 index 裡存儲多種類型的資料,這樣就可以減少 index 的數量了。在使用時,向每個文檔加入 

_type

 字段,在指定 type 搜尋時就會被用于過濾。使用 type 的一個好處是,搜尋一個 index 下的多個 type,和隻搜尋一個 type 相比沒有額外的開銷 —— 需要合并結果的分片數量是一樣的。

但是,這也是有限制的:

  • 不同 type 裡的字段需要保持一緻。例如,一個 index 下的不同 type 裡有兩個名字相同的字段,他們的類型(string, date 等等)和配置也必須相同。
  • 隻在某個 type 裡存在的字段,在其他沒有該字段的 type 中也會消耗資源。這是 Lucene Index 帶來的常見問題:它不喜歡稀疏。由于連續文檔之間的差異太大,稀疏的 posting list 的壓縮效率不高。這個問題在 doc value 上更為嚴重:為了提高速度,doc value 通常會為每個文檔預留一個固定大小的空間,以便文檔可以被高速檢索。這意味着,如果 Lucene 确定它需要一個位元組來存儲某個數字類型的字段,它同樣會給沒有這個字段的文檔預留一個位元組。未來版本的 ES 會在這方面做一些改進,但是我仍然建議你在模組化的時候盡量避免稀疏。[1]
  • 得分是由 index 内的統計資料來決定的。也就是說,一個 type 中的文檔會影響另一個 type 中的文檔的得分。

這意味着,隻有同一個 index 的中的 type 都有類似的映射 (mapping) 時,才應該使用 type。否則,使用多個 type 可能比使用多個 index 消耗的資源更多。

我應該用哪個

這是個困難的問題,它的答案取決于你用的硬體、資料和用例。首先你要明白 type 是有用的,因為它能減少 ES 需要管理的 Lucene Index 的數量。但是也有另外一種方式可以減少這個數量:建立 index 的時候讓它的分片少一些。例如,與其在一個 index 裡塞上 5 個 type,不如建立 5 個隻有一個分片的 index。

在你做決定的時候可以問自己下面幾個問題:

  • 你需要使用父子文檔嗎?如果需要,隻能在一個 index 裡建立多個 type。
  • 你的文檔的映射是否相似?如果不相似,使用多個 index。
  • 如果你的每個 type 都有足夠多的文檔,Lucene Index 的開銷可以被分攤掉,你就可以安全的使用多個 index 了。如果有必要的話,可以把分片數量設小一點。
  • 如果文檔不夠多,你可以考慮把文檔放進一個 index 裡的多個 type 裡,甚至放進一個 type 裡。

總之,你可能有點驚訝,因為 type 的使用場景沒有你想象的多,這是正确的。由于我們上面提到原因,在一個 index 中使用多個 type 的情景其實很少。如果你的資料有不同的映射,那就給他們配置設定不同的 index。但是請記住,如果不需要很高的寫入吞吐量,或者存儲的文檔數量不多,你可以通過減少 index 的分片來使叢集中的分片數量保持合理。

[1] posting list 和 doc value 都是 Lucene 的壓縮技術,原理是儲存後一個文檔和前一個文檔的差異,而不是完整的文檔。

轉載自:http://bayescafe.com/database/elasticsearch-using-index-or-type.html貝葉書部落格

繼續閱讀