Elasticsearch之索引管理API(Index management)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch之索引管理API(Index management)

本文将详细介绍ES索引管理相关的API。


ES索引管理API主要包含如下API:


  • Create Index
    创建索引。
  • Delete Index
    删除索引。
  • Get index
    获取索引。
  • indices Exists Index
    判断索引是否存在
  • Open/Close Index
    打开或关闭索引,使用close index api会使索引处于关闭状态,此时无法对该索引进行读、写,但索引数据不会被删除。
  • Shrink Index
    收缩索引。收缩索引API允许您将现有索引收缩为具有较少主碎片的新索引(下文为们称之为目标索引)。伸缩后的索引主分片的个数必须是原分片的公约数,举例说明,如果原先索引的个数为15,那伸缩后的索引主分片数量可以是3、5、1。
  • Split Index
    拆分索引。将一个索引的主分片个数扩容,详情下文讲解。
  • Rollover Index
    翻转索引,有点类似于log4j记录日志的方式,例如,按日志文件大小超过多少后,创建一个新的文件一样。


image.png

创建索引,通常创建索引API包含3个部分:索引配置、索引映射、索引别名,例如:

1PUT test
 2{
 3    "settings" : {                 //@1
 4        "number_of_shards" : 1
 5    }, 
 6    "mappings" : {                // @2
 7        "_doc" : {
 8            "properties" : {
 9                "field1" : { "type" : "text" }
10            }
11        }
12    },
13    "aliases" : {                  // @3
14        "alias_1" : {},
15        "alias_2" : {
16            "filter" : {
17                "term" : {"user" : "kimchy" }
18            },
19            "routing" : "kimchy"
20        }
21    }
22}

代码@1:索引的配置属性。请详细参考如下博文:


代码@2:定义映射,有点类似于关系型数据库中的定义表结构,详情请参考:Elasticsearch Mapping parameters(主要参数一览)Elasticsearch Mapping类型映射概述与元字段详解


代码@3:为索引指定别名设置。


对应的JAVA示例代码:

1public static void createSuggestMapping() {
 2        RestHighLevelClient client = EsClient.getClient();
 3        try {
 4            CreateIndexRequest request = new CreateIndexRequest("suggest_mapping_001");
 5            XContentBuilder jsonBuilder = XContentFactory.jsonBuilder()
 6                                            .startObject()
 7                                                .startObject("properties")
 8                                                    .startObject("context")
 9                                                        .field("type", "text")
10                                                        .field("analyzer", "ik_smart")
11                                                        .field("search_analyzer", "ik_smart")
12                                                    .endObject()
13                                                .endObject()
14                                            .endObject();
15            request.mapping("_doc", jsonBuilder);
16            System.out.println(client.indices().create(request, RequestOptions.DEFAULT));
17        } catch (Throwable e) {
18            e.printStackTrace();
19        } finally {
20            EsClient.close(client);
21        }
22    }


image.png

查找、删除、打开与关闭索引的使用方法与创建索引类似,都是通过RestHighLevelClient#indices()对应的方法来实现。


类图


接下来从Request类图入手,展示上述API重点的参数。

f838a37d5de03183d37c648cf0a8c4a8.jpg

  • MasterNodeReadRequest
    masterNodeTimeout:查找、连接masterNode的超时时间,默认为30s。
  • AcknowledgedRequest
    ackTimeout、timeout:请求超时时间。
  • DeleteIndexRequest、GetIndexRequest、OpenIndexRequest、CLoseIndexRequest公共属性:

1、private String[] indices
上述API待操作的索引,即可以同时删除、查找、打开或关闭多个索引。
2、private IndicesOptions indicesOptions
索引操作选项。


IndicesOptions(索引操作选项)



42767e9acf0f514c70d21cb51103d215.png

IndicesOptions$WildcardStates枚举类型主要定义通配符的作用范围,例如OPEN,表示处于打开状态的索引,而CLOSE表示处于关闭状态的索引。


IndicesOptions$Option定义操作选项:


  • IGNORE_UNAVAILABLE
    可忽略不可用的索引。
  • IGNORE_ALIASES
    忽略别名。
  • ALLOW_NO_INDICES
    允许索引不存在。
  • FORBID_ALIASES_TO_MULTIPLE_INDICES
    禁止操作多个索引或别名。
  • FORBID_CLOSED_INDICES
    禁止操作关闭状态的索引,如果有这个选项,则API只能对OPEN状态的索引进行操作。


