Logstash向ES写入数据时出现Rejecting mapping update错误求助
我来帮你拆解这个问题的根源,一步步给出解决方案:
为什么会出现这个错误?
核心原因很明确:你的索引模板设置了dynamic: strict模式——这种模式下,Elasticsearch会严格拒绝任何模板中没有预先定义的字段。当Logstash向Elasticsearch发送数据时,如果数据里包含了mappings.properties里没列出的字段,就会触发这个"Rejecting mapping update"的错误。
另外也得确认下配置匹配的细节:你的模板index_patterns是myindexpattern-*,Logstash输出的索引是myindexpattern-%{+YYYY.MM.dd},这个匹配逻辑是对的,但要确保模板确实被正确加载到Elasticsearch里了。
分步解决办法
1. 先找出数据里的"额外字段"
首先得搞清楚Logstash到底在发哪些字段,是不是有模板没覆盖到的:
- 在Logstash的配置里,output部分前面加一段
stdout { codec => rubydebug },这样就能把要发给ES的原始数据打印到控制台,然后对比你模板里的properties字段,找出那些不在定义里的字段。
2. 调整模板的动态映射策略(两种选择)
选项A:把缺失的字段补进模板
如果那些额外字段是你需要保留的,直接把它们添加到模板的properties里就行,比如:
"mappings": { "_doc": { "dynamic" : "strict", "properties": { "existing_field": { "type": "text" }, // 新增你发现的未定义字段 "user_agent": { "type": "keyword" }, "request_time": { "type": "date" } } } }
修改完模板后重启Logstash,它会自动覆盖旧模板(因为你设了template_overwrite => true)。
选项B:放宽动态映射的限制
如果不需要严格管控所有字段,可以把dynamic的值改成false(直接忽略未定义的字段)或者true(让ES自动为新字段创建映射):
"mappings": { "_doc": { "dynamic" : "false", // 换成"true"也可以,看你的需求 "properties": {...} } }
3. 确认模板是否真的被加载到ES了
有时候Logstash可能因为文件权限或者路径问题,没成功把模板上传到ES。你可以用ES的API查一下:
curl -X GET "my-es-host/_template/my-template"
如果返回的内容和你本地的my_template.json不一样,说明模板没被正确覆盖。检查下/usr/share/logstash/files/my_template.json这个路径是否正确,以及Logstash进程有没有读取这个文件的权限。
4. 手动管理模板(可选)
如果不想让Logstash管模板的事,你可以手动把模板上传到ES,然后把Logstash配置里的manage_template改成false:
elasticsearch { hosts => ["my-es-host"] index => "myindexpattern-%{+YYYY.MM.dd}" manage_template => false }
手动上传模板的命令:
curl -X PUT "my-es-host/_template/my-template" -H "Content-Type: application/json" -d @/usr/share/logstash/files/my_template.json
总结
大部分情况下,这个错误都是因为数据里有模板没定义的字段,加上strict模式的限制导致的。先排查数据字段,再根据你的需求调整模板的动态映射策略,同时确保模板正确加载,问题就能解决啦。
内容的提问来源于stack exchange,提问作者pkaramol

