Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案

这篇具有很好参考价值的文章主要介绍了Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、什么是 Mapping “爆炸”?

Elasticsearch 映射如果不做特殊处理,默认 dynamic 为 true。dynamic 为 true 的确切含义是:根据导入的数据自定识别字段类型(有可能不精确),也就是说,可以提前不指定 Mapping,也能写入数据。

但,这导致的问题也非常明显。Mapping 字段越多,会超过默认字段数上限。超过上限后会导致性能下降和内存问题,特别是在高负载或资源有限的集群中表现更为突出。

举例:index.mapping.total_fields.limit 限制的默认最大字段数为 1000。

2、Mapping “爆炸”带来的问题?

之前被问过类似的问题:

“博主,我们现在的业务场景是在宽表中,2000+个字段的联合查询,但是es默认单个索引的字段数是1000个,过多会导致内存问题,和es的性能问题,该如何解决这样的场景呢?”

如下所示,如果任由“sub_field”字段扩展,就会导致 Mapping “爆炸”。

POST dynamic-mapping-test/_doc
{
  "message": "hello",
  "transaction": {
    "user": "hey",
    "amount": 3.14,
    "field3": "hey there, new field",
    "field4": {
      "sub_user": "a sub field",
      "sub_amount": "another sub field",
      "sub_field3": "yet another subfield",
      "sub_field4": "yet another subfield",
      "sub_field5": "yet another subfield",
      "sub_field6": "yet another subfield",
      "sub_field7": "yet another subfield",
      "sub_field8": "yet another subfield",
      "sub_field9": "yet another subfield",
      "sub_fieldx": "yet another subfield"
    }
  }
}

实际业务中不见得所有的字段都需要检索和聚合操作,但如上所有字符串类型都被映射为 “text” 和 “keyword” 组合类型。

我们将浪费内存和磁盘空间来存储这些字段,极大可能这些字段中的某些字段从未被使用过,它们存在的目的仅是:"万一 "它们需要被用于搜索。

3、如何避免 Mapping "爆炸"?

第一:业务层面要尽可能的梳理清楚需求,尽可能避免后期的需求变更导致的 Mapping 的大改。

第二:技术层面要贴合业务需求,合理、规范、站在未来用户使用的角度建模。

3.1 方案一:设置 dynamic 为 strict

dynamic 一旦设置为 strict,就意味着只要字段不在初始设定的范围内,就禁止写入。这是最严格的 Mapping 控制策略。

举例,如下的索引创建dynamic 设置为 strict,而后导入了预制 Mapping 中没有的字段 “field3”。

DELETE dynamic-mapping-test
PUT dynamic-mapping-test
{
 "mappings": {
   "dynamic": "strict",
   "properties": {
     "message": {
       "type": "text"
     },
     "transaction": {
       "properties": {
         "user": {
           "type": "keyword"
         },
         "amount": {
           "type": "long"
         }
       }
     }
   }
 }
}

POST dynamic-mapping-test/_doc
{
  "message": "hello",
  "transaction": {
    "user": "hey",
    "amount": 3.14,
    "field3": "hey there, new field"
  }
}

写入 “field3”会报错如下:

Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案

"dynamic:strict" 应用场景

确定业务层面 Mapping 一经敲定,后面不再修改,则可大胆使用 strict。

这对业务层面、需求层面要求非常高!

3.2 方案二:设置 dynamic 为 false

如果 dynamic 设置为 true 代表很“宽泛”的要求;dynamic 设置为 strict 代表很‘’严格”近乎苛刻的要求。

则,dynamic 设置为 false 则代表介于两者中间的要求。

如下所示,批量写入数据的时候,写入了 mapping 中没有的字段 title。

PUT dynamic-mapping-disabled
{
  "mappings": {
    "dynamic": "false",
    "properties": {
      "message": {
        "type": "text"
      }
    }
  }
}

POST dynamic-mapping-disabled/_bulk
{"index":{"_id":1}}
{"title":"elasticsearch is very good!"}

写入不会报错。但写入后查看一下 Mapping。

