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”,說明有隻讀限制。
本期就到這裏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章