【Elastic Engineering】Elasticsearch:通过 shrink API 减少 shard 数量来缩小 Elasticsearch 索引

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch:通过 shrink API 减少 shard 数量来缩小 Elasticsearch 索引

作者:刘晓国


通过使用 Shrink API 使用更少的主碎片来调整 Elasticsearch 索引的大小。在 Elasticsearch 中,每个索引都包含多个分片,而 Elasticsearch 集群中的每个分片都有助于使用cpu,内存,文件描述符等。这无疑有助于并行处理的性能。 以时间序列数据为例,你将对带有当前日期的索引进行大量读写。


如果该索引下降了请求,并且仅时不时地从该索引中读取数据,那么我们不再需要那么多分片,并且如果我们有多个索引,它们可能会建立并占用大量的计算能力。


对于要减少索引大小的情况,可以使用 Shrink API 减少主分片的数量。


这个过程和我之前介绍的文章 “Split index API - 把一个大的索引分拆成更多分片”刚好相反。在那篇文章中,我们是把一个索引拆分为多个。


Shrink API 介绍


Shrink index API 使你可以使用较少的主碎片将现有索引收缩为新索引。 目标索引中请求的主分片数量必须是源索引中的分片数量的一个分数。 例如,可以将具有8个主碎片的索引缩减为4、2或1个主碎片,或者将具有15个主碎片的索引缩减为5、3或1。如果索引中的分片数是质数,则可以 仅缩小为一个主碎片。 在收缩之前,我们必须满足一下的几个条件:


索引中每个分片的(主副本或副本副本)必须存在于同一节点上。

索引必须是 read-only

索引的健康状态必须是绿色,请查看 health status


简单地说,我们可以通过如下的命令来实现:

PUT /my_source_index/_settings
{
  "settings": {
    "index.number_of_replicas": 0,       (1)                         
    "index.routing.allocation.require._name": "shrink_node_name", (2) 
    "index.blocks.write": true  (3)                                  
  }
}

在上面:


1.删除索引的所有备份

2.把索引的分片重新分配到一个叫做 shrink_node_name 的节点。可以具体参阅文章 “运用shard filtering来控制索引分配给哪个节点” 把主副分片分配于同一个节点上,或者链接 Index-level shard allocation filtering.

3.禁止对此索引进行写操作。 仍然允许元数据更改,例如删除索引。


Shrink 步骤


使用与源索引相同的定义创建目标索引,但主碎片数量较少。 然后,它将段从源索引硬链接到目标索引。 最后,它恢复目标索引,就好像它是刚刚重新打开的封闭索引一样。


动手实践


我们首先按照之前的文章 “Split index API - 把一个大的索引分拆成更多分片” 把一个索引分拆为两个索引。

GET _cat/shards/kibana_sample_data_logs_split?v

上面的命令显示:

index                         shard prirep state   docs store ip        node
kibana_sample_data_logs_split 1     p      STARTED 7076 4.8mb 127.0.0.1 node1
kibana_sample_data_logs_split 0     p      STARTED 6998 4.7mb 127.0.0.1 node1

这个 kibana_sample_data_logs_split 索引有两个 primary shard。我们该如何把这个已经被拆分的索引重新变为只有一个 primary shard。当然具体的数量,可以按照你自己的要求来定义,只要符合上面的数量的要求描述。


按照上面的要求,我们需要把该索引集中到一个节点上。为此,我们可以通过如下的方式来获得索引 kibana_sample_data_logs_split 所在的 node 的名称:

GET _cat/shards/kibana_sample_data_logs_split?v

上面的命令显示:

index                         shard prirep state   docs store ip        node
kibana_sample_data_logs_split 1     p      STARTED 7076 4.8mb 127.0.0.1 node1
kibana_sample_data_logs_split 0     p      STARTED 6998 4.7mb 127.0.0.1 node1

上面显示 kibana_sample_data_logs_split 处于 node1 节点上。当然在我们的实际的使用中,这个节点会有不同,同时,还会有不同的副本的显示在不同的节点上,比如就像如下的一个结构:

index               shard prirep state   docs  store ip       node
my-index-2019.01.10 2     p      STARTED  193  101mb x.x.x.x  Lq9P7eP
my-index-2019.01.10 2     r      STARTED  193  101mb x.x.x.x  F5edOwK
my-index-2019.01.10 4     p      STARTED  197  101mb x.x.x.x  Lq9P7eP
my-index-2019.01.10 4     r      STARTED  197  101mb x.x.x.x  F5edOwK
my-index-2019.01.10 3     r      STARTED  184  101mb x.x.x.x  Lq9P7eP
my-index-2019.01.10 3     p      STARTED  184  101mb x.x.x.x  F5edOwK
my-index-2019.01.10 1     r      STARTED  180  101mb x.x.x.x  Lq9P7eP
my-index-2019.01.10 1     p      STARTED  180  101mb x.x.x.x  F5edOwK
my-index-2019.01.10 0     p      STARTED  187  101mb x.x.x.x  Lq9P7eP
my-index-2019.01.10 0     r      STARTED  187  101mb x.x.x.x  F5edOwK

