admin管理员组文章数量:1445106
Elasticsearch数据写入报错whose UTF8 encoding is longer than the max length 32766的解决方法
完整异常信息如下:
代码语言:txt复制Document contains at least one immense term in field=\"output\"
(whose UTF8 encoding is longer than the max length 32766), all of which were skipped.
Please correct the analyzer to not produce such terms.
报错原因:
在索引mapping中,该字段被动态推断为了keyword类型,而Elasticsearch限制了单个字段的最大UTF-8编码长度为32766字节,通过对比原始数据发现,output字段存储的数据为大段的日志文本内容。导致数据超过了该限制。
解决方案1:修改Filebeat配置,限制字段长度
方式1.1:使用truncate_fields进行字段截断
当前场景是通过Filebeat向Elasticsearch写入数据。在Filebeat中我们可以使用truncate_fields处理超长字段,可以在配置中添加以下内容:
代码语言:javascript代码运行次数:0运行复制processors:
- truncate_fields:
fields: ["output"]
max_bytes: 32000
fail_on_error: false
参数解释:
参数 | 释义 |
---|---|
fields: ["output"] | 仅对output 字段生效。 |
max_bytes: 32000 | 限制output 的最大字节数。 |
fail_on_error: false | 避免因截断失败导致日志丢失。 |
适用情况:如果业务允许接受截断数据,则可以采用该方案。
方式 1.2:使用drop_fields直接删除该字段
如果output不是必须存储的字段,可以选择舍弃该字段:
代码语言:javascript代码运行次数:0运行复制processors:
- drop_fields:
fields: ["output"]
适用情况:如果业务可以丢弃output字段数据,可以选择删除来保障主要数据的正常写入。
解决方案2:调整Elasticsearch的Mapping
如果我们需要让这条超长的日志文本进入Elasticsearch,我们可以通过修改索引Mapping的方式,调整output字段的类型。
方式2.1:将output设为keyword并启用ignore_above
修改索引的 Mapping,将output 设置为keyword,并添加ignore_above:
代码语言:javascript代码运行次数:0运行复制PUT indexname/_mapping
{
"properties": {
"output": {
"type": "keyword",
"ignore_above": 32000
}
}
}
解释:
参数 | 释义 |
---|---|
type: "keyword" | 字段类型,适用于日志类数据,防止分词导致过长。 |
ignore_above: 32000 | 让Elasticsearch自动忽略超过32000字节的值,避免写入报错。 |
适用情况:需要保存output字段,但可以接受超长数据被忽略。
方式 2.2:将output设为text并禁用indexing
如果只想存储output字段值,但不希望这个字段被Elasticsearch索引(避免超长字段问题),则可以按照一下方式修改mapping:
代码语言:javascript代码运行次数:0运行复制PUT indename/_mapping
{
"properties": {
"output": {
"type": "text",
"index": false
}
}
}
适用情况:只需要存储该字段数据,不需要对该字段进行搜索。
解决方案 3:使用Logstash的过滤器对该字段进行处理(Filebeat → Logstash → Elasticsearch)
需要先将Filebeat将数据发送至Logstash,然后通过logstash的过滤器处理后,在通过Logstash将数据发送至Elasticsearch,在Logstash中添加mutate过滤器进行处理:
代码语言:javascript代码运行次数:0运行复制filter {
mutate {
replace => { "output" => "[TRUNCATED]" }
}
}
或者:
代码语言:javascript代码运行次数:0运行复制filter {
ruby {
code => "
if event.get('output') && event.get('output').bytesize > 32000
event.set('output', event.get('output')[0..31999])
end
"
}
}
适用情况:使用Logstash作为中间处理层,通过Logstash的filter阶段超长字段。
方案选择建议
方案 | 适用场景 | 配置难度 | 影响 |
---|---|---|---|
Filebeat truncate_fields | 需要保留output字段,但可接受截断 | ⭐ | 超长字段会被截断 |
Filebeat drop_fields | output字段不重要 | ⭐ | 该字段会被删除 |
Elasticsearch ignore_above | 需要索引但可忽略超长值 | ⭐⭐ | 超长数据会被忽略 |
Elasticsearch index: false | 只存储但不搜索该字段 | ⭐⭐ | 不能搜索output字段数据 |
Logstash filter处理 | 使用Logstash作为数据中间层 | ⭐⭐ | 需要引入新的组件来处理问题字段,并需要修改Logstash规则 |
本文标签: Elasticsearch数据写入报错whose UTF8 encoding is longer than the max length 32766的解决方法
版权声明:本文标题:Elasticsearch数据写入报错whose UTF8 encoding is longer than the max length 32766的解决方法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/biancheng/1748221299a2828410.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论