【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月前
|
存储 人工智能 自然语言处理
Elasticsearch Inference API增加对阿里云AI的支持
本文将介绍如何在 Elasticsearch 中设置和使用阿里云的文本生成、重排序、稀疏向量和稠密向量服务,提升搜索相关性。
76 14
Elasticsearch Inference API增加对阿里云AI的支持
|
4月前
|
Java API 数据中心
百炼平台Java 集成API上传文档到数据中心并添加索引
本文主要演示阿里云百炼产品,如何通过API实现数据中心文档的上传和索引的添加。
114 3
|
6月前
|
监控 Shell API
了解asyncio高级api索引
【6月更文挑战第27天】本文是`asyncio` 高级API概览:运行异步任务如`run()`, `create_task()`;等待机制如`gather()`, `wait_for()`, `shield()`;任务管理如`current_task()`, `all_tasks()`;队列和子进程功能;同步原语包括锁、事件和信号量。示例中涉及`sleep()`, `gather()`, `wait_for()`, 子进程创建及同步异常`TimeoutError`和`CancelledError`。查阅官方文档以获取详细信息和示例代码。
51 1
了解asyncio高级api索引
|
6月前
|
人工智能 自然语言处理 搜索推荐
Elasticsearch 开放 inference API 增加了对 Azure OpenAI 嵌入的支持
【6月更文挑战第8天】Elasticsearch 推出开放 inference API,支持 Azure OpenAI 嵌入,强化搜索和数据分析能力。此更新使用户能灵活集成 AI 技术,实现智能精准搜索。Azure OpenAI 的语言理解能力优化了用户查询处理,提升搜索相关性。示例代码显示了如何结合两者处理查询。该创新提升数据检索效率,适用于智能客服和推荐系统,但也带来数据安全和模型准确性等挑战。这标志着搜索和数据分析领域的智能化新阶段,期待更多创新应用。未来,我们需要持续探索和完善,以发挥技术的最大潜力。
50 3
|
6月前
|
存储 缓存 Java
掌握Elasticsearch集群参数查询API
掌握Elasticsearch集群参数查询API
|
7月前
|
运维 架构师 搜索推荐
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
7 年+积累、 Elastic 创始人Shay Banon 等 15 位专家推荐的 Elasticsearch 8.X新书已上线...
86 4
|
7月前
|
存储 自然语言处理 搜索推荐
Elasticsearch 8.10 同义词管理新篇章:引入同义词 API
Elasticsearch 8.10 同义词管理新篇章:引入同义词 API
171 1
|
7月前
|
存储 安全 数据处理
Elastic 中国开发者大会2023最新干货——Elasticsearch 7、8 新功能一网打尽
Elastic 中国开发者大会2023最新干货——Elasticsearch 7、8 新功能一网打尽
69 0
|
7月前
|
存储 数据可视化 数据建模
阿里云大佬叮嘱我务必要科普这个 Elasticsearch API
阿里云大佬叮嘱我务必要科普这个 Elasticsearch API
76 0
|
21天前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
34 5

相关产品

  • 检索分析服务 Elasticsearch版