按照上面的要求,我们执行如下的命令:

PUT kibana_sample_data_logs_split/_settings
{
  "settings": {
    "index.number_of_replicas": 0,
    "index.routing.allocation.require._name": "node1",
    "index.blocks.write": true
  }
}

上面的命令将删除索引的副本,把所有的主分片分配到 node1 的节点,并同时禁止写入。我们安装如下的方式来查询所有的分片的情况:

GET _cat/shards/kibana_sample_data_logs_split?v

上面显示的结果为:

index                         shard prirep state   docs store ip        node
kibana_sample_data_logs_split 1     p      STARTED 7076 4.8mb 127.0.0.1 node1
kibana_sample_data_logs_split 0     p      STARTED 6998 4.7mb 127.0.0.1 node1

显然所有的分片都已经在 node1 上。


接下来,我们使用 _shrink index API 接口来对索引进行缩小:

POST kibana_sample_data_logs_split/_shrink/kibana_sample_data_logs_shrink
{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 1,
    "index.codec": "best_compression",
    "index.routing.allocation.require._name": null, 
    "index.blocks.write": null 
  },
  "aliases": {
    "my_search_indices": {}
  }
}

在上面,我们清除了对索引的分配要求,并同时允许写入。运行完上的命令后,我们可以通过如下的方式来进行查询过程:

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

我们可以查看到如下的信息:

kibana_sample_data_logs_shrink 0 345ms local_shards done n/a n/a 127.0.0.1 node1 n/a n/a 0 0 100.0% 30 0 0 100.0% 10093464 0 0 100.0%

我们可以看到完成度为 100%。


我们通过如下的命令来查看 kibana_sample_data_logs_shrink 的 primary shard 的数量:

kibana_sample_data_logs_shrink 0 345ms local_shards done n/a n/a 127.0.0.1 node1 n/a n/a 0 0 100.0% 30 0 0 100.0% 10093464 0 0 100.0%

上面的命令:

index                          shard prirep state    docs store ip        node
kibana_sample_data_logs_shrink 0     p      STARTED 14074 9.6mb 127.0.0.1 node1

我们查看一下这个所的文档数量:

GET kibana_sample_data_logs_shrink/_count

上面的结果显示:

{
  "count" : 14074,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  }
}

这个显然和我们最原始的文档的数量是一样的。


在很多的情况下,我们甚至可以把该索引的 segments 的数量降为1。我们可以通过如下的方法来做:

POST kibana_sample_data_logs_shrink/_forcemerge?max_num_segments=1

上面的命令将返回:

{
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  }
}

这样我们可以提高搜索的速度。


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 人工智能 API
(Elasticsearch)使用阿里云 infererence API 及 semantic text 进行向量搜索
本文展示了如何使用阿里云 infererence API 及 semantic text 进行向量搜索。
102 8
|
4月前
|
存储 人工智能 自然语言处理
Elasticsearch Inference API增加对阿里云AI的支持
本文将介绍如何在 Elasticsearch 中设置和使用阿里云的文本生成、重排序、稀疏向量和稠密向量服务,提升搜索相关性。
169 14
Elasticsearch Inference API增加对阿里云AI的支持
|
3月前
|
存储 缓存 监控
优化Elasticsearch 索引设计
优化Elasticsearch 索引设计
38 5
|
3月前
|
监控 API 索引
Elasticsearch集群使用 _cluster/health API
Elasticsearch集群使用 _cluster/health API
85 2
|
3月前
|
Unix API 索引
Elasticsearch集群使用 _cat/health API
Elasticsearch集群使用 _cat/health API
49 1
|
3月前
|
存储 JSON 关系型数据库
Elasticsearch 索引
【11月更文挑战第3天】
49 4
|
3月前
|
测试技术 API 开发工具
ElasticSearch7.6.x 模板及滚动索引创建及注意事项
ElasticSearch7.6.x 模板及滚动索引创建及注意事项
60 8
|
20天前
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
5天前
|
搜索推荐 数据挖掘 API
微店商品详情接口(微店API系列)
微店商品详情接口是微店API的重要组成部分,帮助开发者和商家获取商品的详细信息(如标题、价格、库存等),并将其集成到应用程序或数据分析系统中。该接口支持HTTP GET/POST请求,返回JSON/XML格式数据,需通过AppKey和AppSecret进行身份验证和签名加密。应用场景包括商品信息同步、数据分析与市场调研、个性化推荐系统等,助力商业决策和业务拓展。
28 13
|
7天前
|
供应链 数据挖掘 API
1688app 商品详情接口系列(1688API)
1688作为国内知名批发采购平台,提供了一系列商品详情接口(API),助力企业和开发者获取商品基础、价格、库存及供应商信息。通过Python示例代码展示如何调用这些接口,应用场景涵盖采购决策辅助、数据分析与市场调研、电商平台整合及供应链管理系统的优化,为企业和采购商提供有力的数据支持,提升业务效率和竞争力。
44 15

热门文章

最新文章

相关产品

  • 检索分析服务 Elasticsearch版