elasticsearch-Index template 索引模板

简介

Elasticsearch 本着让用户方便快捷的使用搜索功能的原则,对数据定义(索引定义)做了高度抽象,尽可能得避免了重复性定义工作,使之更加灵活。

Elasticsearch 在这方面做的工作主要体现是索引模板(Index template)和动态映射(Dynamic Mapping)两个功能。索引模板的主要功能,是允许用户在创建索引(index)时,引用已保存的模板来减少配置项。操作的一般过程是先创建索引模板,然后再手动创建索引或保存文档(Document)。而自动创建索引时,索引模板会作为配置的基础作用。对于 X-Pack 的数据流(Data Stream)功能,索引模板用于自动创建后备索引(Backing Indices)。该功能的意义是提供了一种配置复用机制,减少了大量重复作劳动。

目前 Elasticsearch 的索引模板功能以 7.8 版本为界,分为新老两套实现,新老两个版本的主要区别是模板之间复用如何实现。

老版本:

使用优先级(order)关键字实现,当创建索引匹配到多个索引模板时,高优先级会继承并铺盖低优先级的模板配置,最终多个模板共同起作用。

新版本:

删除了 order 关键字,引入了组件模板 Component template 的概念,是第一段可以复用的配置块。在创建普通模板时可以声明引用多个组件模板,当创建索引匹配到多个新版索引模板时,取用最高权重的那个。

下面将以生命周期(创建、查看、使用、删除)为切入点,分别介绍如何使用 Elasticsearch 新老两个版本的索引模板。

新版索引模板

在使用新版本的索引模板功能前,我们应当确认 Elasticsearch 是否开启了安全设置,如果是,那么我们操作的角色对于集群需要有 manage_index_templates 或 manage 权限才能使用索引模板功能,这个限制对新老版本都适用。

对于新版,Elasticsearch 为了方便用户调试,提供了模拟 API 来帮助用户测试创建索引最终的配置。该模拟 API 主要有 2 个

第一个模拟在现有索引模板下创建 1 个索引,最终使用的模板配置是什么样的。

第二个模拟在指定模板的配置下,最终模板配置是什么样的。