IndicesOptions针对上面进行组合,默认给出了一些常量组合:


  • STRICT_EXPAND_OPEN
    (EnumSet.of(Option.ALLOW_NO_INDICES), EnumSet.of(WildcardStates.OPEN))
    主要代表如下几层意义:
    1、如果是指定索引,则索引必须存在。
    2、通配符匹配的范围为OPEN状态的索引。
    3、如果使用通配符来查找索引,未匹配到任何索引不会抛出异常。
  • LENIENT_EXPAND_OPEN
    (EnumSet.of(Option.ALLOW_NO_INDICES, Option.IGNORE_UNAVAILABLE), EnumSet.of(WildcardStates.OPEN))
    主要代表如下几层意义:
    1、允许索引不存在,指定一个不存在的索引,也不会抛出异常。
    2、通配符作用范围为OPEN状态的索引。
    3、如果使用通配符来查找索引,未匹配到任何索引不会抛出异常。
  • STRICT_EXPAND_OPEN_CLOSED
    (EnumSet.of(Option.ALLOW_NO_INDICES), EnumSet.of(WildcardStates.OPEN, WildcardStates.CLOSED))
    主要代表如下几层意义:
    1、如果指定索引,该索引必须存在。
    2、通配符作用范围为OPEN、CLOSED状态的索引。
    3、如果使用通配符来查找索引,未匹配到任何索引不会抛出异常。
  • STRICT_EXPAND_OPEN_FORBID_CLOSED
    (EnumSet.of(Option.ALLOW_NO_INDICES, Option.FORBID_CLOSED_INDICES), EnumSet.of(WildcardStates.OPEN))
    主要代表如下几层意义:
    1、如果指定索引,该索引必须存在。
    2、通配符作用范围为OPEN状态的索引。
    3、如果使用通配符查找索引,未找到索引不会抛出异常。
    4、禁止指定CLOSE状态的索引。 [6.4.0版本测试,这条规则未生效]
  • STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED
    (EnumSet.of(Option.FORBID_ALIASES_TO_MULTIPLE_INDICES, Option.FORBID_CLOSED_INDICES), EnumSet.noneOf(WildcardStates.class))。
    主要代表如下几层意义:
    1、指定的索引或别名必须存在。
    2、不允许使用通配符。
    3、不允许一个别名解析出多个索引的情况。


上面是对IndicesOptions中的枚举类型与默认定义的索引选项进行了一个说明,当然也可以通过IndicesOptions#fromOptions来自定义。


Java示例


删除、打开、查找,关闭等API的使用类似,下面给出一个简单的JAVA示例:

1public static final void testGetIndex() {
 2    RestHighLevelClient client = EsClient.getClient();
 3    try {
 4        GetIndexRequest request = new GetIndexRequest();
 5        request.indices("suggest_mapping_001*")
 6                  //.indicesOptions(IndicesOptions.STRICT_EXPAND_OPEN)
 7                   //.indicesOptions(IndicesOptions.STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED)
 8                   //.indicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN)
 9                   //.includeDefaults(true) 是否输出包含默认配置(settings),默认为false
10                  // .indicesOptions(IndicesOptions.STRICT_EXPAND_OPEN_FORBID_CLOSED)
11                     .indicesOptions(IndicesOptions.STRICT_SINGLE_INDEX_NO_EXPAND_FORBID_CLOSED)
12                   ;
13        System.out.println(client.indices().get(request, RequestOptions.DEFAULT));
14    } catch (Throwable e) {
15        e.printStackTrace();
16    } finally {
17        EsClient.close(client);
18    }
19}


image.png

Split Index,拆分索引。


Shrink Index


收缩索引。收缩索引API允许您将现有索引收缩为具有较少主碎片的新索引(下文为们称之为目标索引)。伸缩后的索引主分片的个数必须是原分片的公约数,举例说明,如果原先索引的个数为15,那伸缩后的索引主分片数量可以是3、5、1。


索引收缩过程:


  • 首先,它创建一个新的目标索引,其定义与源索引相同,但是主碎片的数量更少。
  • 然后它将段从源索引硬链接到目标索引。如果文件系统不支持硬链接,那么所有段都会复制到新索引中,这是一个非常耗时的过程。
  • 然后恢复目标索引,使其能正常工作。


