ES使用_splitAPI重建索引、重新分配分片和副本


前言:
在默认情况下,我们新建的索引,只有1个分片和1个副本,在生产环境中不利于数据安全。那有些索引创建之前没有指定分片和副本数量,创建完成后,怎么重新分配分片和副本数量呢?
索引创建完成后,是不支持增加索引分片的,只能增加分片副本。但在目前的官方文档中,提到了_splitAPI重新分割索引的方式,来重新分配分片和副本。下面开始讲解一下步骤:

一、停止数据写入,将索引设为只读:

PUT /nginx/_settings
{
    "index.blocks.write":true
}

这样,logstash就不会写入数据了,可以看到logstash的日志中出现报错:

[2020-03-31T00:00:00,174][INFO ][logstash.outputs.elasticsearch][main] retrying failed action with response code: 403 ({"type"=>"cluster_block_exception", "reason"=>"index [nginx] blocked by: [FORBIDDEN/8/index write (api)];"})

二、备份索引数据:

PUT /_snapshot/my_backup/nginx
{
  "indices": "nginx"
}

三、使用_splitAPI创建索引

命令格式为:

POST /my_source_index/_split/my_target_index
{
  "settings": {     
    "index.number_of_shards": 3,
  }
}

上面的"index.number_of_shards": 3指的是分片数量为3个,这个数量必须是源索引分片数量的整数倍,源索引分片数量是3个的话,这个地方必须是3的倍数
按照这个格式我们来使用_splitAPI根据nginx索引创建一个跟nginx一样的索引:

POST /nginx/_split/tgnginx
{
  "settings": {     
    "index.number_of_shards": 3,
    "index.number_of_replicas":2
  }
}

创建完成后,看一下当前集群的索引情况:

[root@logstash ~]# curl '192.168.1.3:9200/_cat/indices?v'
health status index                    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   tgnginx                  CPn5kTdaRT-nDNpP7xn7Qg   3   2   3403034      2267417    851.3mb        360.3mb
green  open   nginx                    YnZO4fTUT5qreywyjmZuvg   3   1   3686096            0     1009mb          252mb
green  open   .kibana_task_manager_1   XJL-tjI9SpCA_fe79A05vg   1   1          2            1       38kb         17.1kb
green  open   .apm-agent-configuration kGo27hTHQyKCPPbtfHzpeg   1   1          0            0       566b           283b
green  open   .kibana_1                fLrmHniMTy-LT_Z3Mc6Vdw   1   1         45           17    150.2kb         75.7kb

现在新的索引创建完成了,当前我们使用索引数据,有两种选择:
一个是将logstash中output的索引名称修改为新的tgnginx,将数据直接输出到新的索引中,然后生产上所有接入到nginx索引的,全都改为tgnginx;
另一个方法是将现有的nginx索引删除,(因为上面我们已经将该索引备份了,不用担心数据丢失。)删除后,再使用_splitAPI根据tgnginx索引创建一个新的nginx索引。
现在我们测试一下第二个方法:
这个时候要注意一下:我们的logstash并没有停止运行,如果我们直接删除nginx索引,logstash会再给我们创建一个nginx索引,我们想继续后面的操作就会报错,所以要先把logstash中关于nginx索引的部分暂停下来。

删除nginx索引:

DELETE /nginx

创建一个新的nginx:

POST /tgnginx/_split/nginx
{
  "settings": {     
    "index.number_of_shards": 3,
    "index.number_of_replicas":2
  }
}

我们可以使用以下命令监控进度:

GET /_cat/recovery/nginx?v

会得到以下响应:

index shard time  type           stage source_host source_node target_host target_node repository snapshot files files_recovered files_percent files_total bytes bytes_recovered bytes_percent bytes_total translog_ops translog_ops_recovered translog_ops_percent
nginx 0     7.5s  peer           done  192.168.1.6 es4         192.168.1.7 es5         n/a        n/a      0     0               0.0%          0           0     0               0.0%          0           0            0                      100.0%
nginx 0     23.1s existing_store done  n/a         n/a         192.168.1.6 es4         n/a        n/a      0     0               100.0%        21          0     0               100.0%        82743907    40430        40430                  100.0%
nginx 0     7.3s  peer           done  192.168.1.6 es4         192.168.1.8 es6         n/a        n/a      0     0               0.0%          0           0     0               0.0%          0           0            0                      100.0%
nginx 1     19.7s peer           done  192.168.1.8 es6         192.168.1.7 es5         n/a        n/a      0     0               0.0%          0           0     0               0.0%          0           40415        40415                  100.0%
nginx 1     11.9s peer           done  192.168.1.8 es6         192.168.1.6 es4         n/a        n/a      0     0               0.0%          0           0     0               0.0%          0           40415        40415                  100.0%
nginx 1     22.7s existing_store done  n/a         n/a         192.168.1.8 es6         n/a        n/a      0     0               100.0%        21          0     0               100.0%        82624112    40415        40415                  100.0%
nginx 2     3.3s  peer           done  192.168.1.8 es6         192.168.1.7 es5         n/a        n/a      0     0               0.0%          0           0     0               0.0%          0           0            0                      100.0%
nginx 2     20.7s peer           done  192.168.1.8 es6         192.168.1.6 es4         n/a        n/a      0     0               0.0%          0           0     0               0.0%          0           40245        40245                  100.0%
nginx 2     5s    existing_store done  n/a         n/a         192.168.1.8 es6         n/a        n/a      0     0               100.0%        21          0     0               100.0%        82605452    0            0                      100.0%

以上可以看出每个分片和副本的进度,每个分片和它的两个副本都不在同一个节点上,这样做是为了保证数据安全。
在整个过程中,我们可以使用/_cat/healthAPI来监控集群和索引状态,可以看到nginx索引这状态从red变为yellow,再变为green。

四、解除索引的只读状态

这个地方我费了好几个小时才解决问题,按照网上的方法执行以下命令,解除只读,但我尝试了不行:

PUT /nginx/_settings
{
  "index":{
    "blocks":{
      "read_only_allow_delete": "false"
    }
  }
}

这种方法我试了不行!执行上述命令后,要再次执行以下命令才能取消:

PUT /nginx/_settings
{
  "index":{
    "blocks":{
      "read_only_allow_delete": null
    }
  }
}

要把索引改为可写,要执行以下命令才行:

PUT /nginx/_settings
{
  "index": {
    "blocks": {
      "write": null
    }
  }
}

然后就解除只读限制了。

如果要查看一个索引是否限制只读了,可以执行下面这条命令查看以下:

GET /index-name

比如我们查看一下tgnginx这个索引是否为只读状态:

GET /tgnginx

会得到一个很长的响应值,我们只要找到blocks部分,就知道有没有限制只读:

"blocks" : {
   "write" : "true"
   }

这里看到的是"blocks.write":“true”,说明有只读限制。
本期就到这里。

发布了21 篇原创文章 · 获赞 6 · 访问量 2854

猜你喜欢

转载自blog.csdn.net/weixin_43334786/article/details/105252513