GET dynamic-mapping-disabled/_mapping
Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案

执行检索和聚合操作如下,检索和聚合均没有任何数据召回。

## 如下查询,没有任何数据召回!
POST dynamic-mapping-disabled/_search
{
  "query": {
    "match": {
      "title": "good"
    }
  }
}

## 如下聚合,没有任何数据召回
POST dynamic-mapping-disabled/_search
{
  "size":0,
  "aggs": {
    "terms_aggs": {
      "terms": {
        "field": "title",
        "size": 10
      }
    }
  }
}

"dynamic:false" 应用场景

当设置 dynamic 为 false 时,非 Mapping 指定的字段数据,如上“title”也可以写入索引。但,并没有建立倒排索引和正排索引,也就是说,不会被检索和聚合召回。仅在_source 中被召回显示。这些字段仅会浪费磁盘空间,不会占据内存空间。

POST dynamic-mapping-disabled/_search
Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案

3.3 方案三:设置 dynamic 为 runtime(运行时字段类型)

之前咱们已经过 runtime field 的来龙去脉。

如果把没有 runtime field 之前的 Mapping 叫做 shema on write,那么 runtime field 革命性创新在与其是 schema on read。

runtime field 的本质是:不会在新字段上浪费内存存储,但我们要付出查询或聚合操作响应速度变慢的代价。

仍拿之前的索引和数据为例。

DELETE dynamic-mapping-runtime
PUT dynamic-mapping-runtime
{
 "mappings": {
   "dynamic": "runtime",
   "properties": {
     "message": {
       "type": "text"
     },
     "transaction": {
       "properties": {
         "user": {
           "type": "keyword"
         },
         "amount": {
           "type": "long"
         }
       }
     }
   }
 }
}

POST dynamic-mapping-runtime/_doc
{
 "message": "hello",
 "transaction": {
   "user": "hey",
   "amount": 3.14,
   "field3": "hey there, new field",
   "field4": {
     "sub_user": "a sub field",
     "sub_amount": "another sub field",
     "sub_field3": "yet another subfield",
     "sub_field4": "yet another subfield",
     "sub_field5": "yet another subfield",
     "sub_field6": "yet another subfield",
     "sub_field7": "yet another subfield",
     "sub_field8": "yet another subfield",
     "sub_field9": "yet another subfield"
   }
 }
}
GET dynamic-mapping-runtime/_mapping

Mapping 返回如下:

Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案

这些运行时的字段是可以被检索的,举例如下:

POST dynamic-mapping-runtime/_search
{
 "query": {
   "term": {
     "transaction.field4.sub_field6": "yet another subfield"
   }
 }
}

"dynamic:runtime" 应用场景

当不知道要写入什么类型的文档时,这个策略会很有用!使用运行时字段是一个保守的方法,需要在性能和映射复杂性之间有一个很好的权衡。

4、小结

每种方案都有优点,当然也存在不足,我们需要结合自己业务场景仔细斟酌后选型。

类别 优点 缺点
strict 字段必须先明确指定 非明确指定的字段,禁止写入
false 所有字段均可写入 未被映射的字段不能用于搜索或聚合
runtime 更为灵活的方式 在查询运行时字段时,搜索响应时间相对较慢,需要做好取舍、权衡利弊

大家还有没有更好的方案?欢迎留言交流。

 参考&推荐

1、https://www.elastic.co/cn/blog/3-ways-to-prevent-mapping-explosion-in-elasticsearch

2、Elasticsearch 运行时类型 Runtime fields 深入详解

3、阿里云大佬叮嘱我务必要科普这个 Elasticsearch API

4、Elasticsearch 可以更改 Mapping 吗?如何修改?

更短时间更快习得更多干货!

中国50%+Elastic认证专家出自于此!

在不确定的时代,寻求确定性!

Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案

比同事抢先一步学习进阶干货!文章来源地址https://www.toymoban.com/news/detail-418449.html

