ElasticSearch

15. 集群级别的分片分配和路由设置

2023-12-05  本文已影响0人  ElasticSearch文档
集群级别的分片分配和路由设置

分片分配是将分片分配给节点的过程。这可能发生在初始恢复、副本分配、重新平衡或添加或删除节点时。

主节点的主要作用之一是决定将哪些分片分配给哪些节点,并在需要重新平衡集群时移动分片之间的节点。

有许多设置可用于控制分片分配过程:

除了这些,还有一些其他杂项的集群级别的设置。

集群级别的分片分配设置

您可以使用以下设置来控制分片分配和恢复:

此设置不影响重新启动节点时本地主分片的恢复。重新启动节点如果有未分配的主分片的副本将立即进行恢复,假设其分配ID与集群状态中的活动分配ID之一匹配。

分片再平衡设置

当集群在每个节点上有相等数量的分片,所有节点需要相等的资源,而不在任何节点上集中任何索引的分片时,集群就是平衡的。Elasticsearch运行一个名为再平衡的自动过程,它在集群中的节点之间移动分片,以改善其平衡。再平衡遵循所有其他分片分配规则,如分配过滤和强制感知,这可能会阻止它完全平衡集群。在这种情况下,再平衡会努力在您配置的规则内实现尽可能平衡的集群。如果您使用数据层次,则Elasticsearch会自动应用分配过滤规则,将每个分片放置在适当的层次中。这些规则意味着均衡器在每个层次内独立工作。

您可以使用以下设置来控制集群中分片的再平衡:

分片平衡启发式设置

再平衡通过为每个节点计算其分片分配的权重,然后在节点之间移动分片以减小较重节点的权重并增加较轻节点的权重来实现。当没有可能的分片移动可以将任何节点的权重与任何其他节点的权重之间的差异大于可配置的阈值时,集群就是平衡的。

节点的权重取决于它持有的分片数量,以及这些分片的总估计资源使用量,以磁盘上的分片大小和支持向分片写入流量所需的线程数量表示。当数据流的分片在滚动时,Elasticsearch在创建时估算了它们的资源使用情况。新分片的估计磁盘大小是数据流中其他分片的平均大小。新分片的估计写入负载是数据流中最近分片的实际写入负载的加权平均值。不属于数据流写入索引的分片的估计写入负载为零。

以下设置控制Elasticsearch如何将这些值组合成每个节点权重的整体度量。

基于磁盘的分片分配设置编辑

基于磁盘的分片分配器确保所有节点具有足够的磁盘空间,而无需执行比必要更多的分片移动。它根据一对称为低水位线和高水位线的阈值来分配分片。其主要目标是确保没有节点超过高水位线,或者至少任何此类超出是暂时的。如果某个节点超过高水位线,Elasticsearch 将通过将其一些分片移动到群集中的其他节点来解决这个问题。

节点不时暂时超过高水位线是正常的。

分片分配器还通过禁止将更多分片分配给超过低水位线的节点来努力保持节点远离高水位线。重要的是,如果所有节点都超过了低水位线,那么将无法分配新的分片,Elasticsearch 将无法在节点之间移动任何分片,以使磁盘使用率保持在高水位线以下。您必须确保群集总体上具有足够的磁盘空间,并且始终有一些节点低于低水位线。

由基于磁盘的分片分配器触发的分片移动还必须符合所有其他分片分配规则,例如分配过滤和强制感知。如果这些规则太严格,它们还可能阻止用于保持节点磁盘使用量受控制的分片移动。如果您使用数据层,则 Elasticsearch 会自动配置分配过滤规则,将分片放置在适当的层中,这意味着基于磁盘的分片分配器在每个层内部独立工作。

如果某个节点的磁盘填满得比 Elasticsearch 能够将分片移动到其他位置更快,那么磁盘可能会完全填满。为防止这种情况,作为最后的手段,一旦磁盘使用量达到洪水阶段水印,Elasticsearch 将阻止对受影响节点上具有分片的索引进行写入。它还将继续将分片移动到群集中的其他节点。当受影响节点上的磁盘使用量降到高水位线以下时,Elasticsearch 将自动移除写入阻止。请参阅解决持续水印错误以解决持久性水印错误。

