Elasticsearch Reroute API 的使用

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch Reroute API 的使用

本文通过一个 Elasticsearch 集群中主分片分配不均衡的例子演示一下 Cluster reroute API 的使用。

对于 Elasticsearch 分片分配策略不了解的同学可以点一下关注,后面更文之后获取第一手资料。

环境信息

Windows 10

Elasticsearch 8.1

JDK17

初始集群状态

分片1分片2分片4 都在 node-2 节点上

我们可以使用如下命令移动索引 my-index-0000010node-2 节点上的 主分片1 移动到 node-1 节点上

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "move": {
        "index": "my-index-0000010", "shard": 1,
        "from_node": "node-2", "to_node": "node-1"
      }
    }
  ]
}

移动完成之后结果如下。

下面我们看一个例子,如果我们索引 my-index-0000010node-2 节点上的 主分片4 移动到 node-4 节点会发生什么情况呢,大家可以猜想一下,看一下是不是和你想得一样。

如下命令是移动索引 my-index-0000010node-2 节点上的 主分片4node-4 节点上去。

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "move": {
        "index": "my-index-0000010", "shard": 4,
        "from_node": "node-2", "to_node": "node-4"
      }
    }
  ]
}

返回结果如下所示,我们只需要关注NO的地方即可,我已经在下图标示出来了,提示的意思就是,node-4 节点上已经存在 分片4 的副本,不允许进行 move 操作

对于如上这种情况,那么我们该如何进行分片的迁移呢?

首先可以知道的是,如果我们把节点node-2上的分片4移动到node-4节点上是不被允许的,因为node-4上面已经存在分片4的副本分片,那么我们可以反过来思考,如果想让节点 node-2 上的分片可以均衡分配,只需要让 Elasticsearch 触发一下正常的分片分配即可,所以我们使用如下的语句,来让 Elasticsearch 进行 node-2 节点上 主分片4 的重新分配。

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "cancel": {
        "index": "my-index-0000010",
        "shard": 4,
        "node": "node-2"
      }
    }
  ]
}

如果你执行完了上面的语句,你会发现,报错了

那是因为 Elasticsearch 对于主分片的 cancel 操作,需要添加 allow_primary 属性,设置为true 即可,修改之后的语句如下所示。

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "cancel": {
        "index": "my-index-0000010",
        "shard": 4,
        "node": "node-2",
        "allow_primary": true
      }
    }
  ]
}

返回如下结果代表执行成功。

{
  "acknowledged" : true,
  "state" : {
    "cluster_uuid" : "dyCQnpMvSd2w3Hn9tcBTig"
  }
}

继续查看当前的 Elasticsearch 分片分配情况如下所示。可以看到 主分片4 已经到了节点 node-4上面了。

对于节点 node-5 上面的 分片2 也可以执行同样的操作,执行完成之后,Elasticsearch 进行默认的分片分配策略进行重新分配,结果如下。

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "cancel": {
        "index": "my-index-0000010",
        "shard": 2,
        "node": "node-5",
        "allow_primary": true
      }
    }
  ]
}

未分配分片进行分配

首先创建一个索引 my-index-0000011,分片数量为1,副本分片数量为1

PUT /my-index-0000011
{
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 1
  }
}

通过页面可以看到 主分片分配到了 node-5 上,副本分片在 node-2 上。

添加一条测试数据

PUT my-index-0000011/_doc/1
{
  "name":"zuiyu"
}

我们同时停掉节点 node-2node-5,观察索引 my-index-0000011 的分片分配情况。

可以看到因为两个节点的同时离开,造成了分片无法重新分配,这是因为该索引 my-index-0000011 的主分片与副本文件同时离开,Elasticsearch 集群无法找到有效的分片充当主分片,所以分片会无法分配。针对这种情况下的分片无法分配问题,可以使用如下方式进行解决,具体解决方式看业务来选择。

  • 第一种方式就是重启异常的节点,等待恢复。
  • 第二种就是手动触发分片分配,但是会造成数据丢失

