Elasticsearch之索引管理API(Index management)

本文將詳細介紹ES索引管理相關的API。node

ES索引管理API主要包含以下API:數據庫

  • Create Index
    建立索引。
  • Delete Index
    刪除索引。
  • Get index
    獲取索引。
  • indices Exists Index
    判斷索引是否存在
  • Open/Close Index
    打開或關閉索引,使用close index api會使索引處於關閉狀態,此時沒法對該索引進行讀、寫,但索引數據不會被刪除。
  • Shrink Index
    收縮索引。收縮索引API容許您將現有索引收縮爲具備較少主碎片的新索引(下文爲們稱之爲目標索引)。伸縮後的索引主分片的個數必須是原分片的公約數,舉例說明,若是原先索引的個數爲15,那伸縮後的索引主分片數量能夠是三、五、1。
  • Split Index
    拆分索引。將一個索引的主分片個數擴容,詳情下文講解。
  • Rollover Index
    翻轉索引,有點相似於log4j記錄日誌的方式,例如,按日誌文件大小超過多少後,建立一個新的文件同樣。

建立索引

建立索引,一般建立索引API包含3個部分:索引配置、索引映射、索引別名,例如:json

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:爲索引指定別名設置。api

對應的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    }

查找/刪除/打開/關閉索引

查找、刪除、打開與關閉索引的使用方法與建立索引相似,都是經過RestHighLevelClient#indices()對應的方法來實現。app

類圖

接下來從Request類圖入手,展現上述API重點的參數。運維

Elasticsearch之索引管理API(Index management)

  • MasterNodeReadRequest
    masterNodeTimeout:查找、鏈接masterNode的超時時間,默認爲30s。elasticsearch

  • AcknowledgedRequest
    ackTimeout、timeout:請求超時時間。ide

  • DeleteIndexRequest、GetIndexRequest、OpenIndexRequest、CLoseIndexRequest公共屬性:
    一、private String[] indices
    上述API待操做的索引,便可以同時刪除、查找、打開或關閉多個索引。
    二、private IndicesOptions indicesOptions
    索引操做選項。

IndicesOptions(索引操做選項)

Elasticsearch之索引管理API(Index management)

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))
    主要表明以下幾層意義:
    一、若是是指定索引,則索引必須存在。
    二、通配符匹配的範圍爲OPEN狀態的索引。
    三、若是使用通配符來查找索引,未匹配到任何索引不會拋出異常。
  • LENIENT_EXPAND_OPEN
    (EnumSet.of(Option.ALLOW_NO_INDICES, Option.IGNORE_UNAVAILABLE), EnumSet.of(WildcardStates.OPEN))
    主要表明以下幾層意義:
    一、容許索引不存在,指定一個不存在的索引,也不會拋出異常。
    二、通配符做用範圍爲OPEN狀態的索引。
    三、若是使用通配符來查找索引,未匹配到任何索引不會拋出異常。
  • STRICT_EXPAND_OPEN_CLOSED
    (EnumSet.of(Option.ALLOW_NO_INDICES), EnumSet.of(WildcardStates.OPEN, WildcardStates.CLOSED))
    主要表明以下幾層意義:
    一、若是指定索引,該索引必須存在。
    二、通配符做用範圍爲OPEN、CLOSED狀態的索引。
    三、若是使用通配符來查找索引,未匹配到任何索引不會拋出異常。
  • STRICT_EXPAND_OPEN_FORBID_CLOSED
    (EnumSet.of(Option.ALLOW_NO_INDICES, Option.FORBID_CLOSED_INDICES), EnumSet.of(WildcardStates.OPEN))
    主要表明以下幾層意義:
    一、若是指定索引,該索引必須存在。
    二、通配符做用範圍爲OPEN狀態的索引。
    三、若是使用通配符查找索引,未找到索引不會拋出異常。
    四、禁止指定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))。
    主要表明以下幾層意義:
    一、指定的索引或別名必須存在。
    二、不容許使用通配符。
    三、不容許一個別名解析出多個索引的狀況。

上面是對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}

伸縮與拆分索引

Split Index,拆分索引。

Shrink Index

收縮索引。收縮索引API容許您將現有索引收縮爲具備較少主碎片的新索引(下文爲們稱之爲目標索引)。伸縮後的索引主分片的個數必須是原分片的公約數,舉例說明,若是原先索引的個數爲15,那伸縮後的索引主分片數量能夠是三、五、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    }

拆分索引的必要條件以下:

  • 目標索引必須不存在。
  • 索引的主分片個數必須少於目標索引。
  • 目標索引中的主分片數量必須是源索引中的主分片數量的一個因子。
  • 處理拆分過程的節點必須有足夠的空閒磁盤空間來容納現有索引的第二個副本。

拆分過程的監控與收縮索引相同,不重複介紹。

翻轉索引

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天。br/>代碼@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.一、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之索引管理API(Index management)
來一波廣告,做者新書《RocketMQ技術內幕》新書上市:
Elasticsearch之索引管理API(Index management)《RocketMQ技術內幕》已出版上市,目前可在主流購物平臺(京東、天貓等)購買,本書從源碼角度深度分析了RocketMQ NameServer、消息發送、消息存儲、消息消費、消息過濾、主從同步HA、事務消息;在實戰篇重點介紹了RocketMQ運維管理界面與當前支持的39個運維命令;並在附錄部分羅列了RocketMQ幾乎全部的配置參數。本書獲得了RocketMQ創始人、阿里巴巴Messaging開源技術負責人、Linux OpenMessaging 主席的高度承認並做序推薦。目前是國內第一本成體系剖析RocketMQ的書籍。

相關文章
相關標籤/搜索