什么是 Elasticsearch 模板?

Elasticsearch 模板是一个预设的蓝图,当你创建一个新索引时,可以告诉 Elasticsearch:“请使用这个模板来配置我的新索引”。

elastic search 模板
(图片来源网络,侵删)

模板主要定义了以下内容:

  • 索引模式: 模板应用于哪些索引名,一个名为 logs-* 的模板会应用于所有以 logs- 开头的新索引。
  • 设置: 索引的配置参数,
    • number_of_shards: 主分片数量。
    • number_of_replicas: 副本数量。
    • codec: 压缩算法(如 best_compression)。
    • analysis: 自定义分析器、分词器等。
  • 映射: 定义文档中字段的数据类型、分析器、是否可以被搜索等。text 类型用于全文搜索,keyword 类型用于精确匹配和聚合。
  • 模板优先级: 当有多个模板匹配同一个索引时,可以指定模板的优先级,高优先级的模板会覆盖低优先级的设置。

模板的类型

Elasticsearch 主要有两种模板:

A. 索引模板

这是目前推荐使用的模板类型,自 Elasticsearch 7.8 版本引入,并计划在未来版本中完全取代旧版模板。

  • 核心优势: 支持在模板中定义组件,如索引设置、映射、别名等,这使得模板的管理和复用变得更加模块化和清晰。
  • 工作方式: 当你创建一个匹配的索引时,Elasticsearch 会合并所有匹配的组件(按优先级),然后创建索引。

B. 旧版索引模板

这是在 Elasticsearch 7.8 之前使用的模板类型。

elastic search 模板
(图片来源网络,侵删)
  • 特点: 将所有配置(设置和映射)都放在一个大的 JSON 对象中。
  • 现状: 虽然仍然被支持,但官方强烈建议使用新的索引模板,如果你在旧版本上工作,或者维护旧项目,你可能会遇到它。

索引模板 的实际操作

下面我们通过一个完整的例子来学习如何创建和使用一个索引模板。

场景

我们希望为所有应用日志创建索引,这些索引的命名格式为 app-logs-YYYY.MM.DDapp-logs-2025.10.27),我们希望这些索引具有以下标准配置:

  1. 设置:
    • 3个主分片,1个副本。
    • 使用 best_compression 编码以节省空间。
  2. 映射:
    • @timestamp: 日期类型,用于存储日志时间。
    • message: text 类型,用于全文搜索日志内容。
    • level: keyword 类型,用于精确匹配日志级别(如 INFO, ERROR)。
    • service_name: keyword 类型,用于标识服务名。

步骤 1: 创建索引模板

我们将使用 PUT /_index_template API 来创建模板,模板的名称必须是唯一的。

PUT /_index_template/app_logs_template
{
  "index_patterns": ["app-logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "codec": "best_compression"
    },
    "mappings": {
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "message": {
          "type": "text"
        },
        "level": {
          "type": "keyword"
        },
        "service_name": {
          "type": "keyword"
        }
      }
    }
  },
  "priority": 500 
}

参数解释:

elastic search 模板
(图片来源网络,侵删)
  • app_logs_template: 我们给这个模板取的名字。
  • index_patterns: 一个数组,定义哪些索引会匹配这个模板,这里的通配符 会匹配任意字符。
  • template: 这是核心部分,包含了应用到新索引上的设置和映射。
  • priority: 模板的优先级,如果多个模板匹配同一个索引,数字越大的优先级越高。

步骤 2: 验证模板是否创建成功

你可以通过以下命令查看所有模板的详情:

GET /_index_template/app_logs_template

或者查看所有模板:

GET /_index_template

步骤 3: 使用模板创建索引

我们创建一个符合 app-logs-* 模式的新索引。神奇的是,我们完全不需要在创建索引的请求中提供任何设置或映射!

PUT /app-logs-2025.10.27

Elasticsearch 会自动查找所有匹配 app-logs-* 的模板(这里只有我们刚创建的 app_logs_template),并应用其中的设置和映射。

步骤 4: 验证新索引的配置

让我们检查一下新创建的索引 app-logs-2025.10.27,看看它是否自动应用了模板的配置。

GET /app-logs-2025.10.27

会包含我们模板中定义的所有 settingsmappings

