节点离开时延迟分配编辑

当一个节点因任何原因(有意或无意)离开集群时,主节点会做出以下反应:

  • 将副本分片提升为主分片,以替换该节点上的任何主分片。
  • 分配副本分片以替换丢失的副本(假设有足够的节点)。
  • 在剩余节点之间均匀地重新平衡分片。

这些操作旨在通过确保每个分片尽快完全复制来保护集群免受数据丢失。

即使我们在节点级别集群级别限制并发恢复,这种“分片洗牌”仍然会给集群带来很大的额外负载,如果丢失的节点可能很快就会返回,则可能没有必要。想象一下这种情况

  • 节点 5 失去网络连接。
  • 主节点将节点 5 上的每个主分片的副本分片提升为主分片。
  • 主节点将新的副本分配给集群中的其他节点。
  • 每个新的副本都会通过网络制作主分片的完整副本。
  • 更多分片被移动到不同的节点以重新平衡集群。
  • 节点 5 在几分钟后返回。
  • 主节点通过将分片分配给节点 5 来重新平衡集群。

如果主节点只是等待了几分钟,那么丢失的分片就可以以最少的网络流量重新分配给节点 5。对于空闲分片(未接收索引请求的分片),此过程甚至更快,这些分片已自动刷新

可以使用 index.unassigned.node_left.delayed_timeout 动态设置来延迟因节点离开而变得未分配的副本分片的分配,该设置默认为 1m

可以在实时索引(或所有索引)上更新此设置

resp = client.indices.put_settings(
    index="_all",
    body={
        "settings": {"index.unassigned.node_left.delayed_timeout": "5m"}
    },
)
print(resp)
response = client.indices.put_settings(
  index: '_all',
  body: {
    settings: {
      'index.unassigned.node_left.delayed_timeout' => '5m'
    }
  }
)
puts response
PUT _all/_settings
{
  "settings": {
    "index.unassigned.node_left.delayed_timeout": "5m"
  }
}

启用延迟分配后,上述情况将变为如下所示

  • 节点 5 失去网络连接。
  • 主节点将节点 5 上的每个主分片的副本分片提升为主分片。
  • 主节点记录一条消息,说明未分配分片的分配已延迟,以及延迟时间。
  • 集群保持黄色,因为存在未分配的副本分片。
  • 节点 5 在几分钟后返回,在 timeout 到期之前。
  • 丢失的副本被重新分配给节点 5(并且同步刷新的分片几乎立即恢复)。

此设置不会影响副本提升为主副本,也不会影响以前未分配的副本的分配。特别是,在集群完全重启后,延迟分配不会生效。此外,在主节点故障转移的情况下,经过的延迟时间会被遗忘(即重置为完整的初始延迟)。

取消分片迁移编辑

如果延迟分配超时,主节点会将丢失的分片分配给另一个节点,该节点将开始恢复。如果丢失的节点重新加入集群,并且其分片仍与主分片具有相同的同步 ID,则分片迁移将被取消,并且同步的分片将用于恢复。

因此,默认的 timeout 设置为仅一分钟:即使分片迁移开始,取消恢复以支持同步的分片的成本也很低。

监控延迟的未分配分片编辑

可以使用集群健康 API查看其分配已被此超时设置延迟的分片数量

resp = client.cluster.health()
print(resp)
response = client.cluster.health
puts response
GET _cluster/health 

此请求将返回一个 delayed_unassigned_shards 值。

永久删除节点编辑

如果一个节点不会返回,并且您希望 Elasticsearch 立即将丢失的分片分配出去,只需将超时设置为零

resp = client.indices.put_settings(
    index="_all",
    body={"settings": {"index.unassigned.node_left.delayed_timeout": "0"}},
)
print(resp)
response = client.indices.put_settings(
  index: '_all',
  body: {
    settings: {
      'index.unassigned.node_left.delayed_timeout' => '0'
    }
  }
)
puts response
PUT _all/_settings
{
  "settings": {
    "index.unassigned.node_left.delayed_timeout": "0"
  }
}

您可以在丢失的分片开始恢复后立即重置超时。