第一种模拟 API 使用范例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# 创建1个组件模板ct1
PUT /_component_template/ct1 # 1
{
"template": {
"settings": {
"index.number_of_shards": 2
}
}
}
# 创建1个组件模板ct2
PUT /_component_template/ct2 # 2
{
"template": {
"settings": {
"index.number_of_replicas": 0
},
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
}
}
}
}
}
# 创建1个索引模板 final-template
PUT /_index_template/final-template # 3
{
"index_patterns": ["my-index-*"],
"composed_of": ["ct1", "ct2"],
"priority": 5,
"template":{
"settings": {
"index.number_of_replicas": 1
},
"mappings": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
}
# 验证创建名为 my-index-00000 的索引使用的配置是如何
POST /_index_template/_simulate_index/my-index-00000 # 4
#返回
{
"template" : { # 引用模板中的配置有settings、mappings、aliase
"settings" : {
"index" : {
"number_of_shards" : "2",
"number_of_replicas" : "1"
}
},
"mappings" : {
"properties" : {
"@timestamp" : {
"type" : "date"
},
"name" : {
"type" : "keyword"
}
}
},
"aliases" : { }
},
"overlapping" : [ # 5
{
"name" : "test-template",
"index_patterns" : ["my-*"]
}
]
}
  1. 在 #1 处创建了 1 个名为cr1的组件模板,该模板设置了索引分片数为2
  2. 在 #2 处创建了 1 个名为cr2的组件模板,该模板设置了索引由1个@timestamp属性,并且副本数是0
  3. 在 #3 处创建了1个名为final-template的索引模板,它适用于所有以my-index-开头的索引
  4. 在 #4 处向/_index_template/_simulate_index/my-index-00000发送 POST 请求,测试创建名为my-index-00000的索引,下面的 JSON 是使用索引模板的配置,可以看出 template 字段是组件 cr1、cr2 以及索引模板 final-template 全部配置的聚合。
  5. #5处的overlapping字段表示忽略了名为test-template模板的配置。

第二种模拟 API 使用范例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 默认组件模板 ct1、crt 已创建,内容如前
# 验证按照该模板创建的索引时会使用的配置
POST /_index_template/_simulate/<index-template> #1
{ # 2
"index_patterns":["test-*"],
"composed_of": ["ct1","ct2"],
"priority": 5,
"template": {
"settings": {
"index.number_of_replicas": 1
},
"mappings": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
}
# 返回
{ # 3
"template" : {
"settings" : {
"index" : {
"number_of_shards" : "2",
"number_of_replicas" : "1"
}
},
"mappings" : {
"properties" : {
"@timestamp" : {
"type" : "date"
},
"name" : {
"type" : "keyword"
}
}
},
"aliases" : { }
},
"overlapping" : [
{
"name" : "test-template",
"index_patterns" : ["my-*"]
}
]
}
  1. #1 向/_index_template/_simulate/<index-template>发送 POST 请求,其中<index-template>为自定义索引模板的名词,该模板并不会实际创建
  2. #2 处是请求的 body,与创建一个新版索引模板个格式完全一样,后续详细介绍,目前只需要知道它引用了 cr1 和 cr2 两个组件模
  3. #3 处为请求返回的 body,可以看出内容是组件模板 cr1、cr2 以及请求 body3 个配置的组合。

创建

新版本索引自动配置功能,主要依托组件模板(component template)和索引模板(index template)2 个概念来完成。下面依次来介绍他们是如何实现的。

组件模板的创建

组件模板是用来构建索引模板的特殊模板,它的内容一般是多个索引模板的公有配置,索引模板在创建时,可以声明引用多个组件模板。

在组件模板中可配置的索引内容有:别名aliases、配置settings、映射mappings3 个,具体配置方式与创建索引时一致。组件模板只有在被索引模板引用时,才会发挥作用。当我们需要创建或更新一个组件模板时,向/_component_template路径发送 PUT 请求即可。

具体示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 创建组件模板
PUT /_component_template/template_1?create=true&master_timeout=30s #1
{
"template": { # 2
"settings": {
"number_of_shards": 1
},
"mappings": {
"_source": {
"enabled": false
},
"properties": {
"name": {
"type": "keyword"
}
}
},
"aliases": {
"test-index": {}
}
},
"version": 1, #3
"_meta": { #4
"description1": "for test",
"description2": "create by phoenix"
}
}
  1. #1 处向/_component_template/template_1发送 PUT 请求创建一个名为template_1的组件模板,模板名可以任意替换,需要注意的是,Elasticsearch 中预置有6个组件模板:logs-mappingslogs-settingsmetrics-mappingsmetrics-settingssynthetics-mappingsynthetics-settings,建议不要覆盖。同时 url 中还包含2个可选的查询参数createmaster_timeout
    1. create,表示此次请求是否是创建请求,如果为 true 则系统中如果已有同名的会报错,默认为 false,表示请求可以是创建也可能是更新请求
    2. master_timeout,表示可以容忍的连接 Elasticsearch 主节点的时间,默认是30s,如果超时则请求报错
  2. #2 处template的内容是对索引的设置,主要有别名,映射和配置,在本例中配置了索引分片数是 1,_source不用保存,索引有名为name的属性,类型是 keyword,同时索引别名有test-index
  3. #3 处是用户指定的组件模板的版本号,为了方便外部管理,此为可选项,默认不会为组件模板增加版本号
  4. #4 处是用户为组件模板设置的 meta 信息,该对象字段可随意配置,但不要设置的过大。该字段也是可选的

索引模板的创建

创建或更新一个索引模板的方式都是向/_index_template发送 1 个 PUT 请求。索引模板可以配置的内容主要有 3 类,分别是别名aliases、配置settings、映射mappings。这 3 部分的配置方式,与创建索引时的设置完全一样这里不再赘述。

创建索引模板的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
PUT /_index_template/test_template?create=false&master_timeout=30s #1
{
"index_patterns" : ["te*"], #2
"priority" : 1, #3
"composed_of": ["template_1"], #4
"template": { #5
"settings" : {
"number_of_shards" : 2
}
},
"version": 2, #6
"_meta": { #7
"user": "phoenix",
"time": "2021/05/06"
}
}
# 测试模板
POST /_index_template/_simulate_index/test #8
{
"template" : {
"settings" : {
"index" : {
"number_of_shards" : "2" # 索引模板覆盖了组件模板的配置
}
},
"mappings" : {
"_source" : { # 使用组件模板的配置
"enabled" : false
},
"properties" : {
"name" : { # 使用组件模板的配置
"type" : "keyword"
}
}
},
"aliases" : {
"test-index" : { } # 使用组件模板的配置
}
}
}
  1. #1 处向/_index_template/test_template发送 PUT 请求创建索引模板,模板名称为test_template,名称可任意填写,与组件模板相同,有2个可选的查询参数:
    1. create,表示此次请求是否是创建请求,如果为 true 则系统中如果已有同名模板则会报错,默认为 false,表示请求可以是创建也可能是更新请求
    2. master_timeout,表示可以容忍的连接 Elasticsearch 主节点的时间,默认是30s,如果超时则请求报错
  2. #2 处index_patterns字段用于设置匹配索引的规则,目前仅支持使用索引名称匹配,支持*号作为通配符,该字段是必填字段。需要注意 Elasticsearch 自带了3种匹配规则的索引模板:logs-*-*metrics-*-*synthetics-*-*,建议不要做相同配置。
  3. #3 处priority字段配置的是模板权重,当 1 个索引名符合多个模板的匹配规则时, 会使用该值最大的做为最终使用的模板,此值默认为 0,Elasticsearch 自带的模板此值是100。
  4. #4 处composed_of字段用于配置索引模板引用的组件模板,此处引用的组件模板配置自动会增加到该模板中。此例我们引用了之前创建的template_1组件。
  5. #5 处template的内容是对索引的设置。
  6. #6 处是用户指定的索引模板的版本号,为了方便外部管理,此为可选项,默认不会为组件模板增加版本号
  7. #7 处是用户为索引模板设置的 Meta 信息,该对象字段可随意配置,但不要设置的过大。该字段也是可选的
  8. #8 处用模拟 API 创建名为test的索引,我们发现返回的模板包含了模板test_template和组件template_1的所有配置

查看

创建完索引模板或组件模板后,我们可以使用 GET 请求再次查看其内容,请求是可以指定名称表示精准找,也可以使用通配符*进行范围查找,如果不指定名称则会返回全部。

1
2
3
4
5
6
GET /_component_template/template_1?local=false&master_timeout=30s #1
GET /_component_template/template_* #2
GET /_component_template #3
GET /_index_template/test_template #4
GET /_index_template/test_* #5
GET /_index_template #6
  1. #1 是查看名为template_1的组件模板
  2. #2 是查看名字以template_开头的所有组件模板
  3. #3 是查看所有组件模板,通过该请求我们可以发现 Elasticsearch 默认创建了很多组件模板,使用时应尽量避免冲突
  4. #4 是查看名字为test_template的索引模板
  5. #5 是查看名字以test_开头的所有索引模板
  6. #6 是查看所有索引模板,通过该请求我们可以发现 Elasticsearch 默认创建了很多索引模板,使用时应尽量避免冲突

如 #1 所示,上述所有请求都可以增加 2 个可选的查询参数:

  1. local,如果为true模板的配置仅从本地节点中获取,默认为false表示此次查询结果是master节点返回的
  2. master_timeout,表示可以容忍的连接elasticsearch主节点的时间,默认是30s,如果超时则请求报错

使用

关于组件模板如何使用我们在创建索引模板时已经提及,增加composed_of字段声明索引模板引用的组件模板,这样组件模板的配置,就自动增加到了索引模板中。

索引模板的使用主要发生在创建索引的时候,如果创建的索引名与索引模板的index_patterns配置相匹配,那么该索引将会在此模板的基础上创建。

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 创建名为test-my-template的索引
PUT /test-my-template
{
"settings": {
"index": {
"number_of_replicas": 3
}
},
"mappings": {
"properties": {
"desc":{
"type": "keyword"
}
}
}
}
# 查看索引信息
GET /test-my-template
# 返回
{
"test-my-template" : {
"aliases" : { # 组件模板 template_1 的配置
"test-index" : { }
},
"mappings" : {
"_source" : { # 组件模板 template_1 的配置
"enabled" : false
},
"properties" : {
"desc" : { # 创建索引时的配置
"type" : "keyword"
},
"name" : { # 组件模板 template_1 的配置
"type" : "keyword"
}
}
},
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "3", # 覆盖了 索引模板 number_of_shards=2 的配置
"provided_name" : "test-my-template",
"creation_date" : "1620550940095",
"number_of_replicas" : "1",
"uuid" : "7UZKxK56SZ-bAwBeDL-Jvg",
"version" : {
"created" : "7100099"
}
}
}
}
}

