前言:
在默认情况下,我们新建的索引,只有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”,说明有只读限制。
本期就到这里。