Elasticsearch分片的主动迁移

shard

分片存储了一个索引的一部分数据,多个分片组成了一个完整的索引。分片的形式提升了一个索引查询和写入的并发能力,以横向的方式提升了集群数据存储的上限。比如一个索引1000G,但是集群内最大的数据节点的磁盘容量是500G,在没有分片的情况下,这个索引是无法写入到这个集群的。将这个索引拆分成2个分片理论上两个同样配置的节点就可以存储这个索引所有的数据。 分片这种结构在合理的设置下突破物理硬件的上限,综合利用硬件群集的能力。

根据集群的分配策略,分片在集群内会出现从一个节点移动到另一个节点的情况。而下面几种情况都会触发这种迁移的发生。

  • 新建或删除索引
  • 集群节点变动:新增、减少
  • 节点重启
  • 手动reroute

查看分片迁移的状态

分片的迁移是需要消耗集群内部带宽、cpu、磁盘、内存资源的,实际集群维护过程中有时需要人工干预分片迁移的进度、修复迁移失败的分片。

  1. 查看正在迁移的分片
#在kibana中执行
GET _cat/recovery?v&&active_only=true
  1. 如果有分配失败的分片,查看失败的原因
GET _cluster/allocation/explain?pretty

鉴于分片的迁移需要消耗集群的资源,对于所有主动触发的分片迁移,如:重启、扩缩容等操作建议放在业务低峰期进行。分片迁移过程中可以调整并发的分片数和分片恢复的速度上限以缩短集群恢复时间。

对于非主动触发的分片迁移,如果对业务产生影响,可以通过命令控制分片恢复的速度,减少对业务的影响。

  1. 调整分片并发和速度
PUT _cluster/settings
{ 
    "persistent": {
            "cluster.routing.allocation.node_concurrent_recoveries": 2,
            "indices.recovery.max_bytes_per_sec": "40mb/s" 
    }
}

cluster.routing.allocation.node_concurrent_recoveries 分片恢复的并发进程数

indices.recovery.max_bytes_per_sec 索引恢复时带宽上限

使用上面的命令根据需要调大或调小集群分片恢复的并发数和带宽上限,以控制集群恢复的时间和对业务影响的程度。

分片的自动迁移

以下情况会触发分片的自动迁移:

  • 新建或删除索引
  • 集群节点变动:新增、减少
  • 节点重启

手动迁移分片

API介绍

分片主动迁移,es提供api实现人为主动操作分片在节点上的分配。

POST /_cluster/reroute
request样例
POST /_cluster/reroute?metric=none
命令可接受的参数

dry_run 请求中加上dry_run参数后,这个请求只会根据当前集群状态计算命令执行的结果并返回它,并不会在集群上真正执行.

POST /_cluster/reroute?dry_run

explain 解释这个请求可执行(不可执行)的原因

POST /_cluster/reroute?dry_run

metric 指定命令返回的内容

POST /_cluster/reroute?metric=master_node

可指定的模块:
master_node	     	#显示主节点部分
metadata					#显示元数据部分
node		    			#显示节点部分
routing_table	   	#显示路由表部分
version  	       	#显示版本信息

retry_failed 重试分配失败的分片

POST  _cluster/reroute?retry_failed=true

master_timeout 主节点超时时间

timeout 命令超时时间

请求体内容

样例:

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "move": {
        "index": "test", "shard": 0,
        "from_node": "node1", "to_node": "node2"
      }
    },
    {
      "allocate_replica": {
        "index": "test", "shard": 1,
        "node": "node3"
      }
    }
  ]
}

_cluster/reroute 支持的post方法的请求,请求体内需要提供commands参数。 commands需要提供一个列表,指定要操作的内容。

commands可接受的子命令:move、cancel、allocate_replica、allocate_stale_primary、allocate_empty_primary。

样例:

move 将一个分片从一个节点移动到另外一个节点

POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "test",				#索引名
        "shard": 0,							#分片编号
        "from_node": "node1", 	#分片源节点
        "to_node": "node2"			#分片迁移目标节点
      }
    }
  ]
}

cancel 撤销一个分片的分配,默认操作对象为副本分片。执行后可以强制重新初始化副本分片并从主分片同步数据。如果确认需要操作主分片,需要在请求主体中增加allow_primary参数并置为true.