本例我们创建了名为test-my-template的索引,其索引名以te开头,匹配索引模板test_template的筛选规则。我们在创建时仅指定了分片数和一个desc属性,而在我们使用 GET 请求查看索引信息时可以看出,索引模板中的别名配置、_source配置和name属性的配置被使用了。但是关于分片的设置,由于创建索引时明确指出了,所以模板中的配置number_of_shards=2被覆盖为了 3。

由于在向 一个不存在的索引中插入数据时,Elasticsearch 会自动创建索引,如果新的索引名匹配某个索引模板的话,也会以模板配置来创建索引。在使用该功能前,请确保 Elasticsearch 集群的action.auto_create_index配置是允许你自动创建目标索引的。

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 向不存在的 test 索引中保存1条数据
PUT /test/_doc/1
{
"name":"tom",
"age": 18
}

# 查看 test 索引信息
GET /test
{
"test" : {
"aliases" : { # 组件模板 template_1 的配置
"test-index" : { }
},
"mappings" : {
"_source" : { # 组件模板 template_1 的配置
"enabled" : false
},
"properties" : {
"age" : { # ES 自动推断创建的属性
"type" : "long"
},
"name" : { # 组件模板 template_1 的配置
"type" : "keyword"
}
}
},
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "2", # 使用索引模板的配置
"provided_name" : "test",
"creation_date" : "1620551933756",
"number_of_replicas" : "1",
"uuid" : "Oop40MPySjKbSKvs0OQwTA",
"version" : {
"created" : "7100099"
}
}
}
}
}