群集中的节点使用的磁盘空间量可能差异很大是正常的。群集的平衡仅取决于每个节点上的分片数量以及这些分片所属的索引。它既不考虑这些分片的大小,也不考虑每个节点上的可用磁盘空间,原因如下:

磁盘使用会随时间变化。平衡每个节点的磁盘使用量将需要更多的分片移动,甚至可能浪费之前的移动。移动分片会消耗 I/O 和网络带宽等资源,并可能从文件系统缓存中驱逐数据。最好将这些资源用于处理您的搜索和尽可能处理索引。
每个节点上的磁盘使用相等的群集通常性能不比磁盘使用不均匀的群集好,只要没有磁盘过满。
您可以使用以下设置来控制基于磁盘的分配:

cluster.routing.allocation.disk.threshold_enabled
(动态)默认为 true。设置为 false 以禁用磁盘分配决策者。禁用后,它还将删除任何现有的 index.blocks.read_only_allow_delete 索引块。
cluster.routing.allocation.disk.watermark.low logo cloud
(动态)控制磁盘使用的低水位线。默认为 85%,这意味着 Elasticsearch 不会将分片分配给磁盘使用率超过 85% 的节点。它还可以设置为比率值,例如 0.85。也可以设置为绝对字节值(如 500mb),以防止 Elasticsearch 在可用空间低于指定量时分配分片。此设置对于新创建的索引的主分片没有影响,但会阻止其副本的分配。
cluster.routing.allocation.disk.watermark.low.max_headroom
(动态)控制低水位线的最大余地(在百分比/比率值的情况下)。当 cluster.routing.allocation.disk.watermark.low 没有明确设置时,默认为 200GB。这限制所需的可用空间量。
cluster.routing.allocation.disk.watermark.high logo cloud
(动态)控制高水位线。默认为 90%,这意味着 Elasticsearch 将尝试将分片从磁盘使用率超过 90% 的节点中重新定位。它还可以设置为比率值,例如 0.9。也可以设置为绝对字节值(类似于低水位线),以在节点的可用空间低于指定量时重新定位分片。此设置影响所有分配的分片,无论之前是否分配。
cluster.routing.allocation.disk.watermark.high.max_headroom
(动态)控制高水位线的最大余地(在百分比/比率值的情况下)。当 cluster.routing.allocation.disk.watermark.high 没有明确设置时,默认为 150GB。这限制所需的可用空间量。
cluster.routing.allocation.disk.watermark.enable_for_single_data_node
(静态)在早期版本中,单数据节点群集在进行分配决策

时默认情况下会忽略磁盘水印。自 7.14 版本以来,已弃用此行为,并已在 8.0 版本中删除。此设置的唯一有效值现在是 true。该设置将在将来的版本中删除。
cluster.routing.allocation.disk.watermark.flood_stage logo cloud
(动态)控制洪水阶段水印,默认为 95%。Elasticsearch 在每个节点上分配了一个或多个分片的每个索引上强制执行只读索引块(index.blocks.read_only_allow_delete),并且至少有一个磁盘超过了洪水阶段。此设置是防止节点耗尽磁盘空间的最后手段。当磁盘利用率降到高水位线以下时,索引块会自动释放。与低水位线和高水位线值类似,它还可以设置为比率值,例如 0.95,或绝对字节值。

重置 my-index-000001 索引上的只读索引块的示例:

PUT /my-index-000001/_settings
{
  "index.blocks.read_only_allow_delete": null
}
# 或者使用 curl
curl -X PUT "localhost:9200/my-index-000001/_settings" -H 'Content-Type: application/json' -d '{
  "index.blocks.read_only_allow_delete": null
}'

集群路由分配磁盘水印洪水阶段最大余地

(动态)控制洪水阶段水印的最大余地(在百分比/比率值的情况下)。当 cluster.routing.allocation.disk.watermark.flood_stage 没有明确设置时,默认为 100GB。这限制所需的可用空间量。

