Elasticsearch:路由 – routing

2023年6月12日   |   by mebius

%title插图%num

你是否考虑过 Elasticsearch 如何知道将文档存储在何处? 它如何知道在哪里寻找它们,以及是否检索、更新或删除它们? 这是一个令人兴奋的过程,一切都归结为路由的概念。

路由介绍

%title插图%num

路由是确定文档属于哪个分片以便检索它或将其存储在它所属的位置的过程。 当 Elasticsearch 索引文档时,它会进行各种计算以确定将其放在哪个分片上。 这是通过使用以下公式完成的:

shard_num = hash(_routing) % num_primary_shards

默认情况下,“_routing” 等于文档的 ID。 这表明 Elasticsearch 查找文档的 ID 以确定它属于哪个分片。 当我们更新或删除文档时也是如此。

因此,当我们要求 Elasticsearch 通过其 ID 检索文档时,Elasticsearch 使用该 ID 来定tgcode位存储文档的分片。 如果文档存在,几乎可以肯定它在路由公式对应的分片上。

当我们更新或删除某些文档时也是如此。 但是,如果要根据 ID 以外的特征来查找文档,则情况会有所不同。 但我们最终会谈到这一点。

默认路由策略

路由的妙处在于它对 Elasticsearch 用户是完全不可见的。 Elasticsearch 通过提供默认路由策略让我们的生活变得更加轻松,这让我们不必自己处理所有这些路由问题。

你可能想知道是否可以更改默认路由策略。 答案是肯定的; 如果你愿意,你可以修改它。 然而,这是一个复杂的话题,我们稍后会讨论。

除了确保文档被分配到一个分片并且我们可以通过 ID 获取它们之外,默认路由策略还确保文档均匀分布在索引中的所有分片上。 这有助于确保没有一个分片比另一个分片拥有更多的文档。

如果我们决定修改文档的路由方式,我们必须要么确保它们仍然均匀分布,要么接受一个分片最终可能比另一个分片拥有更多的文档。

Elasticsearch 元字段和自定义路由

Elasticsearch 在其索引的文档中保留了一些附加信息。 除了我们提供的数据(比如我们用来添加文档的 JSON)之外,Elasticsearch 还包括像 _id和 _source这样的元字段。 _id字段具有文档的唯一标识符,而 _source 字段包含用于为其编制索引的 JSON 负载。

还有一个名为 _routing 的元字段。 此选项用于为我们的文档自定义路由计划。

默认情况下,Elasticsearch 使用基于哈希的路由方法来确定文档应放置在哪些分片中。但是,如果我们在索引文档时提供自定义路由值,Elasticsearch 将使用该值来识别适当的分片编号。比如我们可以使用如下的方式来进行 routing:

PUT my_index/_doc/3?routing=1?refresh  (1)
{
  "text": "This is an answer",
  "my_join_field": {
    "name": "answer",   (2)
    "parent": "1"       (3)
  }
}
 
PUT my_index/_doc/4?routing=1?refresh
{
  "text": "This is another answer",
  "my_join_field": {
    "name": "answer",
    "parent": "1"
  }
}

如上所示,我们把 routing 设置为1,那么所有都含有同样的 routing 值的文档都会被写入到同一个分片里。这种情况在有些时候是必须的,比如针对 join 数据类型的文档。具体操作可以参阅文档 “Elasticsearch: Join 数据类型​​​​​​​”。

了解索引中的分片数量是固定的并且在创建索引后无法修改这一点至关重要。 这是因为 Elasticsearch 的路由公式依赖于索引中的分片数量。 具体来说,它用来确定分片数量的公式是 shard_num = hash(_routing) % num_primary_shards。

如果索引中的分片数量发生变化,路由公式将提供不同的结果。 对于新索引的文档来说这不是什么大不了的事情,但对于旧的文档来说却是这样。 假设我们有一个包含两个分片的索引,并且我们索引了一个文档。 根据路由公式,文档存储在第二个tgcode分片中。 但是,如果索引中的分片数量后来增加到四个,则需要将文档转移到单独的分片中。 这可能需要一些时间,我的朋友。 所以,在 Elasticsearch 中创建索引时,我们必须仔细考虑我们想要的分片数量。

管理 Elasticsearch 分片:注意事项和最佳实践

%title插图%num

好的,让我们假装我们向索引添加了更多分片,比如大约 5 个。 这样,我们可以添加更多文档而不会引起任何明显的问题。 但是,当我们尝试通过 ID 查找某些文档时,Elasticsearch 有时会找不到它们。 基本上,ID 会再次通过路由算法运行,并且由于其中一个因素发生了变tgcode化,结果可能会有所不同。

这意味着 Elasticsearch 在错误的分片中查找文档并且不返回任何内容,尽管该文档在索引中。 众所周知,此问题会产生重大问题,尤其是在处理时间敏感的信息时。 一种解决方案是开发一种更好的路由机制,可以更有效地处理分片数量的变化。

还值得注意的是,其他因素(例如文档如何分布在不同的分片中)也会在这个问题中发挥作用。 因此,仔细评估索引策略并确保其针对最大效率和准确性进行优化至关重要。

在考虑向索引添加更多分片时,请牢记这一非常重要的原则。 你必须确保索引中的文档分布不均匀,否则你可能会遇到性能问题。 因此,如果你可以平衡所有分片,那么搜索时间和其他方面会好得多。

但是,如果要更改分片数,则必须创建新索引并重新索引所有文档。你可以使用 reindex 来进行重新索引文档。我们可以参考文章 “Elasticsearch: Reindex 接口”。

这听起来很糟糕,但有些 API 可以提供帮助。 如果你有兴趣,请查看 shrinksplit 功能来进行缩小或扩大分片数。 使用这些可以帮助你创建具有不同数量分片的新索引并重新索引所有文档而不会遇到严重麻烦。

总的来说,你在建立索引时应该谨慎行事,并考虑所需的分片数量以及任何潜在的未来修订。 然而,通过适当的准备和正确的工具,管理分片会变得轻而易举,并显着提高你的搜索速度。

文章来源于互联网:Elasticsearch:路由 – routing

相关推荐: Elasticsearch:实用指南

我们将更多地讨论使用 Elasticsearch 的最佳实践。这些做法是一般性建议,可以应用于任何用例。 让我们开始吧。 Bulk Requests 批量 API 使得在单个 API 调用中执行许多索引/删除操作成为可能。 这可以大大增加索引速度。 每个子请求…

Tags: