前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Elasticsearch数据写入报错whose UTF8 encoding is longer than the max length 32766的解决方法

Elasticsearch数据写入报错whose UTF8 encoding is longer than the max length 32766的解决方法

原创
作者头像
空洞的盒子
修改2025-03-18 16:28:00
修改2025-03-18 16:28:00
5600
代码可运行
举报
文章被收录于专栏:JD的专栏JD的专栏
运行总次数:0
代码可运行

完整异常信息如下:

代码语言: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规则

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 完整异常信息如下:
  • 报错原因:
  • 解决方案1:修改Filebeat配置,限制字段长度
    • 方式1.1:使用truncate_fields进行字段截断
    • 方式 1.2:使用drop_fields直接删除该字段
  • 解决方案2:调整Elasticsearch的Mapping
    • 方式 2.2:将output设为text并禁用indexing
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档