到了这里,关于Elasticsearch 8.X 防止 Mapping “爆炸”的三种方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter屏幕适配的三种方案

    做移动端开发的同学都知道,针对不同型号和尺寸的手机要进行页面的适配,且 iOS 和 Android 适配方案各不相同,那我们用 Flutter 开发要怎么处理屏幕适配呢? Flutter使用的是类似于iOS中的点pt,也就是point。我们经常说 iPhone8 的尺寸是375x667,但是它的分辨率其实是 750x1334 。因

    2024年02月06日
    浏览(35)
  • 恒流电路的三种设计方案

    作为硬件研发工程师相信对恒流电路不会陌生,本文介绍下三种恒流电路的原理图。 三极管恒流电路 三极管恒流电路     三极管的恒流电路,主要是利用Q2三极管的基级导通电压为0.6~0.7V这个特性;当Q2三极管导通,Q1三极管基级电压被拉低而截止,负载R1不工作;负载R1流

    2024年02月11日
    浏览(50)
  • iOS 组件化的三种方案

    本文主要介绍iOS组件化的三种方案 URL Scheme Target - Action Protocol - Class 匹配 1.1、 URL Scheme路由 使 URL 处理本地的跳转 通过中间层进⾏注册 调⽤ (load方法里把被调用者注册到中间层) 注册表⽆需使用反射 非懒加载 / 注册表的维护 / 参数 URL Scheme路由示例  参考了系统URL Schem

    2024年02月12日
    浏览(35)
  • PyTorch使用Tricks:梯度裁剪-防止梯度爆炸或梯度消失 !!

    前言 1、对参数的梯度进行裁剪,使其不超过一个指定的值 2、一个使用的torch.nn.utils.clip_grad_norm_ 例子 3、怎么获得梯度的norm 4、什么情况下需要梯度裁剪 5、注意事项 梯度裁剪(Gradient Clipping)是一种防止梯度爆炸或梯度消失的优化技术,它可以在反向传播过程中对梯度进行

    2024年02月22日
    浏览(51)
  • 分享后端解决跨域问题的三种方案

    跨源资源共享( CORS——Cross-Origin Resource Sharing ,跨源资源共享,或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它源(域、协议或端口),使得浏览器允许这些源访问加载自己的资源。跨源资源共享还通过一种机制来

    2024年02月02日
    浏览(57)
  • Redis数据一致性问题的三种解决方案

    Redis(Remote Dictionary Server ),是一个高性能的基于Key-Value结构存储的NoSQL开源数据库。大部分公司采用Redis来实现分布式缓存,用来提高数据查询效率。 在Web应用发展的初期,系统的访问和并发并不高,交互也比较少。但随着业务的扩大,访问量的提升,使得服务器负载和关系

    2024年02月14日
    浏览(37)
  • 虚拟机的三种网络模式分别是什么含义?

    桥接模式: 其实就是你的虚拟机当做局域网中的一员,跟你的主机是平起平坐的。虚拟机的网段和主机的网段是一样的。比如 主机是192.168.1.101 , 虚拟机也是192.168.1.102..... 弊端:假如你现在从学院回家了,主机的IP会发生变化,而你的虚拟机由于都是设置的静态,所以不发生

    2023年04月17日
    浏览(40)
  • React创建组件的三种方式及其区别是什么?

    在React中,创建组件的三种主要方式是函数式组件、类组件和使用React Hooks的函数式组件。以下是对每种方式的详细解释以及它们之间的区别: 1、函数式组件: 函数式组件是使用纯粹的JavaScript函数来定义的。它接收一个props对象作为参数,并返回一个用于描述组件UI的React元

    2024年02月11日
    浏览(43)
  • MySQL大数据表处理的三种方案,查询效率嘎嘎高

    场景 当我们业务数据库表中的数据越来越多,如果你也和我遇到了以下类似场景,那让我们一起来解决这个问题 数据的插入,查询时长较长 后续业务需求的扩展 在表中新增字段 影响较大 表中的数据并不是所有的都为有效数据 需求只查询时间区间内的 评估表数据体量 我们可

    2024年02月13日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包