收缩索引前置条件:


  • 设置索引为只读。
  • 将待收缩索引(Source Index)的所有主分片与副本分片重定向到一个节点上
  • 集群的状态为:green。


首先使用如下API更新源索引的配置信息(settings):


1PUT /my_source_index/_settings
2{
3  "settings": {
4    "index.routing.allocation.require._name": "shrink_node_name",  // @1
5    "index.blocks.write": true                                                               // @2
6  }
7}


代码@1:index.routing.allocation.require._name:强制将索引下所有的副本转移到指定名称(node.name)。


代码@2:设置该索引数据只读,无法再添加新的索引数据,但可以改变索引元数据。

注意:此过程可能需要一段时间,可以通过(_cat recovery api)或cluster health API查看其进度。


Shrink API使用示例:

1POST my_source_index/_shrink/my_target_index?copy_settings=true
2{
3  "settings": {
4    "index.routing.allocation.require._name": null,     // @1
5    "index.blocks.write": null                                       // @2
6  }
7}

这里要特别注意,由于在收缩之前,改变了原索引的相关配置,收缩后的索引,需要恢复这些配置。


对应的JAVA示例:

1public static final void testShrinkIndex() {
 2        RestHighLevelClient client = EsClient.getClient();
 3        try {
 4            Map settings = new HashMap();
 5            settings.put("index.routing.allocation.require._name", null);
 6            settings.put("index.blocks.write", false);
 7            ResizeRequest resizeRequest = new ResizeRequest("targetIndex", "sourceIndex");
 8            resizeRequest.setCopySettings(true);
 9            resizeRequest.getTargetIndexRequest().settings(settings);
10            ResizeResponse result = client.indices().shrink(resizeRequest, RequestOptions.DEFAULT);
11            System.out.println(result);
12        } catch (Throwable e) {
13            e.printStackTrace();
14        } finally {
15            EsClient.close(client);
16        }
17}

上面的请求,只要目标索引在集群中配置,立即胡返回,不会等到收缩完成。


收缩索引的必要条件如下:


  • 目标索引必须不存在。
  • 源索引必须具有比目标索引更多的主分片数量。
  • 目标索引中的主分片数量必须是源索引中的主分片数量的一个公因子。
  • 索引不能包含超过2,147,483,519个文档,因为这是一个碎片中可以容纳的最大文档数量。
  • 处理收缩过程的节点必须有足够的空闲磁盘空间来容纳现有索引的第二个副本。


索引收缩是可以通过_cat recovery api和cluster health api来监控shrink的过程,这两个命令将在后续文章中详解。


收缩索引由于需要创建索引,故支持wait_for_active_shards参数。


Split Index


拆分索引。


注意:在elasticsearch7.0版本之前,如果将来需要使用split api拆分索引,那么需要在创建索引的时候指定number_of_routing_shards参数,方便日后进行索引的拆分。


number_of_routing_shards用来指定指定内部用于跨具有一致哈希的分片分发文档的哈希空间。例如,一个拥有5个主分片的索引,其number_of_routing_shards设置为30 (5 x 2 x 3)的5切分索引可以除以2或3的因数,其拆分方式如下:


  • 5 → 10 → 30 (split by 2, then by 3)
  • 5 → 15 → 30 (split by 3, then by 2)
  • 5 → 30 (split by 6)


索引拆分过程


  • 首先,它创建一个新的目标索引,其定义与源索引相同,但主分片数量增大。
  • 然后它将段从源索引硬链接到目标索引。(如果文件系统不支持硬链接,那么所有段都会复制到新索引中,这是一个非常耗时的过程。)
  • 一旦创建了底层文件,所有文档将再次散列,以删除属于不同切分的文档。
  • 最后恢复目标索引,使该索引可用。


拆分索引前置条件:


  • 设置索引为只读。


其对应的API:

1PUT /my_source_index/_settings
2{
3  "settings": {
4    "index.blocks.write": true     // 设置原索引只读
5  }
6}

然后使用Split Index拆分索引。

1POST my_source_index/_split/my_target_index?copy_settings=true
2{
3  "settings": {
4    "index.number_of_shards": 2
5  }
6}

其对应的JAVA代码:

