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

本文涉及的产品
Elasticsearch Serverless通用抵扣包,测试体验金 200元
简介: 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
  }
}

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


相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
9月前
|
存储 人工智能 API
(Elasticsearch)使用阿里云 infererence API 及 semantic text 进行向量搜索
本文展示了如何使用阿里云 infererence API 及 semantic text 进行向量搜索。
370 8
|
11月前
|
存储 人工智能 自然语言处理
Elasticsearch Inference API增加对阿里云AI的支持
本文将介绍如何在 Elasticsearch 中设置和使用阿里云的文本生成、重排序、稀疏向量和稠密向量服务,提升搜索相关性。
394 14
Elasticsearch Inference API增加对阿里云AI的支持
|
10月前
|
监控 API 索引
Elasticsearch集群使用 _cluster/health API
Elasticsearch集群使用 _cluster/health API
373 2
|
10月前
|
Unix API 索引
Elasticsearch集群使用 _cat/health API
Elasticsearch集群使用 _cat/health API
178 1
|
人工智能 自然语言处理 搜索推荐
Elasticsearch 开放 inference API 增加了对 Azure OpenAI 嵌入的支持
【6月更文挑战第8天】Elasticsearch 推出开放 inference API,支持 Azure OpenAI 嵌入,强化搜索和数据分析能力。此更新使用户能灵活集成 AI 技术,实现智能精准搜索。Azure OpenAI 的语言理解能力优化了用户查询处理,提升搜索相关性。示例代码显示了如何结合两者处理查询。该创新提升数据检索效率,适用于智能客服和推荐系统,但也带来数据安全和模型准确性等挑战。这标志着搜索和数据分析领域的智能化新阶段,期待更多创新应用。未来,我们需要持续探索和完善,以发挥技术的最大潜力。
123 3
|
运维 架构师 搜索推荐
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
|
存储 自然语言处理 搜索推荐
Elasticsearch 8.10 同义词管理新篇章:引入同义词 API
Elasticsearch 8.10 同义词管理新篇章:引入同义词 API
|
存储 缓存 Java
掌握Elasticsearch集群参数查询API
掌握Elasticsearch集群参数查询API
|
1月前
|
JSON API 数据格式
淘宝/天猫图片搜索API接口,json返回数据。
淘宝/天猫平台虽未开放直接的图片搜索API,但可通过阿里妈妈淘宝联盟或天猫开放平台接口实现类似功能。本文提供基于淘宝联盟的图片关联商品搜索Curl示例及JSON响应说明,适用于已获权限的开发者。如需更高精度搜索,可选用阿里云视觉智能API。
|
1月前
|
JSON API 数据安全/隐私保护
深度分析淘宝卖家订单详情API接口,用json返回数据
淘宝卖家订单详情API(taobao.trade.fullinfo.get)是淘宝开放平台提供的重要接口,用于获取单个订单的完整信息,包括订单状态、买家信息、商品明细、支付与物流信息等,支撑订单管理、ERP对接及售后处理。需通过appkey、appsecret和session认证,并遵守调用频率与数据权限限制。本文详解其使用方法并附Python调用示例。

相关产品

  • 检索分析服务 Elasticsearch版