作者:刘晓国
注意:本主题描述了 Elasticsearch 7.8 中引入的可组合索引模板(composable index template)。 有关索引模板以前如何工作的信息,请参阅旧版模板文档。你也可以参阅我之前的文章 “Elasticsearch: Index template”。
索引模板(Index template)是一种告诉 Elasticsearch 在创建索引时如何配置索引的方法。 对于数据流(data stream),索引模板会在创建流时支持其后备索引。 在创建索引之前先配置模板,然后在手动创建索引或通过对文档建立索引创建索引时,模板设置将用作创建索引的基础。
模板有两种类型:索引模板和组件模板。 组件模板是可重用的构建块,用于配置映射,设置和别名。 你使用组件模板来构造索引模板,但它们不会直接应用于一组索引。 索引模板可以包含组件模板的集合,也可以直接指定设置,映射和别名。
如果新数据流或索引与多个索引模板匹配,则使用优先级最高的索引模板。
重要提示:Elasticsearch 具有以下索引模板的内置索引模板,每个索引的优先级为 100:
logs-*-*
metrics-*-*
synthetics-*-*
Elastic Agent 使用这些模板来创建数据流。 如果使用 Elastic Agent,请为索引模板分配低于100的优先级,以避免覆盖内置模板。 否则,为避免意外应用内置模板,请执行以下一项或多项操作:
要禁用所有内置索引索引和组件模板,请使用集群更新设置 API 将 stack.templates.enabled 设置为 false。
使用非重叠索引模式。
为具有重叠模式的模板分配优先级高于100。例如,如果你不使用 Elastic Agent,并且想为 logs-* 索引模式创建模板,请为模板分配优先级 200。这样可以确保你的模板 应用而不是日志的内置模板 logs-*-*。
当可组合模板与给定索引匹配时,它始终优先于旧模板。 如果没有可组合模板匹配,则旧版模板可能仍匹配并被应用。
如果使用显式设置创建索引并且该索引也与索引模板匹配,则创建索引请求中的设置将优先于索引模板及其组件模板中指定的设置。
创建可组合的 index template
下面,我们来使用一个例子来展示如何使用可组合的 index template。
我们首先来创建二个组件模板:
PUT _component_template/component_template1 { "template": { "mappings": { "properties": { "@timestamp": { "type": "date" } } } } } PUT _component_template/other_component_template { "template": { "mappings": { "properties": { "ip_address": { "type": "ip" } } } } }
在上面,我们定义了 component_template1 以及 other_component_template 两个组合模板。我们运用上面的两个 component template 来组合一个 index tempate。 这两个 component template 分别定义了一个 index template 的其中的一部分字段。
我们使用如下的命令来创建一个新的 index template:
PUT _index_template/template_1 { "index_patterns": ["te*", "bar*"], "template": { "settings": { "number_of_shards": 1 }, "mappings": { "_source": { "enabled": false }, "properties": { "host_name": { "type": "keyword" }, "created_at": { "type": "date", "format": "EEE MMM dd HH:mm:ss Z yyyy" } } }, "aliases": { "mydata": { } } }, "priority": 200, "composed_of": ["component_template1", "other_component_template"], "version": 3, "_meta": { "description": "my custom" } }
在上面,请注意这个部分:
"composed_of": ["component_template1", "other_component_template"],
也就是说这个叫做 template_1 的 index template,它包含了两个可组合的 component templates:component_template 及 other_component_template。
在上面,我们定义了以 te 和 bar 开头的索引所应该具有的 index template。我们在 Kibana 中创建一个叫做 test 的索引:
PUT test
我们可以通过如下的命令来进行检查:
GET test
上面的命令的响应如下:
{ "test" : { "aliases" : { "mydata" : { } }, "mappings" : { "_source" : { "enabled" : false }, "properties" : { "@timestamp" : { "type" : "date" }, "created_at" : { "type" : "date", "format" : "EEE MMM dd HH:mm:ss Z yyyy" }, "host_name" : { "type" : "keyword" }, "ip_address" : { "type" : "ip" } } }, "settings" : { "index" : { "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" } } }, "number_of_shards" : "1", "provided_name" : "test", "creation_date" : "1612751497863", "number_of_replicas" : "1", "uuid" : "ki41iwTGR66yxkLBLCi80Q", "version" : { "created" : "7100099" } } } } }
显然 test 索引它具有我们先前在两个 component template 里具有的 mapping。
模拟多组件模板
由于模板不仅可以由多个组件模板组成,还可以由索引模板本身组成,因此有两个模拟API可以确定最终的索引设置是什么。
要模拟将应用于特定索引名称的设置:
POST /_index_template/_simulate_index/test
我们将看到如下的输出:
{ "template" : { "settings" : { "index" : { "number_of_shards" : "1" } }, "mappings" : { "_source" : { "enabled" : false }, "properties" : { "@timestamp" : { "type" : "date" }, "created_at" : { "type" : "date", "format" : "EEE MMM dd HH:mm:ss Z yyyy" }, "host_name" : { "type" : "keyword" }, "ip_address" : { "type" : "ip" } } }, "aliases" : { "mydata" : { } } }, "overlapping" : [ ] }
要模拟将从现有模板中应用的设置:
POST /_index_template/_simulate/template_1
在上面的练习中,我们已经创建了 template_1 的模板。上面命令的输出为:
{ "template" : { "settings" : { "index" : { "number_of_shards" : "1" } }, "mappings" : { "_source" : { "enabled" : false }, "properties" : { "@timestamp" : { "type" : "date" }, "created_at" : { "type" : "date", "format" : "EEE MMM dd HH:mm:ss Z yyyy" }, "host_name" : { "type" : "keyword" }, "ip_address" : { "type" : "ip" } } }, "aliases" : { "mydata" : { } } }, "overlapping" : [ ] }
你也可以在模拟请求中指定模板定义。 这样,你可以在添加新模板之前验证设置是否将按预期应用。
PUT /_component_template/ct1 { "template": { "settings": { "index.number_of_shards": 2 } } } PUT /_component_template/ct2 { "template": { "settings": { "index.number_of_replicas": 0 }, "mappings": { "properties": { "@timestamp": { "type": "date" } } } } }
在上面我们定义了两个 component template。我们在一下的命令中来模拟一下这个模板:
POST /_index_template/_simulate { "index_patterns": ["my*"], "template": { "settings" : { "index.number_of_shards" : 3 } }, "composed_of": ["ct1", "ct2"] }
上面的命令输出为:
{ "template" : { "settings" : { "index" : { "number_of_shards" : "3", "number_of_replicas" : "0" } }, "mappings" : { "properties" : { "@timestamp" : { "type" : "date" } } }, "aliases" : { } }, "overlapping" : [ ] }
该响应显示将应用于匹配索引的 settings,mappings 和 aliases,以及任何配置将被模拟模板主体或更高优先级模板取代的重叠模板。
使用 Kibana 来创建可组合 index template
在上面,我们使用了命令行来创建可组合 index template。在这节里,我们使用 Kibana 来创建我们的可组合 index template。
我们打开 Kinana 界面:
我们向下滚动,你就可以发现我们在上面已经创建好的 template_1 index template:
从上面我们可以看出来 template_1 有两个 component template 组成的。
接下来,我们来创建一个新的 index template。
创建 component template
在这个 template 里,我们只配置一个如上的设置。
在之后的设置中,我们一直点击 Next 按钮,并不做任何的设置,直到保存。
这样我们就创建了一个叫做 component_temp1 的模板。
我们接下来创建另外一个叫做 component_temp2 的模板:
在上面,我们定义了一个叫做 ip_address 的字段,并定义了它的数据类型 IP。
这样我们就生产了一个叫做 component_temp2 的模板。
我们接下来创建一个叫做 template2 的 index template:
在上面,我们定义了 index pattern: "good-*"。
在上面,我们选中已经创建好的 component template:
这样就创建了叫做 template2 的 index template。
我们可以直接在 Kibana 的 console 中进行如下的测试:
PUT good-morning
我们通过如下的方式来进行检查:
GET good-morning
上面的命令显示的结果为:
{ "good-morning" : { "aliases" : { }, "mappings" : { "properties" : { "ip_address" : { "type" : "ip" } } }, "settings" : { "index" : { "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" } } }, "number_of_shards" : "1", "auto_expand_replicas" : "0-2", "provided_name" : "good-morning", "creation_date" : "1612755833290", "number_of_replicas" : "0", "uuid" : "8AHF5hl_QU6euyqaKgn2hg", "version" : { "created" : "7100099" } } } } }
从上面的显示中,我们可以看出来 ip_address 字段以及 auto_expand_replicas 都是我们之前在 component_temp1 以及 component_temp2 里所定义的。