#未验证
POST /_cluster/reroute
{
  "commands": [
    {
      "cancel": {
        "index": "test",				#索引名
        "shard": 0,							#分片编号
        "node": "node1" 				#分片源节点
      }
    }
  ]
}

allocate_replica 分配一个未分配的分片到指定节点

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "allocate_replica": {
        "index": "test", 		#索引名
        "shard": 1,					#分配编号
        "node": "node3"			#分片分配的节点
      }
    }
  ]
}

allocate_stale_primary 将一个保留有过期数据的副本分片提升为主节点

POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_stale_primary": {
        "index": "test",				#索引名
        "shard": 0,							#分片编号
        "node": "node1" 				#分片源节点
        "accept_data_loss": "true"	#接受潜在的数据丢失
      }
    }
  ]
}

POST /_cluster/reroute
{
  "commands" : [
    {
      "allocate_stale_primary" : {
        "index" : "jy_seal_car_detail20240628",
        "shard" : 4,
        "node" : "Z6GsmF8CQHSp2iaw_SpkZA",
        "accept_data_loss" : true  
      }
    }
  ]
}

accept_data_loss #执行这条命令后,如果一个持有最新副本(good copy)的节点重新加入当前集群,新节点上的最新副本(good copy)会被分配的过期副本(stale copy)上的数据所覆盖。为了确保执行命令时了解到这条命令的风险,增加将accept_data_loss设置为true

allocate_empty_primary 分配一个空分片到指定节点

POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_empty_primary": {
        "index": "test",				#索引名
        "shard": 0,							#分片编号
        "node": "node1" 				#分片源节点
        "accept_data_loss": "true"	#接受潜在的数据丢失
      }
    }
  ]
}

accept_data_loss #请求中值设置为true. 这条命令的执行将会导致分配的这个主分片原来的数据全部丢失。如果后续有一个节点重新加入集群,且这个节点上有执行分片的数据,新节点上的这个分片数据将会被删除。

allocate_stale_primary、allocate_empty_primary这两条命令操作对象都是主分片,有一定丢失数据的风险。

一般情况下主分片的分配都会由es集群自动处理完成,只有在极端情况下才需要使用下面两条命令。造成主分片分配失败的原因:

  • 新索引创建但是集群内node都不满足分配策略导致主分片无法分配,主分片处理未分配状态。
  • 当前集群内数据节点上找不到数据的最新副本分片,为防止数据丢失,系统不会将过期副本分片提升为主分片,主分片处理未分配状态。

一般用于在原始数据无法恢复,并且可以接受数据丢失的情况下。 如果是遇到临时可修复的问题,不要使用这两条命令,使用上面提到的retry_failed来修复分片的分配。

注意一旦执行了这两条命令,当有一个新的节点加入当前集群后,如果新节点上带有这个分片的副本,那么新节点上的副本将会被删除覆盖

使用场景

各个节点上分片数一致,但因为不同的索引大小不一,导致个别节点磁盘使用率超90%,其他节点在50%左右。这种情况下一旦发生节点重启,90%磁盘使用率的节点可能会被打满?

解决:这种场景下,只能是手动将快写满的节点上的分片迁移到其他节点。

手动迁移任意一个分片都会触发集群的自动平衡,以恢复集群到平衡状态。比如,从node1上迁移一个分片到node2上之后,动态平衡会从node2再迁移一个分片到node1。可以通过配置cluster.routing.rebalance.enable参数,禁用动态平衡以维持手动迁移分片的结果。

禁用自动平衡(支持索引级别配置)

PUT /_cluster/settings
{
  "transient" : {
     "cluster.routing.rebalance.enable" : "none"
  }
}

手动将分片从磁盘使用率超90%的节点上将分片移走

POST /_cluster/reroute
{
  "commands": [
    {
      "move": {
        "index": "test",				#索引名
        "shard": 0,							#分片编号
        "from_node": "node1", 	#分片源节点
        "to_node": "node2"			#分片迁移目标节点
      }
    }
  ]
}

解决索引及分片问题后恢复集群自动平衡

PUT /_cluster/settings
{
 "transient" : {
  "cluster.routing.rebalance.enable" : "all"
 }
}
  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值