Su的技术博客

  • 首页
  • 原创
  • 视频
  • Java
  • MySQL
  • DDD
  • 事故复盘
  • 架构方案
  • AI
  • Other
  • 工具
    • AI工具集
    • 工具清单
    • JSON在线格式化
    • JSON在线比较
    • SQL在线格式化
  • 打赏
  • 关于
路很长,又很短
  1. 首页
  2. ElasticSearch
  3. 正文
                           

【flattened】Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!

2025-03-02 573点热度 0人点赞 0条评论

1、线上真实案例

球友问题:我记得您写过一篇关于建模字段膨胀的问题,对于比如request header response这种动态的对象,是怎么处理来着?

进一步反馈:决定升级es高版本了,Flattened  解千愁!主要我们这需求要把接口所有信息都保留,只能这样了。

2、Elasticsarch 字段膨胀

Elasticsearch Mapping 如果不做特殊设置,默认为 dynamic。dynamic 的本质就是:不加约束的动态添加字段。这样对某些日志场景,可能会产生大量的未知字段。字段如果持续激增,就会达到 Elasticsearch Mapping 层面的默认上限,对应设置和默认大小为:index.mapping.total_fields.limit:1000。

我们把这种非预期字段激增的现象或结果称为:字段膨胀。

拿自己线上环境示例,说一下 dynamic 的副作用。在一个实际业务环境,混淆了检索和写入的语法,会导致将检索语句动态认定为新增 Mapping 字段。

当然,如果是非常复杂的大 bool 检索语句,会导致 Mapping 变得非常复杂甚至会出现字段膨胀的情况。

Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!

当然,可行的解决方案就是:dynamic 设置为 false,甚至更为严谨的推荐方式:将 dynamic 设置为 strict。

2.1 解决字段膨胀方案一:dynamic 设置为 false

dynamic 设置为 false 后,新来的非 mapping 预设字段数据可以写入,但是:不能被检索,仅支持 Get 获取文档的方式通过 _source 查看详情内容。
举例如下:

Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!

2.2 解决字段膨胀方案二:dynamic 设置为 strict

dynamic 一旦设置为:strict,会“阻止一切来犯之敌”,一切索引创建阶段指定的 Mapping 字段之外的字段名称都将会报错。
设置为 strict 后,再动态插入数据,会报错如下:
{
  "error" : {
    "root_cause" : [
      {
        "type" : "strict_dynamic_mapping_exception",
        "reason" : "mapping set to strict, dynamic introduction of [cont] within [_doc] is not allowed"
      }
    ],
    "type" : "strict_dynamic_mapping_exception",
    "reason" : "mapping set to strict, dynamic introduction of [cont] within [_doc] is not allowed"
  },
  "status" : 400
}

3、Flattened  类型产生的背景

如前分析,将 dynamic 设置为 false 或者 strict 不是普适的解决方案 ,如日志场景需求如下:

  • 一方面:期望能动态添加字段。strict 过于严谨会导致新字段数据拒绝写入,dynamic 过于松散会字段膨胀。

  • 另一方面:不期望索引字段膨胀。

这就导致同时满足上述两个方面的 Flattend 字段的诞生。

Flattened  中文释义:“压扁、弄平”,实际就是字段扁平化的意思。

当面临处理包含大量不可预测字段的文档时,使用 Flattend 类型可以通过将整个 JSON 对象及其嵌套 Nested 字段索引为单个关键字 keyword 类型字段来帮助减少字段总数。

Flattened 类型的最早发布在:7.3 版本。

4、Flattened 类型解决的根本问题

特定日志场景、电商场景,Elasticsearch Mapping 字段数有时是无法预知的。如果随着新写入数据激增,字段也激增,可能带来的后果是什么呢?

Elasticsearch 必须为每个新字段更新集群状态,并且必须将此集群状态传递给所有节点。由于跨节点的集群状态传输是单线程操作,因此需要更新的字段映射越多,完成更新所需的时间就越长。这种延迟通常大大降低集群性能,有时会导致整个集群宕机。这被称为“ Mapping 爆炸”(mapping explosion)。

这也是 Elasticsearch 从 5.x 及更高版本将索引中的字段数限制为 1000 的原因之一。如果实战业务场景字段数超过 1000,我们必须手动更改默认索引字段限制或者重新考虑架构重构。

修改默认值的方式如下:

PUT record_infos
{
  "settings": {
    "index.mapping.total_fields.limit": 2000
  }
}
Flattened  扁平化字段就是解决:“Mapping 爆炸”问题的。

5、Flattened  类型实战解读

5.1 Flattened  类型真容

千呼万唤始出来,Flattend 真容如下:

Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!

这和 Integer、long、nested、join 等都属于字段类型的范畴。
Flattened  本质是:将原来一个复杂的 Object 或者 Nested 嵌套多字段类型统一映射为偏平的单字段类型。
这里要强调的,不管原来内嵌多少个字段,内嵌多少层,有了 Flattend,一下都打平!!

5.2 基于 Flattened 类型插入数据

基于上面的 Mapping,写入一条数据如下:
PUT demo-flattened/_doc/1
{
  "message": "[5592:1:0309/123054.737712:ERROR:child_process_sandbox_support_impl_linux.cc(79)] FontService unique font name matching request did not receive a response.",
  "fileset": {
    "name": "syslog"
  },
  "process": {
    "name": "org.gnome.Shell.desktop",
    "pid": 3383
  },
  "@timestamp": "2020-03-09T18:00:54.000+05:30",
  "host": {
    "hostname": "bionic",
    "name": "bionic"
  }
}
这时候再查看 Mapping, 如下:

Elasticsearch 字段膨胀不要怕,Flattened 类型解千愁!

由于 host 字段设置为:Flattened,其下的:hostname、name 字段都不再映射为特定嵌套子字段。

5.3 更新 Flattened 字段,添加数据

POST demo-flattened/_update/1
{
  "doc": {
    "host": {
      "osVersion": "Bionic Beaver",
      "osArchitecture": "x86_64"
    }
  }
}
再次查看 Mapping,依然“岿然不动”。继续 Flattened 拉平,没有字段扩增,也就不会再有 “Mapping 爆炸”出现。

5.4 Flattened 类型检索

以下两种检索都会召回数据:
GET demo-flattened/_search
{
  "query": {
    "term": {
      "host": "Bionic Beaver"
    }
  }
}
GET demo-flattened/_search
{
  "query": {
    "term": {
      "host.osVersion": "Bionic Beaver"
    }
  }
}

而,如下的检索,则返回结果为空。

GET demo-flattened/_search
{
  "query": {
    "match": {
      "host.osVersion": "bionic beaver"
    }
  }
}

GET demo-flattened/_search
{
"query": {
"match": {
"host.osVersion": "Beaver"
}
}
}

为什么呢?
由于使用 Flattened 扁平化类型,Elasticsearch 未对该字段进行分析,因此它只会返回匹配字母大小写且完全一致的结果。
如上检索结果和 keyword 类型检索结果一致。
这也初步暴露出:Flattened 类型的部分缺陷。

5.5 Flattend 类型的不足

每当面临 Flattened 扁平化对象的决定时,在选型 Elasticsearch 扁平化数据类型时,我们需要考虑以下几个关键限制:
Flattened 类型支持的查询类型目前仅限于以下几种:
  • term
  • terms
  • terms_set
  • prefix
  • range
  • match and multi_match
  • query_string and simple_query_string
  • exists
Flattened 不支持的查询类型如下:
  • 无法执行涉及数字计算的查询,例如:range query。
  • 无法支持高亮查询。
  • 尽管支持诸如 term 聚合之类的聚合,但不支持处理诸如“histograms”或“date_histograms”之类的数值数据的聚合。

6、小结

Flattened 类型的出现,解决了字段膨胀引起的 Mapping 爆炸问题,如果您的生产环境高于7.3版本,有文章开头类似问题,可以小心求证、大胆尝试这种新类型。
您生产环境使用 Flattened 类型了吗?您有没有遇到过字段膨胀或“Mapping 爆炸”问题,是如何解决的?
欢迎留言说一下您的实战思考!
ps:文章标题灵感起源于球友微信交流,对球友表示感谢!

参考

https://coralogix.com/blog/flattened-datatype-mappings-elasticsearch-tutorial/

https://www.elastic.co/guide/en/elasticsearch/reference/master/flattened.html#flattened

本文仅供学习!所有权归属原作者。侵删!文章来源: 铭毅天下Elasticsearch -铭毅天下 :http://mp.weixin.qq.com/s/jVs-jOSPXZ07ikcZ0d0SqQ