您不能在 cluster.routing.allocation.disk.watermark.low、cluster.routing.allocation.disk.watermark.high 和 cluster.routing.allocation.disk.watermark.flood_stage 设置中混合使用百分比/比率值和字节值。要么所有值都设置为百分比/比率值,要么所有值都设置为字节值。此强制执行是为了 Elasticsearch 可以验证这些设置在内部是一致的,确保低磁盘阈值小于高磁盘阈值,高磁盘阈值小于洪水阶段阈值。max headroom 值也进行了类似的比较检查。

(动态)控制专用冻结节点的洪水阶段水印,默认为 95%。
(动态)控制专用冻结节点的洪水阶段水印的最大余地(在百分比/比率值的情况下)。当 cluster.routing.allocation.disk.watermark.flood_stage.frozen 没有明确设置时,默认为 20GB。这限制专用冻结节点上所需的可用空间量。

(动态)Elasticsearch 应该多久检查一次集群中每个节点的磁盘使用情况。默认为 30s。

百分比值是指已用磁盘空间,而字节值是指空闲磁盘空间。这可能会令人困惑,因为它颠倒了高和低的含义。例如,将低水位线设置为 10GB,将高水位线设置为 5GB 是有意义的,但反过来则不是。

将低水位线更新为至少有 100GB 空闲,将高水位线更新为至少有 50GB 空闲,将洪水阶段水印更新为至少有 10GB 空闲,并且每分钟更新一次有关群集的信息的示例:

PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.disk.watermark.low": "100gb",
    "cluster.routing.allocation.disk.watermark.high": "50gb",
    "cluster.routing.allocation.disk.watermark.flood_stage": "10gb",
    "cluster.info.update.interval": "1m"
  }
}
# 或者使用 curl
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d '{
  "persistent": {
    "cluster.routing.allocation.disk.watermark.low": "100gb",
    "cluster.routing.allocation.disk.watermark.high": "50gb",
    "cluster.routing.allocation.disk.watermark.flood_stage": "10gb",
    "cluster.info.update.interval": "1m"
  }
}'

关于水印的最大余地设置,请注意这仅适用于水印设置为百分比/比率的情况。max headroom 值的目的是限制在达到相应水印之前所需的空闲磁盘空间。这对于具有较大磁盘的服务器特别有用,其中百分比/比率水印可能转换为大量的免费磁盘空间需求,而 max headroom 可以用于限制所需的免费磁盘空间量。例如,让我们以洪水水印的默认设置为例。它的默认值是 95%,而洪水最大余地设置的默认值是 100GB。这意味着:

对于较小的磁盘,例如 100GB,洪水水印将在达到 95% 时触发,即在 5GB 的空闲空间时触发,因为 5GB 小于 100GB 的最大余地值。
对于较大的磁盘,例如 100TB,洪水水印将在 100GB 的空闲空间时触发。这是因为 95% 的洪水水印单独将需要 5TB 的免费磁盘空间,但该值被最大余地设置限制为 100GB。
最后,如果其相应的水印设置没有明确设置(因此,它们具有默认的百分比值),则 max headroom 设置才具有其默认值。如果水印被明确设置,那么 max headroom 设置就不具有默认值,并且如果需要,则需要明确设置。

Shard allocation awareness(分片分配感知)

您可以使用自定义节点属性作为感知属性,以使Elasticsearch在分配分片时考虑到您的物理硬件配置。如果Elasticsearch知道哪些节点位于同一物理服务器、同一机架或同一区域,它可以分发主分片及其副本分片,以最小化在发生故障时丢失所有分片副本的风险。

当使用动态的 cluster.routing.allocation.awareness.attributes 设置启用分片分配感知时,分片仅分配给为指定感知属性设置了值的节点。如果使用多个感知属性,Elasticsearch在分配分片时会分别考虑每个属性。

属性值的数量确定在每个位置分配多少个分片副本。如果每个位置的节点数量不平衡,并且有很多副本,可能会导致副本分片无法分配。

启用分片分配感知