{
  "app-logs-2025.10.27": {
    "aliases": {},
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "level": { "type": "keyword" },
        "message": { "type": "text" },
        "service_name": { "type": "keyword" }
      }
    },
    "settings": {
      "index": {
        "codec": "best_compression",
        "number_of_shards": "3",
        "number_of_replicas": "1",
        "provided_name": "app-logs-2025.10.27",
        "creation_date": "1698412345678",
        "uuid": "...",
        "version": {
          "created": "...)"
        }
      }
    }
  }
}

可以看到,索引完全按照我们的模板进行了配置。


高级用法:组件模板

组件模板是新版索引模板的精髓,它允许你将配置拆分成可复用的模块。

场景

假设我们有一些通用的设置和映射,想在多个不同的模板中复用。

  1. 通用设置模板: 包含分片数、副本数等。
  2. 日志映射模板: 包含 @timestamp, message, level 等字段。
  3. 特定服务模板: 包含特定服务的字段,user_id

步骤 1: 创建组件模板

# 创建通用设置组件模板
PUT /_component_template/common_settings
{
  "template": {
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    }
  }
}
# 创建通用日志映射组件模板
PUT /_component_template/common_log_mappings
{
  "template": {
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "message": { "type": "text" },
        "level": { "type": "keyword" }
      }
    }
  }
}

步骤 2: 创建一个使用组件模板的索引模板

我们可以创建一个更高级的索引模板,它组合了上面的组件模板,并可以添加自己的配置。

PUT /_index_template/web_server_logs_template
{
  "index_patterns": ["web-server-logs-*"],
  "template": {
    "settings": {
      "codec": "best_compression" 
    },
    "mappings": {
      "properties": {
        "client_ip": { "type": "ip" },
        "response_time_ms": { "type": "integer" }
      }
    }
  },
  "composed_of": ["common_settings", "common_log_mappings"]
}

关键参数 composed_of:

  • 这个数组列出了这个索引模板依赖的所有组件模板的名称。
  • 当创建索引时,Elasticsearch 会按照以下顺序合并配置:
    1. 首先合并 composed_of 中列出的所有组件模板。
    2. 然后合并索引模板 template 部分中的配置。后合并的会覆盖先合并的

在这个例子中,最终的索引会拥有:

  • 来自 common_settingsnumber_of_shardsnumber_of_replicas
  • 来自 common_log_mappings@timestamp, message, level 字段。
  • 来自 web_server_logs_template 自己的 codec 设置、client_ipresponse_time_ms 字段。

这种模块化的方式极大地提高了配置的可维护性和复用性。


生命周期管理 与模板

ILM 是 Elasticsearch 自动管理索引生命周期的功能,例如根据索引的大小或年龄自动执行滚动快照删除等操作。

ILM 与模板是天作之合:

  1. 你可以在索引模板中直接定义一个 ILM 策略。
  2. 当任何匹配该模板的索引被创建时,它会自动被绑定到这个 ILM 策略上。

示例:在模板中集成 ILM

PUT /_index_template/app_logs_template_with_ilm
{
  "index_patterns": ["app-logs-with-ilm-*"],
  "template": {
    "settings": {
      "number_of_shards": 1,
      "lifecycle": {
        "name": "my_ilm_policy" 
      }
    }
  }
}

这样,所有 app-logs-with-ilm-* 索引从诞生之日起,就会遵循 my_ilm_policy 定义的生命周期,无需手动为每个索引配置。


总结与最佳实践

特性 描述 优点
标准化 确保所有相似索引具有一致的配置和结构。 简化管理,避免人为错误。
效率 无需为每个新索引重复定义设置和映射。 加速索引创建过程。
可维护性 修改模板即可影响所有未来匹配的索引。 集中化配置,便于更新和审计。
生命周期管理 与 ILM 无缝集成,实现自动化索引管理。 实现数据的自动化、低成本运维。

最佳实践:

  1. 使用新版索引模板: 优先使用 _index_template API,并利用组件模板 (_component_template) 进行模块化设计。
  2. 命名清晰: 为模板和组件模板使用有意义的名称,如 team-x-data-templatecommon-analysis-settings
  3. 优先级管理: 当有多个模板时,合理设置 priority,确保高优先级的模板能覆盖低优先级的。
  4. 结合 ILM: 在生产环境中,强烈建议将索引模板与 ILM 策略结合使用,以实现数据的全生命周期自动化管理。
  5. 版本控制: 将你的模板定义(JSON 文件)存储在版本控制系统(如 Git)中,以便追踪变更和实现 DevOps 流程。