ES 6.0版本以下 index的type详解

本文探讨了在Elasticsearch中如何选择存储数据的方式,是新建索引还是新建类型。指出过去将索引类比为数据库、类型类比为表的做法并不准确,因为它们的实现机制不同。索引由分片组成,过多的索引或分片可能导致资源消耗增加。类型允许在同一个索引中存储多种数据,但也要求映射一致,可能导致资源浪费。建议根据文档的相似性和数量来决定使用单个索引还是多个索引。在ES6以后,每个索引默认只有一个_type,即_doc,且ES7将完全移除类型概念。选择时应考虑是否需要父子文档、映射是否相似以及文档数量等因素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

对于 ES 的新用户来说,有一个常见的问题:要存储一批新数据时,应该在已有 index 里新建一个 type,还是给它新建一个 index?要想回答这个问题,我们必须先理解这两者是怎么实现的。

在过去,我们试图通过与关系数据库建立类比来使弹性搜索更容易理解:索引index就像数据库一样,类型type似于数据库中的表。这是一个错误:数据的存储方式是如此不同,以至于任何比较几乎都没有意义,这最终会导致在有害的情况下过度使用类型。

index 是什么

索引index存储在一系列分片中,它们本身就是Lucene index。所以使用新索引应该注意:Lucene索引在磁盘空间,内存使用和使用的文件描述符方面有一个小而固定的开销。因此,单个大index比几个小index效率更高,Lucene index的固定开销更好地摊销在多个文档中。

另一个重要因素是如何搜索数据,虽然每个分片都是独立搜索的,但Elasticsearch最终需要合并所有搜索分片的结果。例如,搜索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 的压缩技术,原理是保存后一个文档和前一个文档的差异,而不是完整的文档。

变化

1. ES 数据库的存储结构变化:去除了Type

  • es6时,官方就提到了es7会删除type,并且es6时已经规定每一个index只能有一个type。在es7中使用默认的_doc作为type,官方说在8.x版本会彻底移除type。
  • api请求方式也发送变化,对索引的文档进行操作的时候,默认使用的Type是 _doc
  • 如获得某索引的某ID的文档:GET index/_doc/id其中index和id为具体的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值