说到分片未分配,需要重新分配问题,那么就要提到我们的第三个命令 allocate_replica,用法如下:

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "allocate_replica": {
        "index": "my-index-0000011",
        "shard": 0,
        "node":""
      }
    }
  ]
}

对于我们的情况就没法使用了,因为索引 my-index-0000011 的主分片与副本分片同时丢失,Elasticsearch 集群无法获取到正确的副本来进行恢复。此时就要用到另外的两个命令了。

需要注意的是,这另外的两个命令都会造成数据丢失

会造成数据丢失

会造成数据丢失

所以需要一个另外的参数来清晰的告诉你,你在做什么,以后丢了数据是你允许的。参数就是 accept_data_loss, 当该参数为 true 时,表示如果丢了数据,我可不背这锅。

如下两个命令为原始数据无法恢复且允许接收数据丢失的情况下使用

allocate_stale_primary

该参数的意思就是,如果有该索引的副本分片存在(但是该分片是过时的,也就是说不是最新的副本分片),Elasticsearch 会将主分片分配给该副本分片,所以这个情况下会造成数据丢失。显然对于我们目前的情况来说也是不合适的,下面我们来看另一个命令。

allocate_empty_primary

该参数命令会为索引分配一个全新的空的主分片,相当于没有数据,也就造成数据丢失了,而且是完全丢失。当之后拥有数据副本的节点再次加入集群时,该分片的数据会被删除。

这个命令对我们这个情况来说是可以实现的,不过就是在数据不被需要的时候是可以使用的。所以使用场景就要看我们每个人的业务场景了。

用法如下所示:

POST /_cluster/reroute?metric=none
{
  "commands": [
    {
      "allocate_empty_primary": {
        "index": "my-index-0000011",
        "shard": 0,
        "node":"node-3",
        "accept_data_loss":true
      }
    }
  ]
}

总结

对于分片未分配的问题,可以使用 API 来进行查看分片分配情况。使用 move 命令修改主分片的存储节点位置;使用 cancel 命令撤销主分片节点存储位置,使 Elasticsearch 重新分配索引分片;使用 allocate_replica 手动触发分片重新分配;使用 allocate_stale_primary 分配一个过时的副本分片来充当主分片;使用 allocate_empty_primary 生成一个新的空分片来充当主分片。

备注

使用如下命令获取索引分片分配情况,不加参数随机返回一个有问题的索引,加了参数就按照参数指定的来返回。

GET _cluster/allocation/explain
{
  "index": "my-index-0000011",
  "shard": 0,
  "primary": true
}


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
3月前
|
存储 JSON 自然语言处理
Elasticsearch 利用API进行搜索
Elasticsearch 利用API进行搜索
36 0
|
7月前
|
JSON Java 测试技术
Elasticsearch常用Java API编程 1
Elasticsearch常用Java API编程
74 0
|
4月前
|
安全 大数据 API
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
64 0
|
4月前
|
Java API
SpringBoot【集成ElasticSearch 01】2种方式的高级客户端 RestHighLevelClient 使用(依赖+配置+客户端API测试源码)
SpringBoot【集成ElasticSearch 01】2种方式的高级客户端 RestHighLevelClient 使用(依赖+配置+客户端API测试源码)
81 0
|
7月前
|
JSON Java 测试技术
Elasticsearch常用Java API编程 2
Elasticsearch常用Java API编程
47 0
|
7月前
|
Java API 数据安全/隐私保护
Elasticsearch Java API Client 开发
本场景主要介绍如何使用 Elasticsearch Java API Client 进行开发,实现常用的 CRUD 操作。
146 0
|
18天前
|
缓存 前端开发 API
API接口封装系列
API(Application Programming Interface)接口封装是将系统内部的功能封装成可复用的程序接口并向外部提供,以便其他系统调用和使用这些功能,通过这种方式实现系统之间的通信和协作。下面将介绍API接口封装的一些关键步骤和注意事项。
|
25天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。
|
1天前
|
前端开发 Java 测试技术
IDEA 版 API 接口神器来了,一键生成文档,贼香!
IDEA 版 API 接口神器来了,一键生成文档,贼香!
6 0