Elasticsearch 索引模板丢失原始字符串映射

Elasticsearch Index template lost raw string mapping

我是 运行 单个节点上的小型 ELK 5.4.0 堆栈服务器。当我开始时,我只是采用了所有默认值,这意味着每个索引有 5 个分片。我不想要所有这些分片的开销,所以我创建了一个索引模板,如下所示:

PUT /_template/logstash
{
  "template": "logstash*",
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  }
}

这工作正常,但我刚刚意识到我所有的原始字段现在在 ES 中都丢失了。例如,"uri" 是我的索引字段之一,我曾经将 "uri.raw" 作为它的未分析版本。但是自从我更新了模板后,它们就不见了。查看当前模板显示

GET /_template/logstash
Returns:
{
    "logstash": {
        "order": 0,
        "template": "logstash*",
        "settings": {
            "index": {
                "number_of_shards": "1",
                "number_of_replicas": "0"
            }
        },
        "mappings": {},
        "aliases": {}
    }
}

似乎映射丢失了。我可以从较早的索引中提取映射

GET /logstash-2017.03.01

并与最近的比较

GET /logstash-2017.08.01

这里我看到三月份的时候有一个映射结构像

mappings: {
    "logs": {
        "_all": {...},
        "dynamic_templates": {...},
        "properties": {...}
    },
    "_default_": {
        "_all": {...},
        "dynamic_templates": {...},
        "properties": {...}
    }
}

现在我只有

mappings: {
    "logs": {
        "properties": {...}
    }
}

dynamic_templates 散列包含有关创建 "raw" 字段的信息。

我的猜测是我需要添加以将我的索引模板更新为

PUT /_template/logstash
{
  "template": "logstash*",
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings": {
    "logs": {
        "_all": {...},
        "dynamic_templates": {...},
    },
    "_default_": {
        "_all": {...},
        "dynamic_templates": {...},
        "properties": {...}
    }
}

IOW,除 logs.properties 之外的所有内容(其中包含 logstash 发送的当前字段列表)。

但我不是 ES 专家,现在我有点担心。我原来的索引模板没有按照我想的那样运行。我的上述计划行得通吗?还是我会让事情变得更糟?创建索引模板时必须始终包含 所有内容 吗?在我有模板文件之前,旧索引的映射从何而来?

当 Logstash 首次启动时,elasticsearch 输出插件会使用 _default_ 模板和 dynamic_templates 安装 its own index template,正如您正确理解的那样。

每次 Logstash 创建新的 logstash-* 索引(即每天)时,都会利用模板并使用模板中存在的适当映射创建索引。

您现在需要做的只是获取您已覆盖的官方 logstash 模板并像这样重新安装它(但使用修改的分片设置):

PUT /_template/logstash
{
  "template" : "logstash-*",
  "version" : 50001,
  "settings" : {
    "index.refresh_interval" : "5s"
    "index.number_of_shards": 1,
    "index.number_of_replicas": 0
  },
  "mappings" : {
    "_default_" : {
      "_all" : {"enabled" : true, "norms" : false},
      "dynamic_templates" : [ {
        "message_field" : {
          "path_match" : "message",
          "match_mapping_type" : "string",
          "mapping" : {
            "type" : "text",
            "norms" : false
          }
        }
      }, {
        "string_fields" : {
          "match" : "*",
          "match_mapping_type" : "string",
          "mapping" : {
            "type" : "text", "norms" : false,
            "fields" : {
              "keyword" : { "type": "keyword", "ignore_above": 256 }
            }
          }
        }
      } ],
      "properties" : {
        "@timestamp": { "type": "date", "include_in_all": false },
        "@version": { "type": "keyword", "include_in_all": false },
        "geoip"  : {
          "dynamic": true,
          "properties" : {
            "ip": { "type": "ip" },
            "location" : { "type" : "geo_point" },
            "latitude" : { "type" : "half_float" },
            "longitude" : { "type" : "half_float" }
          }
        }
      }
    }
  }
}

另一种方法是不覆盖 logstash 模板,而是使用任何其他 ID,例如 _template/my_logstash,这样在创建索引时,两个模板都会启动并使用来自官方 logstash 模板的映射和来自您的模板的分片设置。