Elasticsearch如何选择索引或类型来存储数据

来源:互联网 发布:上海软件开发培训班 编辑:程序博客网 时间:2024/06/05 23:02
阅读这篇文章来帮助决定何时选择索引或类型来存储数据。

没有人知道新的数据是应该放进已经存在索引的新的类型中还是一个新的索引中。
对于新用户来说,这是一个反复出现的问题,如果不了解这两者是如何实现的,那么就无法回答这些问题。

在过去,我们通过建立与关系型数据库的对比来尝试让elasticsearch更容易理解:索引(indices)就像一个数据库,类型(types)像数据库中的表;这是错误的:两者之间数据存储的方式有很大的不同,所以任何的比较都是没有意义的;这最终导致过度使用类型,在它们是有害多于有益处的情况。

索引是什么?

一个索引存储在一个或多个分片中。这里的分片是指 Lucene 的索引。这已经让您了解了一直使用新索引的局限性:Lucene索引在磁盘空间、内存使用和文件描述符等方面有一定的固定开销。因此,一个大的索引比几个小的索引更有效率:Lucene索引的固定成本在许多文档中更好地摊销。
另外一个重要的因素是你打算如何搜索你的数据,每个分片都是独立的执行搜索,Elasticsearch最终需要合并来自各个参与搜索分片查询的结果。
例如你的搜索贯穿10个索引,每个索引有5个分片,协调搜索请求执行的节点需要合并5*10个分片的搜索结果。这里你同样需要小心:如果有太多的的分片搜索结果需要合并或者你再跑一个很重的请求产生大量的分片结果(这会很容易在聚合中发生)所有这些分片结果合并的任务可以成为非常占用资源,无论是在CPU和内存方面的。这又会提倡使用更少的索引。

什么是类型?

类型一个很好的地方在于:在一个索引的不同的类型中搜索和在一个单一的类型中搜索相比是没有额外的开销的:因为它不会改变需要合并的分片搜索结果的数量。

然而这里同样有一些限制:

1.字段需要跨类型一致。例如,如果两个字段在同一索引的不同类型中具有相同的名称,则它们需要具有相同的字段类型(字符串、日期等)并具有相同的配置。

2.存在于一种类型中的字段也将消耗该字段不存在的类型文档的资源。这是Lucene索引的一个普遍问题:它们不喜欢稀疏性。由于连续匹配之间的高增量,稀疏的压缩列表不能有效地压缩。这个问题更糟的是doc值:由于速度原因,doc值通常为每个文档预留一个固定的磁盘空间,以便有效地处理值。这意味着,如果Lucene规定它需要一个字节来存储给定数值字段的所有值,那么它也将为该字段没有值的文档消耗一个字节。Elasticsearch的未来版本将在这方面有改进,但我还是建议你在某种程度上会限制稀疏尽可能你的数据模型。

3.分数使用索引范围统计,所以一种类型的文档分数可能受到其他类型文档的影响。

这意味着但只有当给定索引中的所有类型都具有类似的映射时,使用不同的类型可能是有用的。否则,字段在不存在的文档中消耗资源的事实可能会使数据比存储在单独索引中的情况更糟。


我应该选择哪一个?
这是一个棘手的问题,答案将取决于您的硬件、数据和用例。首先是要认识到,类型是有用的因为他们可以帮助减少Elasticsearch需要管理的Lucene索引的数量。但是还有另一种方法可以减少这个数字:创建具有较少分片的索引。例如您可以创建5个索引,每个索引有一个主分片,而不是把5个类型存到同一个索引中。

尽量总结一下你应该问自己做决定的问题:

你使用parent/child结构吗?如果是,只能在同一索引中使用两种类型。
你的文档有相似的映射吗?如果没有,使用不同的索引。
如果每个类型有很多文档,那么Lucene索引的开销将很容易摊销,这样您就可以安全地使用索引,如果需要的话,设置的分片比默认的5更少。
否则,您可以考虑将文档放在同一索引的不同类型中。甚至是同一类型的。

总之,您可能会对您所期望的类型并没有那么多用例感到惊讶。这是正确的:由于上面提到的原因,实际上在同一索引中有几个类型的用例很少。不要犹豫为那些有不同映射的数据分配不同的索引。但是你应该记住为你的集群设置合理数量的分片,这可以通过减少不需要高写入吞吐量或将存储少量文档的索引的分片数量来实现。
原创粉丝点击