1@SuppressWarnings({ "rawtypes", "unchecked" })
 2    public static final void testSplinkIndex() {
 3        RestHighLevelClient client = EsClient.getClient();
 4        try {
 5            Map settings = new HashMap();
 6            settings.put("index.number_of_shards", 2);
 7            ResizeRequest resizeRequest = new ResizeRequest("targetIndex", "sourceIndex");
 8            resizeRequest.setCopySettings(true);
 9            resizeRequest.getTargetIndexRequest().settings(settings);
10            ResizeResponse result = client.indices().split(resizeRequest, RequestOptions.DEFAULT);
11            System.out.println(result);
12        } catch (Throwable e) {
13            e.printStackTrace();
14        } finally {
15            EsClient.close(client);
16        }
17    }

拆分索引的必要条件如下:


  • 目标索引必须不存在。
  • 索引的主分片个数必须少于目标索引。
  • 目标索引中的主分片数量必须是源索引中的主分片数量的一个因子。
  • 处理拆分过程的节点必须有足够的空闲磁盘空间来容纳现有索引的第二个副本。


拆分过程的监控与收缩索引相同,不重复介绍。

image.png

rollover index API,当认为现有索引太大或太旧时,可以使用rollover index API将别名滚到新索引。该API必须接收一个索引别名和一个条件列表(用来从老的索引中过滤需要迁移的文档)。根据别名指向索引的类别,别名元数据将以不同的方式更新。两种情况如下:


  • alias只指向一个单一的索引(索引可写)
    在这个场景中,原始索引的rollover别名将被添加到新创建的索引中,并从原始索引中删除。
  • alias指向多个索引
    一个别名指向多个索引时,其中一个会通过is_write_index =true来表示写索引。
    在这个场景中,将原写索引is_write_index设置为false,而新创建的索引的is_write_index=true。


支持如下条件参数:


  • max_age
    索引年龄,从索引创建时间开始算起。
  • max_docs
    索引应该包含的最大文档数量。
  • max_size
    索引主分片最大大小。


示例:


step1:创建索引,并指定一个别名。


1PUT /logs-000001 
2{
3     "aliases": {
4         "logs_write": {}
5     }
6}

step2:向该索引中添加超过1000个文档。

1# Add > 1000 documents to logs-000001

step3:rollover 索引

1POST /logs_write/_rollover 
2{
3"conditions": {
4     "max_age":   "7d",     // @1
5     "max_docs":  1000,   // @2
6     "max_size":  "5gb"     // @3
7}
8}

代码@1:索引是否已创建7天。


代码@2:索引中包含的文档数量。


代码@3:索引的主分片大小。


索引命名


如果现有索引的名称以-和一个数字结束,例如logs-000001。然后,新索引的名称将遵循相同的模式,增加数字(log -000002)。无论旧索引名是什么,该数字都是零,长度为6。


如果原索引的名称不符合该格式,则需要手动指定新索引的名称。


1POST /my_alias/_rollover/my_new_index_name
2{
3  "conditions": {
4    "max_age":   "7d",
5    "max_docs":  1000,
6    "max_size": "5gb"
7  }
8}

4.2 date mesh方式

1# PUT /<logs-{now/d}-1> with URI encoding:
 2
 3PUT /%3Clogs-%7Bnow%2Fd%7D-1%3E    // @1
 4{
 5  "aliases": {
 6    "logs_write": {}
 7  }
 8}
 9
10PUT logs_write/_doc/1
11{
12  "message": "a dummy log"
13}
14
15POST logs_write/_refresh
16
17# Wait for a day to pass
18
19POST /logs_write/_rollover  // @2
20{
21  "conditions": {
22    "max_docs":   "1"
23  }
24}

代码@1:使用date mesh格式定义新索引的格式。


代码@2:创建一个以今天的日期(例如)命名的索引log -2016.10.31-1:,转到具有今天日期的新索引,例如如果立即运行,log -2016.10.31-000002,如果24小时后运行,log -2016.11.01-000002。


dry_run模式


rollover API支持dry_run模式,在这种模式下,无需执行实际的翻转就可以检查请求条件。


Java示例