要启用分片分配感知:

  1. 使用自定义节点属性指定每个节点的位置。例如,如果您希望Elasticsearch在不同的机架上分发分片,则可以在每个节点的 elasticsearch.yml 配置文件中设置一个名为 rack_id 的感知属性。
node.attr.rack_id: rack_one

您还可以在启动节点时设置自定义属性:

./bin/elasticsearch -Enode.attr.rack_id=rack_one
  1. 通过在每个主节点的 elasticsearch.yml 配置文件中设置 cluster.routing.allocation.awareness.attributes,告诉Elasticsearch在分配分片时考虑一个或多个感知属性。
cluster.routing.allocation.awareness.attributes: rack_id

将多个属性指定为逗号分隔的列表。
您还可以使用 cluster-update-settings API 设置或更新群集的感知属性。
使用此示例配置,如果您启动两个节点,并将 node.attr.rack_id 设置为 rack_one,然后创建一个具有 5 个主分片和每个主分片 1 个副本的索引,所有主分片和副本将分配到这两个节点上。
如果添加两个 node.attr.rack_id 设置为 rack_two 的节点,Elasticsearch将移动分片到新节点,确保(如果可能)相同分片的两个副本不在同一机架上。
如果 rack_two 失败并导致两个节点都宕机,默认情况下,Elasticsearch将丢失的分片副本分配给 rack_one 中的节点。为了防止在相同位置分配特定分片的多个副本,您可以启用强制感知。

强制感知

默认情况下,如果一个位置失败,Elasticsearch会将所有缺失的副本分片分配给其余位置。尽管您可能在所有位置上有足够的资源来托管主分片和副本分片,但是单个位置可能无法托管所有分片。

为了防止在发生故障时使单个位置超负荷,您可以设置 cluster.routing.allocation.awareness.force,以便在其他位置的节点可用之前不分配任何副本。

例如,如果您有一个名为 zone 的感知属性,并配置了位于 zone1zone2 的节点,您可以使用强制感知来防止 Elasticsearch 在仅有一个区域可用时分配副本:

cluster.routing.allocation.awareness.attributes: zone
cluster.routing.allocation.awareness.force.zone.values: zone1,zone2

指定感知属性的所有可能值。

使用此示例配置,如果您启动两个节点,并将 node.attr.zone 设置为 zone1,然后创建一个具有 5 个分片和每个分片 1 个副本的索引,Elasticsearch将创建该索引并分配 5 个主分片,但不分配副本。只有在具有 node.attr.zone 设置为 zone2 的节点可用时,才会分配副本。

集群级别的分片分配过滤

您可以使用集群级别的分片分配过滤来控制Elasticsearch从任何索引分配分片的位置。这些集群范围的过滤器与每个索引的分配过滤器和分配感知一起应用。

分片分配过滤器可以基于自定义节点属性或内置的 _name、_host_ip、_publish_ip、_ip、_host、_id 和 _tier 属性。

cluster.routing.allocation 设置是动态的,允许将活动索引从一组节点移动到另一组节点。仅当可以在不违反其他路由约束的情况下进行重新定位分片时,才会重新定位分片,例如永不在同一节点上分配主分片和副本分片。

集群级别的分片分配过滤的最常见用例是当您想要停用节点时。为了在关闭节点之前将分片移出节点,您可以创建一个通过其IP地址排除该节点的过滤器:

PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.exclude._ip": "10.0.0.1"
  }
}
集群路由设置

集群分配设置支持以下内置属性:

_name Match nodes by node name
_host_ip Match nodes by host IP address (IP associated with hostname)
_publish_ip Match nodes by publish IP address
_ip Match either _host_ip or _publish_ip
_host Match nodes by hostname
_id Match nodes by node id
_tier Match nodes by the node’s data tier role

_tier 过滤基于节点角色。只有一部分角色是数据层角色,而通用数据角色将与任何层过滤匹配。有一部分角色是数据层角色,但通用数据角色将与任何层过滤匹配。

在指定属性值时,您可以使用通配符,例如:

PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.exclude._ip": "192.168.2.*"
  }
}
上一篇下一篇

猜你喜欢

热点阅读