如上例所示,我们向不存在的test索引中保存 1 条数据,该索引名与索引模板test_template的规则相匹配。因此索引的配置与模板配置完全契合,除了模板中没有配置的age字段,是通过 Elasticsearch 属性自动创建功能生成的。

删除

当索引模板或组件模板完成了它们的使命,我们应该及时将其删除,避免因遗忘导致创建出的索引出现了预料之外的配置。删除操作非常简单,发送 DELETE 请求即可,删除同样可以使用通配符*一次删除多个,示例如下:

1
2
3
4
DELETE  /_component_template/template_1?master_timeout=30s&timeout=30s  #1
DELETE /_component_template/template_* #2
DELETE /_index_template/test_template #3
DELETE /_index_template/test_* #4
  1. #1 表示删除名为template_1的组件模板
  2. #2 表示删除名字以template_开头的组件模板
  3. #3 表示删除名为test_template的索引模板
  4. #3 表示删除名字以test_开头的索引模板

如 #1 所示,上述所有请求都可以增加 2 个可选的查询参数:

  1. timeout,表示可以容忍的等待响应时间,默认是 30s,如果超时则请求报错
  2. master_timeout,表示可以容忍的连接 Elasticsearch 主节点的时间,默认是 30s,如果超时则请求报错

老版索引模板

