分片缩减场景

在有些情况下我们可能要缩减索引的分片的数量,例如前期设置的分片太多,每个分片实际数据量又较小,而一个查询需要访问每一个分片,会导致不必要的查询开销,影响查询效率。

分片缩减方式

分片缩减的方式有两种,一种是使用reindex api重建一个分片少的索引;另外一种是使用shrink api重建一个分片少的索引。其中shrink api的方式相对效率较高一些,但执行步骤较为复杂一些。

使用reindex api缩减分片数量

新建缩减后的index_to_shrink_target,然后使用reindex重建

PUT /index_to_shrink_target
{
  "settings": {
    "index": {
      "refresh_interval": "30s",
      "number_of_shards": "2",
      "translog": {
        "flush_threshold_size": "1024mb",
        "sync_interval": "30s",
        "durability": "async"
      },
      "number_of_replicas": "2"
    }
  },
  "mappings": {
    "properties": {
      ......
    }
  }
}

POST _reindex
{
  "source": {
    "index": "index_to_shrink_source"
  },
  "dest": {
    "index": "index_to_shrink_target"
  }
}

index_to_shrink_source为需要缩减的索引,index_to_shrink_target为缩减后的索引。

使用shrink api缩减分片数量

前提

在使用shrink api缩减分片数量需要满足一下条件:

  • 索引必须是只读状态(read-only)
  • 索引中每个主分片必须存在于同一节点上
  • 索引的健康状态必须是绿色

缩减前准备

明确需要缩减的索引的分片的分布,index_to_shrink_source为需要缩减的索引:

GET _cat/shards/index_to_shrink_source?v

删除副本、分配所有主分片到同一节点、禁止写入。

PUT index_to_shrink_source/_settings
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.routing.allocation.require._name": "es-datanode1",
    "index.blocks.write": true
  }
}

其中,es-datanode1为elasticsearch集群中节点。以上操作需要一定时间完成,可以通过如下命令查看执行状态:

GET _cat/shards/index_to_shrink_source?v

执行缩减

删除副本、分配所有主分片到同一节点、禁止写入三项操作执行完毕后,再使用_shrink index API 接口来对索引进行缩减:

POST index_to_shrink_source/_shrink/index_to_shrink_target
{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 2,
    "index.routing.allocation.require._name": null, 
    "index.blocks.write": null 
  }
}

index_to_shrink_target为缩小后的索引
注意:

  • 缩减后的分片数量必须能让原来的整除,也就是上面中的参数number_of_shards;
  • 可以先将副本设置为0,尽快完成分片,后续可以再修改。

查看缩减进度

GET _cat/recovery/index_to_shrink_target?human&detailed=true

当该命令输出结果中的进度都为100%时,表示分片缩减完成。

设置副本

PUT /index_to_shrink_target/_settings
{
    "number_of_replicas": 2
}

查看副本进度

GET _cat/shards/index_to_shrink_target?v

删除旧索引

DELETE /index_to_shrink_source?pretty

执行完删除命令后,可通过如下命令确认是否已经被真正删除掉:

GET /_cat/indices?v

追加别名

针对缩减主分片后的索引追加别名,避免缩减后索引不被之前的查询条件命中。

POST /_aliases
{
    "actions" : [
        { "add" : { "index" : "index_to_shrink_target", "alias" : "index_to_shrink_source" } }
    ]
}