企业项目管理、ORK、研发管理与敏捷开发工具平台

网站首页 > 精选文章 正文

Elasticsearch集群节点下线和分片感知意识

wudianyun 2025-08-01 21:48:33 精选文章 4 ℃

本篇文章将介绍如下内容:

  • 分片分配感知意识(定义节点区域属性)
  • 强制感知意识
  • 分片分配过滤(节点下线)
  • 集群分片数量限制


1、分片分配感知意识

为了使分片分配能够考虑节点的物理硬件配置,我们可以给集群中的节点设置一些自定义的属性。如果Elasticsearch知道某些节点位于同一物理区域,比如同一个机架或者同一个街区,就可以把索引的主分片和副本分片数据放置在不同的物理区域,以防止因同一物理区域服务器全部不可用而导致整个集群的数据不可用。

当通过
cluster.routing.allocation.awareness.attributes启用
分片分配感知意识,分片只会被分配到配置了awareness属性的节点上,如果有多个awareness属性,Elasticsearch会综合考虑,然后进行合理的分片分配。

默认情况下Elasticsearch会使用自适应的方式去路由搜索请求,但是当使用了分片意识之后,Elasticsearch会优先选择在同一个区域的分片去执行搜索请求。

awareness属性的数量决定了副本的数量,比如我们设置5个街区,最多可以有四个副本分片,共5个数据拷贝;如果设置了1个街区,我们的索引有一个副本,就有可能导致我们的副本无法分配,其实副本能否分配也是有参数可以配置的;如果每个区域的节点数不相同,并且集群中有很多的副本,有可能导致某些索引的副本无法分配(无空间可以分配)。

启用分片分配感知意识:

(1)给每个节点指定一个自定义的区域属性,比如想让索引的每个分片分配到不同的机架上,此时需要在每个节点的elasticsearch.yml文件中配置rack_id 属性

node.attr.rack_id: rack_one
`./bin/elasticsearch -Enode.attr.rack_id=rack_one`

也可以在启动Elasticsearch时指定截取参数。

(2)在候选master节点的配置文件中设置
cluster.routing.allocation.awareness.attributes属性,Elasticsearch在分配分片时会考虑
awareness属性

cluster.routing.allocation.awareness.attributes: rack_id

如果是多个属性使用逗号分隔。

如果使用上面的配置,我们启动两个节点,并且都设置了node.attr.rack_id: rack_one,此时创建一个索引,5个分片一个副本,所有的主分片和副本都会分配到这两个节点上(这种情况是我们不想要的,其实我们是想这种情况下只分配主分片,不分配副本,即不允许相同的数据出现在同一个区域,参考:强制意识)。如果我们再加入两个节点,并且配置了
node.attr.rack_id:rack_two,Elasticsearch会自动移动分片至新的节点。如果rack_two 的两个节点宕机了,此时Elasticsearch会在rack_one恢复丢失的分片。为了阻止相同的数据出现在同一个区域,我们需要使用强制意识配置去避免。


2、强制感知意识

默认情况下,当一个区域全部不可用,Elasticsearch会默认把这个区域丢失的副本在其他区域恢复。如果你配置了多个分区,会有足够的资源去承载这些分片,但是只有一个分区的话,有可能无法分片这些分片。

为了防止因一个区域不可用,而导致其他区域过载,可以配置
cluster.routing.allocation.awareness.force,这样副本不会分配,直到有节点在其他分区可用。

例如,你有一个分配意识属性zone,给节点配置上zone1和zone2值,可以配置强制意识,去阻止在仅有一个区域的情况下进行副本分配:

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

配置所有可用的分配意识值。

上面的例子,如果我们有两个节点,都配置node.attr.zone为zone1,此时创建一个索引5个分片一个副本,此时只会在zone1上分配5个主分片,不会分配副本。只有当分配意识属性为zone2的区域存在时,才会分片副本。


3、集群级的分片分配过滤

可以使用集群级的分片分配过滤功能,控制所有索引的分片分配位置,分配过滤功能可以使用内置的或者自定义的属性,比如:_name, _host_ip, _publish_ip, _ip, _host, _id and _tier等。并且此配置支持动态更新,分片分配会受到强制意识机制的制约,比如不会在同一个节点分配相同数据的主分片和副本。

分配过滤最常用的场景是节点下线,在关闭节点之前将其上的数据迁移至其他节点,比如我们使用ip做过滤:

curl -X PUT "localhost:9200/_cluster/settings?pretty" -H 'Content-Type: application/json' -d'
{
  "transient" : {
    "cluster.routing.allocation.exclude._ip" : "10.150.0.1"
  }
}
'


集群路由设置如下,可以配置多个参数

cluster.routing.allocation.include.{attribute}

将分片分配到,至少包含一个属性的节点上。

cluster.routing.allocation.require.{attribute}

仅将分片分配给包含全部属性的节点上

cluster.routing.allocation.exclude.{attribute}

包含属性的节点上都不分配分片,可以用作节点下线前的数据迁移。

{attribute}支持以下属性:

  • _name 匹配节点名称
  • _host_ip 匹配主机IP地址(与主机名称相关联的IP)
  • _publish_ip 匹配公网IP地址
  • _ip 匹配_host_ip 或者 _publish_ip
  • _host 匹配主机名
  • _id 匹配节点id

(1)设置属性的时候,可以使用通配符,执行下面命令通过ip排除节点

curl -X PUT "localhost:9200/_cluster/settings?pretty" -H 'Content-Type: application/json' -d'
{
  "transient": {
    "cluster.routing.allocation.exclude._ip": "192.168.2.*"
  }
}
'

下图可以看出我们的排除操作已经成功


(2)使用_name做排除

curl -X PUT "localhost:9200/_cluster/settings?pretty" -H 'Content-Type: application/json' -d'
{
  "transient": {
    "cluster.routing.allocation.exclude._name": "node1"
  }
}
'

(3)通过配置查询命令,查看我们的集群配置

curl -X GET "localhost:9200/_cluster/settings?pretty"

从下面可以看出我们的排除配置_name和_ip都生效了


4、其他设置

cluster.blocks.read_only

设置集群只读,write操作将不被允许,元数据也不允许修改。创建或者删除索引。

luster.blocks.read_only_allow_delete

只允许查询和删除。不能依赖这两个配置,对集群的修改做限制,任何人都可以通过集群配置API动态修改参数值。

5、集群分片数量限制

集群中的分片数量是由集群中的节点数决定的,节点数越多允许分配的分片也就越多。不能无限制的分配分片,因为会导致集群不稳定。默认情况下每个节点最多可分配1000个分片,关闭的索引不算在内,可以通过下面的参数修改:

cluster.max_shards_per_node

当达到阈值,Elasticsearch会拒绝在此节点分配分片,比如配置100,共三个节点,现在已经有298个分片,集群不会再分配需要两个以上分片的索引。注意,此设置不会限制单个节点的分片数量,想要限制单个分片的数据需要使用,
cluster.routing.allocation.total_shards_per_node 。

如果文章对您有帮助,欢迎关注、点赞、留言,我会持续更新Elasticsearch技术相关文章,和大家一起学习进步!

什么是Elasticsearch?(简介)

Elasticsearch快速上手,Linux环境安装及使用

Elasticsearch启动及配置

Elasticsearch集群分片分配

Tags:

最近发表
标签列表