1public static final void testRolloverIndex() {
 2        RestHighLevelClient client = EsClient.getClient();
 3        try {
 4            // public RolloverRequest(String alias, String newIndexName)
 5            RolloverRequest resizeRequest = new RolloverRequest("logs_write", null);
 6            resizeRequest.addMaxIndexAgeCondition(TimeValue.parseTimeValue("7d", "max_age"));
 7            resizeRequest.addMaxIndexDocsCondition(50);
 8            resizeRequest.addMaxIndexSizeCondition(ByteSizeValue.parseBytesSizeValue("5G", "max_index_size"));
 9            resizeRequest.dryRun(true);
10            RolloverResponse result = client.indices().rollover(resizeRequest, RequestOptions.DEFAULT);
11            System.out.println(result);
12        } catch (Throwable e) {
13            e.printStackTrace();
14        } finally {
15            EsClient.close(client);
16        }
17    }

在创建RolloverRequest时,newIndexName可以指定为空,新索引的命名遵循4.1、4.2中的规则。


本节详细介绍了索引管理相关的API,主要包括Index Create、Delete Index、Get index、indices Exists Index、Open/Close Index 、Shrink Index、Split Index、Rollover Index。有关于索引的更新,包括(映射Mapping、配置Settings)的更新比较简单,就不做介绍,下一节,我们重点探讨索引模板(Index Templates)。


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
Linux API 数据安全/隐私保护
【Linux 用户管理】Linux用户身份信息获取与管理API 接口
【Linux 用户管理】Linux用户身份信息获取与管理API 接口
29 0
|
3月前
|
存储 API 索引
Elasticsearch Reroute API 的使用
Elasticsearch Reroute API 的使用
42 1
|
4月前
|
存储 JSON 自然语言处理
Elasticsearch 利用API进行搜索
Elasticsearch 利用API进行搜索
36 0
|
3月前
|
API
GEE案例分析——利用sentinel-3数据计算空气污染指数(Air Pollution Index,简称API)
GEE案例分析——利用sentinel-3数据计算空气污染指数(Air Pollution Index,简称API)
115 0
|
6天前
|
前端开发 JavaScript API
React的Context API:全局状态管理的利器
【4月更文挑战第25天】React的Context API解决了深层组件间状态共享的难题,提供全局状态管理方案。通过`Provider`和`Consumer`组件,或结合`useContext` Hook,实现状态在组件树中的传递。最佳实践包括避免过度使用,分离逻辑,以及在必要时与Redux或MobX结合。Context API简化了数据传递,但需谨慎使用以保持代码清晰。
|
8天前
|
索引
Elasticsearch exception [type=illegal_argument_exception, reason=index [.1] is the write index for data stream [slowlog] and cannot be deleted]
在 Elasticsearch 中,你尝试删除的索引是一个数据流(data stream)的一部分,而且是数据流的写入索引(write index),因此无法直接删除它。为了解决这个问题,你可以按照以下步骤进行操作:
|
8天前
|
JSON JavaScript API
访问REST API:在Vue中消费和管理远程数据
【4月更文挑战第23天】本文探讨了在Vue应用中高效访问REST API的方法,包括选择合适的API、使用Axios或Fetch发送请求、封装API服务、处理响应和数据、错误管理及性能优化。关键点在于创建服务层封装请求,使用计算属性和方法处理数据,以及实施错误处理和性能提升策略。通过这些最佳实践,开发者能更好地管理和消费远程数据,构建出动态、响应式的Vue应用。
|
14天前
|
供应链 数据挖掘 API
淘宝API接口系列:数据分析丨Erp上货丨维权控价丨商品搬家丨店铺订单管理
淘宝API接口系列在多个方面为电商业务提供了强大的支持,包括数据分析、ERP上货、维权控价、商品搬家以及店铺订单管理。下面将针对这些方面逐一进行说明。
|
22天前
|
存储 监控 大数据
【Elasticsearch专栏 15】深入探索:Elasticsearch使用API删除旧数据
本文探讨了如何使用Elasticsearch API管理并删除旧数据。Elasticsearch提供RESTful API,支持按条件批量删除。删除策略可基于时间、文档数量或索引。通过`DELETE BY QUERY` API,可以根据时间戳范围删除数据,如删除早于30天的记录。为处理大量数据,建议分批次进行,使用`scroll`和`size`参数控制。监控删除进度可使用任务ID。合理运用这些方法能有效优化存储,适应不同业务需求。
|
2月前
|
Linux API 网络架构
Rest API请求管理最佳实践:RestClient-cpp库的应用案例
Rest API请求管理最佳实践:RestClient-cpp库的应用案例