10

ElasticSearch: Index 和 Type 的区别

 3 years ago
source link: https://www.bayescafe.com/database/elasticsearch-using-index-or-type.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原文: Index vs. Type By Adrien Grand
译者: fengchang

对于 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 的压缩技术,原理是保存后一个文档和前一个文档的差异,而不是完整的文档。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK