介绍几个实际生产中常用的API

2021-01-03 23:17:21 浏览数 (1)

前言|

本文将介绍几个ES集群生产运维中用得比较多的API,方便大家操作维护日常的运维问题。

一、Split API 介绍

Split 能将一个索引中的大分片切割成若干小的分片,如果一个索引特别大,主分片又比较少,我们可以使用它来进行相关的操作。执行Split API 有以下前置条件:

执行API 前提条件执行API 前提条件

二、Split API 实践

Split API 在ES6环境下与ES7还有所不同,在ES6环境下,源索引在创建的时候必须要指定 "index.number_of_routing_shards“参数,如果存量索引没有预先配置这个参数,在ES6环境下是无法执行此Split操作的。下面我们将分别实践测试:

  • 环境: ES 7.5.1

第一步: 源索引停写:

代码语言:javascript复制
PUT logstash-cms5885_001/_settings     //假设索引主分片数量为1
{
  "settings":{
    "index.blocks.write": true
  }
}

第二步:执行split 操作:

代码语言:javascript复制

POST logstash-cms5885_001/_split/logstash-cms5885_001_new     //目标索引必须不存在
{
  "settings":{
    "index.number_of_shards": 10                    //必须是源索引分片数的倍数,切成10个
  }
}

第三步:取消目标索引只读,恢复写功能

代码语言:javascript复制
PUT logstash-cms5885_001_new/_settings
{
  "settings":{
    "index.blocks.write": false
  }
}

最后:用户确认新索引无误后删除源索引以释放空间。

  • 环境 ES 6.8.2

刚前面的文章说了,如果是ES6的环境,源索引必须具备“the number of routing shards”属性,

如果不具备这个参数,在执行上面的API时,报错如下,API无法执行。

因此,ES6环境下正常的split操作流程应该是这样:

代码语言:javascript复制
PUT testserver{
    "settings": {
        "index.number_of_shards" : 3,     //主分片数
        "index.number_of_replicas": 0,
        "index.number_of_routing_shards" : 30 //将来可以支持切割的主分片数的最大数,这个值应该设置的足够大,建议设置为主分片数的倍数
    }        
}

接下来,设置只读属性,

代码语言:javascript复制
PUT /testserver/_settings
{
  "settings": {
    "index.blocks.write": true 
  }
}

接下来,我们进行切割:

代码语言:javascript复制
POST testserver/_split/testserver-target?copy_settings=true
{
  "settings": {
    "index.number_of_shards": 5
  }
}

报错如下:

代码语言:javascript复制
{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[1609341716000179332][10.1.3.9:9300][indices:admin/resize]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "the number of source shards [3] must be a factor of [5]"  //目标主分片数不是源的倍数
  },
  "status": 400
}

OK,那我们换成6试试,执行成功。

代码语言:javascript复制
POST testserver/_split/testserver-target?copy_settings=true
{
  "settings": {
    "index.number_of_shards": 6,
    "index.number_of_replicas":0
  }
}
//
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "testserver-target"
}

我们可以使用GET _cat/shards/testserver-target,查看目标索引的分片分布

目标索引分片分布查看目标索引分片分布查看

如果目标索引的个数大于30呢,我们看看是什么效果?很明显,是不可以的。路由分片的个数必须是目标索引主分片数的倍数。

代码语言:javascript复制
POST testserver/_split/testserver-target?copy_settings=true
{
  "settings": {
    "index.number_of_shards": 36,
    "index.number_of_replicas":0
  }
}

反馈如下:
{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[1609341716000179332][10.1.3.9:9300][indices:admin/resize]"
      }
    ],
    "type": "illegal_state_exception",
    "reason": "the number of routing shards [30] must be a multiple of the target shards [36]"
  },
  "status": 500
}

因此,我们基于上面的测试可以知道,在ES6环境下,目标索引主分片数必须是源索引分片数的倍数,必须大于源分片数,同时必须小于路由分片数。

那么,在ES6环境下,对于那些集群存量的数量大同时分片比较少的索引,在不适合使用split的环境下,我们还能用什么方法去切割索引呢,可以使用Reindex来操作。

三、Reindex 介绍、实践

reindex是数据复制的API ,实际生产中用的比较多,这里重点讲解一下其实际如何操作。

第一步:先创建目标索引,指定mapping、settings分片数

代码语言:javascript复制
PUT   目标索引
{
    "settings": {
        "index.number_of_shards" : 20,
        "index.number_of_replicas": 0,
        "index.number_of_routing_shards" : 60,
        "index.mapping.total_fields.limit": 2000
    }
}

第二步:执行如下API:

代码语言:javascript复制

如果索引比较大,可以加一个参数,放到后台执行

POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "index_A"
  },
  "dest": {
    "index": "index_目标索引"
  }
}

第三步: 执行上面的API,会生成一个TaskID ,

代码语言:javascript复制
{
  "task" : "xWyhGhgpSqGGJA9CtWciaQ:2244774"
}

d

第四步: 查看复制进度,通过GET _tasks/taskID的方式进行查看

代码语言:javascript复制
GET _tasks/xWyhGhgpSqGGJA9CtWciaQ:2244774

Response,如下

四、 Shrink API

Shrink API 的作用:可以将索引的主分片数收缩到较小的值。会使用和源索引相同的配置去创建索引,仅仅降低主分片数。

因为Shrink API 采用硬链接的方式去读取文件,因此它的性能比reindex会好很多,但是它也有很多的限制

  • 源分片数必须是目标分片数的倍数,如果源分片数是素数,目标分片数必须是1;
  • 文件系统支持硬链接,会将segments硬链接到目标索引,所以性能好;
  • 在执行shrink API的时候,会执行一系列的验证,如下信息

  • 分片必须只读
  • 所有的分片必须在同一节点上
  • 集群健康状态为green

五、 Shrink API 实践

第一步,先创建一个源索引

代码语言:javascript复制
PUT my_source_index
{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 3
  }
}

第二步,尝试写入一个文档

代码语言:javascript复制
PUT my_source_index/_doc/1
{
  "key":"value"
}

第三步,查看该索引分片分布 GET /_cat/shards/my_source_index

第四步, 执行如下API,将分片减少到2个,看能否成功。

代码语言:javascript复制
POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 2, 
    "index.codec": "best_compression" 
  },
  "aliases": {
    "my_search_indices": {}
  }
}

报错如下:

大概意思是:源分片数要能整除目标分片数,是其的倍数。那我们调整成1,再试试

代码语言:javascript复制
POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 1, 
    "index.codec": "best_compression" 
  },
  "aliases": {
    "my_search_indices": {}
  }
}
  

上面的报错消失,又有新错。如下:

源索引要设置成,只读,执行如下命令

代码语言:javascript复制
  PUT my_source_index/_settings
  {
    "settings":{
      "index.blocks.write":true
    }
  }
  

再次执行shrink操作

代码语言:javascript复制
POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 1, 
    "index.codec": "best_compression" 
  },
  "aliases": {
    "my_search_indices": {}
  }
}

报错如下:

意思是,所有的源索引的所有分片必须是在同一节点上。可以使用如下API调整分片所属节点信息

代码语言:javascript复制
PUT my_source_index/_settings
{
  "index.routing.allocation.require._ip": "172.16.15.6"
}  

再次查看源索引的分片节点信息是否在同一节点上,如下:

再次执行如下命令,执行Shink操作

代码语言:javascript复制
POST my_source_index/_shrink/my_target_index
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.number_of_shards": 1, 
    "index.codec": "best_compression" 
  },
  "aliases": {
    "my_search_indices": {}
  }
}

返回成功

查看目标索引的分片信息,如下截图:

再次查看目标索引的文档内容是否正常,如下,返回正常。

这样,Shrink API操作成功。过程还是有点点复杂。

六、总结

今天花点时间动手总结了几个常用的API,希望能帮到大家,后续将更新更多的使用的操作API。

0 人点赞