Elasticsearch 7.8 版本之前的索引模板功能,与新版本基本相同,唯一的区别就是在模板的复用方式上。老版本允许在创建索引时,匹配到多个模板,多个模板间根据order配置的优先级从低到高依次覆盖。这种方式会造成用户在创建索引时,不能明确知道自己到底用了多少模板,索引配置在继承覆盖的过程中非常容易出错。

下面依然从模板的生命周期出发,介绍如何使用。

创建

与新版本一样,创建或更新一个老版索引模板,只需要向/_template发送PUT请求即可,通过索引模板可配置的字段依然是:别名aliases、配置settings、映射mappings3个。

具体示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 创建或更新老模板
PUT /_template/old_template?order=1&create=false&master_timeout=30s # 1
{
"index_patterns": ["te*", "bar*"], #2
"settings": { #3
"number_of_shards": 1
},
"aliases": { #4
"old-template-index": {}
},
"mappings": { #5
"_source": {
"enabled": false
},
"properties": {
"host_name": {
"type": "keyword"
}
}
},
"version": 0 #6
}
  1. #1 处向/_template/old_template发送PUT请求创建或索引模板,模板名称为old_template,名称可任意填写,该请求有 4 个可选的查询参数:
    1. create,表示此次请求是否是创建请求,如果为 true 则系统中如果已有同名模板会报错,默认为 false,表示请求可以是创建也可能是更新请求
    2. master_timeout,表示可以容忍的连接 Elasticsearch 主节点的时间,默认是30s,如果超时则请求报错
    3. order,该变量接受一个整数,表示模板的优先级,数字越大优先级越高,相关配置越可能被实际使用,强烈建议每个模板都根据实际情况配置该值,不要使用默认值。
  2. #2 处index_patterns字段用于配置匹配索引的规则,目前仅支持使用索引名称匹配,支持*号作为通配符,该字段是必填字段,可配置多个值表示”或“的关系。
  3. #3 处settings字段用于配置索引属性。

    具体规则详见文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.10/index-modules.html#index-modules-settings

  4. #4 处aliases字段用于配置索引的别名。

    具体规则详见文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.10/indices-aliases.html

  5. #5 处mappings字段用于配置索引的映射。

    具体规则详见文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.10/mapping.html

  6. #6 处version字段是用户指定的索引模板的版本号,为了方便外部管理,此为可选项,Elasticsearch 默认不会为组件模板增加版本号。

查看

我们可以使用 GET 请求,查看其模板内容,同样可以使用名称精确查找,也可以使用通配符部分搜索以及搜索全部。老版本还支持使用HEAD请求快速验证 1 个模板是否存在

1
2
3
4
GET /_template/old_template?local=false&master_timeout=30s&flat_settings=false #1
GET /_template/old_* #2
GET /_template #3
HEAD /_template/old_template #4
  1. #1 是查看名为old_template的索引模板
  2. #2 是查看名字以old_开头的所有索引模板
  3. #3 是查看所有索引模板,通过该请求我们可以发现 Elasticsearch 默认创建了很多组件模板,使用时应尽量避免冲突
  4. #4 是验证名为old_template的索引模板是否存在,与上面 3 个请求返回模板内容不同,本请求不返回模板内容,以状态码为 200 表示存在,404 表示不存在

如#1所示,上述所有请求都可以增加 3 个可选的查询参数:

  1. local,如果为true组件模板的配置仅从本地节点中获取,默认为false表示此次查询结果是master节点返回的
  2. master_timeout,表示可以容忍的连接 Elasticsearch 主节点的时间,默认是30s,如果超时则请求报错
  3. flat_settings,表示返回的配置中关于settings字段如何展示,如果为 false 则使用标准 JSON 格式展示,默认为 true 表示多级属性会压缩成 1 级属性名,以点分格式展示,比如关于索引分片的设置,如果该变量为 true 则返回为index.number_of_shards:1

使用

