【问题标题】:ElasticSearch : More indices vs More typesElasticSearch:更多索引与更多类型
【发布时间】:2018-01-02 16:14:21
【问题描述】:

我们将弹性搜索用于以下用例。
Elasticsearch 版本:5.1.1
注意:我们使用的是 AWS 托管的 ElasticSearch

我们有一个多租户系统,在每个租户中存储多个事物的数据,并且租户的数量将每天增加。

exa:每个租户都会有以下信息。

1] tickets
2] sw_inventory
3] hw_inventory

目前的索引策略如下:

索引名称:
租户 ID (GUID) 例如:tenant_xx1234xx-5b6x-4982-889a-667a758499c8

类型:

1] tickets
2] sw_inventory
3] hw_inventory

我们面临的问题:

1] 常见字段的映射冲突例如:(id,name,userId) 类型 (tickets,sw_inventory,hw_inventory)
2] 随着租户数量的增加,指数的数量也可以达到 1000 或 2000。

如果我们反转索引策略会是个好主意吗?

例如: 索引名称:

1] tickets
2] sw_inventory
3] hw_inventory

类型:

tenant_tenant_id1
tenant_tenant_id2
tenant_tenant_id3
tenant_tenant_id4

所以只有 3 个巨大的索引,N 种类型作为租户。

那么在这种情况下的问题是哪种解决方案更好?

1] 许多小索引和 3 种类型

2] 3个巨大的索引和许多类型

问候

【问题讨论】:

  • Multiple mapping types in an index are deprecated。 Elasticsearch 6 及更高版本不允许创建具有多个映射类型的索引。
  • P.S.不要在一个索引中使用多个类型。这会使一切变得缓慢,并且对未来不利。
  • 谢谢大家!!这帮助很大

标签: elasticsearch


【解决方案1】:

我建议另一种方法:https://www.elastic.co/guide/en/elasticsearch/guide/master/faking-it.html

意思是自定义路由,其中​​每个文档都有tenant_id 或类似名称(每个租户独有的东西),并将其用于路由和为每个租户定义别名。然后,当仅查询特定租户的文档时,您使用别名。

您将以这种方式使用一个索引和一种类型。根据索引的大小,您考虑现有的索引大小和节点数,并尝试以这样的方式提出多个分片​​,使它们在所有数据保存节点上或多或少地被平均分割,并且遵循您的测试性能是可以接受的。如果将来索引变得太大并且分片变得太大而无法保持相同的性能,请考虑创建一个具有更多主分片的新索引并在该新索引中重新索引所有内容。这不是闻所未闻、未使用或不推荐的方法。

就处理能力而言,1000-2000 个别名算不了什么。如果您有接近 10 个或超过 10 个节点,我还建议您使用具有 4-6GB 堆大小和至少 4 个 CPU 内核的专用主节点。

【讨论】:

  • 谢谢安德烈·斯特凡!!这是一个令人印象深刻的解决方案。但由于这是一种索引一种类型的方法,我相信我们只能使用单一映射类型。但是,我们正在存储以下种类或类型的数据,即(tickets、hw_inventory、sw_inventory),它们都需要不同的映射类型。
  • 然后创建三个索引并在所有索引中使用相同的方法,当然要保持tenant_id 相同。
  • 如果采用这种方法,在安全设计中不要依赖索引别名,在使用任何安全插件时仍然使用文档级安全性:elastic.co/guide/en/x-pack/current/… 根据 Elasticsearch 的使用方式,过滤别名管理可能被证明是需要管理的另一层复杂性。即如果租户无法直接访问 ES,但使用了接口应用程序,那么真的需要别名吗?
  • @ryanlutgen 我同意 x-pack 安全限制。与不使用别名相比,使用别名为您提供了一种简单、万无一失的方法,即使用具有特定 tenant_id 和相应路由 ID 的过滤器。否则,需要将这两个要求添加到对该索引的每次调用中。尽管如此,在我看来,在对单个索引的每个请求中使用自定义路由和过滤器的想法比拥有成百上千个无法有效使用节点硬件资源的索引要好得多。
  • 感谢 @AndreiStefan 和 ryanlutgen,这对您有很大帮助
【解决方案2】:

这两种方法都行不通。正如其他人所提到的,这两种方法都具有成本效益,并且会阻止您升级。

考虑为每组数据设置一个索引和类型,例如sw_inventory 然后在映射中有一个字段来区分每个租户。然后,您可以在 X-Pack 或 Search Guard 等安全插件中利用文档级别的安全性来防止一个租户看到另一个租户的记录(如果需要)。

【讨论】:

  • 同意这一点。请记住,不推荐使用 Elasticsearch 作为主数据存储(可被视为反模式)。
【解决方案3】:

在 Elasticsearch 6.0.0 或更高版本中创建的索引可能只包含一个映射类型,这意味着不推荐使用 doc_type (_type)。

完整的解释你可以找到here,但总的来说有两种解决方案:

每种文档类型的索引

这种方法有两个好处:

  • 数据更可能是密集的,因此受益于 Lucene 中使用的压缩技术。
  • 在全文搜索中用于评分的术语统计信息更可能准确,因为同一索引中的所有文档都代表一个实体。

自定义类型字段

当然,集群中可以存在多少主分片是有限制的,因此您可能不想浪费整个分片来收集仅有几千个文档的集合。在这种情况下,您可以实现自己的自定义类型字段,其工作方式与旧 _type 类似。

PUT twitter
{
  "mappings": {
    "_doc": {
      "properties": {
        "type": { "type": "keyword" }, 
        "name": { "type": "text" },
        "user_name": { "type": "keyword" },
        "email": { "type": "keyword" },
        "content": { "type": "text" },
        "tweeted_at": { "type": "date" }
      }
    }
  }
}

您使用旧版本的 Elastic,但可以应用相同的逻辑,当您决定这样做时,迁移到新版本会更容易,所以我认为您应该使用单独的索引结构,或者换句话说,3 巨大索引和许多类型,但类型作为映射中的字段而不是 _type。

【讨论】:

    【解决方案4】:

    我认为这两种策略各有利弊:

    多个索引:

    优点: - 租户数据与其他数据隔离,任何查询都不会返回多个结果。 - 如果文档总数非常大,不同的较小索引可以提供更好的性能

    缺点:更难管理。如果每个索引的文档很少,您可能会浪费大量资源。

    已编辑:根据 cmets o 性能和功能弃用,避免在同一索引中使用多种类型

    【讨论】:

    • 不应使用多种类型,如问题的 cmets 中所述。
    猜你喜欢
    • 2017-12-25
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    相关资源
    最近更新 更多