更多文章:

  1. Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!
  2. Spring事务无法生效的11个场景
  3. Elasticsearch 中 _count 和 _stats 文档数量不一致的困惑与解决方案
  4. Routing Elasticsearch架构VI:路由
  5. Java后端18种接口优化技巧
  6. DDD系列第五讲:聊聊如何避免写流水账代码
  7. 系统设计 | 对象转换方案
  8. ElasticSearch之各大版本演进,发布8.0.0 Alpha 2版本
  9. 图解Git
  10. Eureka源码剖析之三:服务拉取
标签: flattened ElasticSearch
最后更新:2025-03-03

coder

分享干货文章,学习先进经验。

打赏 点赞
< 上一篇
下一篇 >
广告
文章目录
  • 1、线上真实案例
  • 2、Elasticsarch 字段膨胀
    • 2.1 解决字段膨胀方案一:dynamic 设置为 false
    • 2.2 解决字段膨胀方案二:dynamic 设置为 strict
  • 3、Flattened  类型产生的背景
  • 4、Flattened 类型解决的根本问题
  • 5、Flattened  类型实战解读
    • 5.1 Flattened  类型真容
    • 5.2 基于 Flattened 类型插入数据
    • 5.3 更新 Flattened 字段,添加数据
    • 5.4 Flattened 类型检索
    • 5.5 Flattend 类型的不足
  • 6、小结
  • 参考
最新 热点 推荐
最新 热点 推荐
干货 | 论Elasticsearch数据建模的重要性 马蜂窝消息总线——面向业务的消息服务设计 基于 MySQL Binlog 实现可配置的异构数据同步 视频笔记:Google发布Agent2Agent协议 视频笔记:什么是微服务,为什么是微服务? 视频笔记:什么是AI 智能体? 视频笔记:什么是Flink? 如何秒级实现接口间“幂等”补偿:一款轻量级仿幂等数据校正处理辅助工具
Elasticsearch 使用误区之六——富文本内容写入前不清洗基于 MySQL Binlog 实现可配置的异构数据同步马蜂窝消息总线——面向业务的消息服务设计干货 | 论Elasticsearch数据建模的重要性你可以不用RxJava,但必须得领悟它的思想!如何秒级实现接口间“幂等”补偿:一款轻量级仿幂等数据校正处理辅助工具视频笔记:什么是Flink?视频笔记:什么是AI 智能体?
干货 | 论Elasticsearch数据建模的重要性 解决事件驱动架构中的数据一致性难题 历经 16 年猪八戒网如何成功实现双活流量架构 如何画好一张架构图/业务图/流程图,掌握这4个关键点 康威定律:为什么你的架构会反映团队结构? LangChain原理学习笔记 笔记 | 5种网络IO模型 2.软件架构预述(译)

CRUD (1) Event Sourcing (1) graphql (1) id (1) NoSQL (1) quarkus (1) rest (1) RocketMQ (2) Spring Boot (1) zk (1) zookeeper (1) 上下文 (1) 事务消息 (1) 二级缓存 (1) 值对象 (1) 关系数据库 (1) 分布式缓存 (1) 原子性 (1) 唯一ID (1) 商品 (1) 多对多 (1) 子域 (1) 字符集 (1) 客户端心跳 (1) 幂等 (2) 干货 (1) 并发 (1) 应用场景 (1) 应用架构图 (1) 康威定律 (2) 异步复制 (1) 微服务架构 (2) 总体方案 (1) 技术方案 (2) 技术架构 (2) 技术架构图 (1) 技能 (1) 持续集成 (1) 支撑域 (1) 故障恢复 (1) 数据架构图 (1) 方案选型 (1) 日记 (1) 服务发现 (1) 服务治理 (1) 服务注册 (2) 机房 (1) 核心域 (1) 泄漏 (1) 洋葱架构 (1) 消息队列 (5) 源码剖析 (1) 灰度发布 (1) 熔断 (1) 生态 (1) 画图工具 (1) 研发团队 (1) 线程 (2) 组织架构 (1) 缓存架构 (1) 编码 (1) 视频 (18) 读写分离 (1) 贵州 (1) 软件设计 (1) 迁移 (1) 通用域 (1) 集群化 (1) 雪花算法 (1) 顺序消息 (1)

推荐链接🔗
  • AI工具集
  • 工具箱🛠️

COPYRIGHT © 2014-2025 verysu.com . ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

粤ICP备15033072号-2

x