索引模板的使用,主要发生在创建索引的时候,如果创建的索引名与索引模板相匹配,那么该索引将会在此模板的基础上创建。需要注意的是,如果同时匹配到新老两个版本的模板,那么默认使用新版本。如果仅匹配到多个老版模板则根据order字段依次覆盖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 创建索引
PUT /bar-test-old
{
"settings": {
"number_of_replicas": 2
},
"mappings": {
"_source": {
"enabled": true
},
"properties": {
"ip":{
"type": "ip"
}
}
}
}
# 查看索引
GET /bar-test-old
# 返回
{
"bar-test-old" : {
"aliases" : {
"old-template-index" : { } # old_template模板中的配置
},
"mappings" : {
"_source": {
"enabled": true # 创建时的配置覆盖模板的配置
},
"properties" : {
"host_name" : { # old_template模板中的配置
"type" : "keyword"
},
"ip" : {
"type" : "ip"
}
}
},
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "1", # old_template模板中的配置
"provided_name" : "bar-test-old",
"creation_date" : "1620615937000",
"number_of_replicas" : "2",
"uuid" : "jG3xiiB_S-iFrlwZ7df56g",
"version" : {
"created" : "7100099"
}
}
}
}
}

本例我们创建了名为bar-test-old的索引,其索引名以bar开头,匹配索引模板old_template的筛选规则,我们在创建时仅指定了副本数和 1 个ip属性,而使用 GET 请求查看索引信息时可以看出,索引模板中的别名配置、host_name属性和分片数的配置被使用了。但是关于_source的设置,由于创建索引时明确指出了,所以模板中的false配置被覆盖为了true

当匹配到多个老版索引模板时,最终配置为多个模板的组合,当不同模板配置了相同字段时,那么以order高的模板配置为准。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# 创建新版索引模板   
PUT /_index_template/new_template #1
{
"index_patterns": ["template*"],
"priority" : 100,
"template": {
"mappings": {
"dynamic": "true"
},
"aliases": {
"new-template": {}
}
}
}
# 创建老版索引模板,不配置 order
PUT /_template/old_template_1 #2
{
"index_patterns": ["temp*"],
"mappings": {
"dynamic": "false"
},
"aliases": {
"old_template_1": {}
}
}
# 创建老版本索引模板,配置高 order
PUT /_template/old_template_2?order=10 #3
{
"index_patterns": ["temp-*"],
"mappings": {
"dynamic": "strict"
},
"aliases": {
"old_template_2": {}
}
}
# 创建索引,名称会匹配 new_template 模板和 old_template_1 模板
PUT /template-test #4
{
"settings": {
"number_of_shards": 2
},
"mappings": {
"properties": {
"ip":{
"type": "ip"
}
}
}
}
# 查看索引配置
GET /template-test #5
# 返回
{
"template-test" : {
"aliases" : {
"new-template" : { } # 仅有新版本模板的别名设置
},
"mappings" : {
"dynamic" : "true",
"properties" : {
"ip" : {
"type" : "ip"
}
}
},
"settings" : {
"index" : {
"routing" : {
"allocation" : {
"include" : {
"_tier_preference" : "data_content"
}
}
},
"number_of_shards" : "2",
"provided_name" : "template-test",
"creation_date" : "1620617781794",
"number_of_replicas" : "1",
"uuid" : "0PKYANozRya9zG3LdMG1UA",
"version" : {
"created" : "7100099"
}
}
}
}
}
# 创建索引,名称会匹配 old_template_1 模板和 old_template_1 模板
PUT /temp-test #6
{
"settings": {
"number_of_shards": 2
},
"mappings": {
"properties": {
"ip":{
"type": "ip"
}
}
}
}
# 查看索引配置
GET /temp-test
# 返回
{
"temp-test" : {
"aliases" : {
"old_template_1" : { }, # old_template_1 的配置
"old_template_2" : { } # old_template_2 的配置
},
"mappings" : {
"dynamic" : "strict", # old_template_2 的配置
"properties" : {
"ip" : {
"type" : "ip"
}
}
},
"settings" : {
"refresh_interval" : "10s",
"number_of_shards" : "2",
"provided_name" : "temp-test",
"creation_date" : "1620617979932",
"number_of_replicas" : "1",
"uuid" : "RwvrdGziT7iVmVutXYPwqA",
"version" : {
"created" : "7100099"
}
}
}
}
}
  1. #1 处我们创建了 1 个新版本的索引模板匹配名字,以template开头的索引,设置可以动态增加属性并设置别名new-template
  2. #2 处我们创建了 1 个老版本的索引模板匹配名字,以temp开头的索引,设置不动态增加属性并设置别名old_template_1
  3. #3 处我们创建了 1 个老版本的索引模板匹配名字,以temp-开头的索引,设置有新增属性时报错并设置别名old_template_2,同时配置order为10
  4. #4 处我们创建了 1 个名为template-test的索引
  5. #5 处查看索引template-test的配置,该名称会匹配新版new_template模板,和老版old_template_1模板,根据索引的别名信息,只有新版模板配置的别名可以看出,该索引仅仅应用了new_template模板
  6. #6 处创建了 1 个名为temp-test的索引
  7. #7 处查看索引temp-test的配置,该名称会匹配老版old_template_1old_template_2模板,根据索引的别名信息有old_template_1old_template_1可以看出,2 个模板的配置都应用了。通过dynamic字段为strict我们可以判断该字段使用了order较高的模板old_template_2的配置

删除

老版本的索引模板完成使命后,应该及时将其删除,避免创建索引时匹配到不必要的模板,导致最终创建的索引与预期不符。删除操作非常简单,发送 delete 请求即可,删除同样可以使用通配符*一次删除多个,示例如下:

1
2
DELETE  /_template/old_template_1?master_timeout=30s&timeout=30s  #1
DELETE /_template/old_template* #2
  1. #1 表示删除名为old_template_1的索引模板
  2. #2 表示删除名字以old_template开头的索引模板

如 #1 所示,上述 2 个请求都可以增加 2 个可选的查询参数

  1. timeout,表示可以容忍的等待响应时间,默认是 30s,如果超时则请求报错
  2. master_timeout,表示可以容忍的连接elasticsearch主节点的时间,默认是 30s,如果超时则请求报错

注意事项及技巧

目前新老版本的索引模板在7.10版本都可以使用,并且都是通过名称匹配的方式,来决定最后使用的配置,那么在使用的过程中难免会遇到,匹配到多个模板且配置有冲突的情况。下面总结几点规则来介绍,创建索引的最终配置是如何决定的。

  1. 如果同时匹配到新老 2 个版本的索引模板,那么使用新版模板。
  2. 如果仅匹配到多个新版模板,那么使用priority值最高的索引模板。
  3. 如果新版模板中配置了多个组件模板,且组件中有配置冲突,那么使用composed_of数组中靠后的组件模板的配置。
  4. 如果组件模板和索引模板有字段冲突,那么使用索引模板中的配置。
  5. 如果仅匹配到多个老版模板,那么最终配置由多个模板共同构成,如果有配置冲突,使用order值高的模板的配置。
  6. 如果创建索引语句中的配置与索引模板(不管新老版本)冲突,那么使用创建语句中的配置。

索引模板一般和动态映射结合使用,这样可以大大减少创建索引的语句,缩减索引创建频次。配置方式是在mappings字段中配置dynamic_templates的相关内容。

这个功能一般用于创建时序类数据的索引,比如日志数据,每天都会有新数据进入索引,数据量会持续增加,只用一个索引肯定不合适,需要按日或按月创建。

这种情况约定录入数据的索引名称与日期相关,再创建索引模板,这样数据持续录入时,索引也会按需增加,且不用人工干预,后期对不同索引还能做冷热处理。

鸣谢

本文收录至《Elastic Stack 实战手册》,欢迎和我一起解锁开发者共创书籍,系统学习 Elasticsearch。感谢阿里组织ES百人大战,感谢各位老师及小伙伴的帮助。https://developer.aliyun.com/topic/elasticstack/playbook