图解 Elasticsearch 的 Fielddata Cache 使用与优化

news2024/9/22 15:38:28

1、难搞的 fielddata cache

在 ES 使用的几个内存缓存中,fielddata cache 算是一个让人头疼的家伙。

作为和 query cache 和 request cache 一样不受 GC 控制的内存使用者,fielddata cache 虽然也有 indices.fielddata.cache.size 的设置来阻止过度使用,但是默认是不限制的

并且,当 fielddata cache 达到 indices.fielddata.cache.size 设定值的时候,虽然有类似LRU的清理算法,但是官方还是建议你进行手工清理

97b89e055c4e51e3a361dc9d0fb4989a.png

那么 fielddata cache 是被什么内容使用了呢?它的作用是什么呢?我们结合官方的一些资料扒一扒。

2、fielddata 内存构成

根据官方文档中的信息,我这边做了这么一个汇总。

034a78218c0da5bcc9744579f7ddb705.png

其中 bucket aggregations 特定包括我们常用的 terms 以及 composite/diversified_sampler/significant_terms

使用的涉及面还不少,不仅有倒排字段,还有聚合查询甚至还扯上了不常见的 join 关联字段类型。感觉这类缓存的使用很复杂。

下面,我们先来看看 Text 的 fielddata。

3、Text 的 fielddata 使用

Text 类型结合分词器的使用产生的倒排索引,可以满足用户进行数据检索的需求。

但是倒排索引是不支持排序聚合以及脚本编辑处理的这些需求的,而这些需求在日常业务场景下又是不避免的,那怎么办呢?

ES 做了 fielddata 这个属性来满足这一部分需求。

简单来说,开启 text 字段的 fielddata 后,ES 将把所有字段的值(即分词后的 token)装载进内存,然后对数据进行重新计算实现适合排序聚合等需求的内存数据结构。

a8d655cfcae76aaa1aa09eb12407de93.png

比起在检索查询直接访问写入时计算好的倒排索引数据结构,排序聚合等查询则需要在数据重载到内存中计算出数据结构。

这样的使用方式让 jvm 内的 fielddata cache 承担了较大的空间使用,动不动好几 GB。

并且在 ES 古早的版本中,由于没有 docvalue 的设计,排序聚合等场景可能需要在 text 上开启 fielddata 得以实现,不仅使用麻烦,OOM 的风险也增加了。

4、global ordinals

除了 text 字段上的 fielddata,另一个使用 fielddata cache 的 global ordinals 也占据了 fielddata cache 的很多使用场景。

要想了解 global ordinals的产生,我们先聊聊 doc values。

4.1 doc values 是什么

Doc values 是 lucene 4 版本开始的一个特性,它以列存的方式将字段值存储在磁盘,这样既能利用了堆外的系统缓存,同时又实现排序查询或者 scripting 所需要的数据结构,完成了 fielddata 一样的任务。

原来的写入流程和排序 scripting 是这样的

e789f776ce4a85a4af99545b190f1da4.png

有了 doc values 后

88ad3ed9ba01e22e9e9b085278e317e8.png

不仅可以在数据写入时就产生列存结构数据结果,同时减少了 jvm 内存的使用

当然,如果只是为了把数据计算提前到写入时和减少对堆内内存的使用,这对于 ES 来说显然是不够的。

doc values 实际有多种存储结构,都实现了快速随机访问与数据压缩的均衡。

  • NumericDocValuesWriter (数值类型,ES 使用这个类型存储_seq_no等元数据字段)

  • SortedNumericDocValuesWriter (多值内部排序的数值类型,被存储的字段是数值类型的数组,ES 使用这种方式存储用户定义的数值类型)

  • SortedDocValuesWriter (排序的字符类型,保存原始值及 hash 位置)

  • SortedSetDocValuesWriter (排序的字符数组类型,保存原始值及 hash 位置)

对其底层实现有兴趣的同学可以查看这篇博客:https://mp.weixin.qq.com/s/kP5Pza2xRtBlcJs5WYvgjA

4.2 global ordinals 让 doc values 聚合

现在我们再去理解 global ordinals 会更简单一些,下面是官网对其的定义:

To support aggregations and other operations that require looking up field values on a per-document basis, Elasticsearch uses a data structure called doc values. Term-based field types such as keyword store their doc values using an ordinal mapping for a more compact representation. This mapping works by assigning each term an incremental integer or ordinal based on its lexicographic order. The field’s doc values store only the ordinals for each document instead of the original terms, with a separate lookup structure to convert between ordinals and terms.
When used during aggregations, ordinals can greatly improve performance. As an example, the terms aggregation relies only on ordinals to collect documents into buckets at the shard-level, then converts the ordinals back to their original term values when combining results across shards.
Each index segment defines its own ordinal mapping, but aggregations collect data across an entire shard. So to be able to use ordinals for shard-level operations like aggregations, Elasticsearch creates a unified mapping called global ordinals. The global ordinal mapping is built on top of segment ordinals, and works by maintaining a map from global ordinal to the local ordinal for each segment.
Global ordinals are used if a search contains any of the following components:
Certain bucket aggregations on keyword, ip, and flattened fields. This includes terms aggregations as mentioned above, as well as composite, diversified_sampler, and significant_terms.
Bucket aggregations on text fields that require fielddata to be enabled.
Operations on parent and child documents from a join field, including has_child queries and parent aggregations.
The global ordinal mapping uses heap memory as part of the field data cache. Aggregations on high cardinality fields can use a lot of memory and trigger the field data circuit breaker.

翻译一下:

  1. 聚合涉及每个分片每个segment数据的汇总计算。

  2. 以词项数据为主的字段类型(或者说字符串数据,比如 keyword 类型)的 doc values 使用一种紧凑的数据结构 ordinals 来映射原始 terms 的值,ordinals 能加速聚合查询

  3. global ordinal 是对每个 segment oridnals 的 map 映射

  4. global ordinal mapping 使用了 fielddata cache 的内存。

注意:这里只说明是 Term-based field types,涉及的是 keyword/ip/flattened 这三个类型。其他类型比如 long/int 等使用聚合则并不会使用 global ordinals。

有兴趣的大佬可以验证 lucene 的org.apache.lucene.index.OrdinalMap 类,欢迎指正

7915f056b6ff6bde453d85eb5da3af51.png

鉴于每个 segment 上的 ordinal mapping 已经压缩映射了原本的字段数据,而 global ordinals 是每个 ordinals 的一个 map。不难看出,global ordinal 在 fielddata cache 中的占用会比简单的 text 开启 fielddata 装载数据到内存减少很多

虽然 global ordinals 已经做了不少内存使用优化,但是高基数的数据聚合会占用大量的内存,这里的高基数是指一个字段包含很大比例的唯一值。

5、 fielddata内存监控与清理

5.1 设置限制

这里主要有两个限制可以控制 fielddata cache 的使用:indices.fielddata.cache.size 和 indices.breaker.fielddata.limit.

indices.fielddata.cache.size
(Static) The max size of the field data cache, eg 38% of node heap space, or an absolute value, eg 12GB. Defaults to unbounded. If you choose to set it, it should be smaller than Field data circuit breaker limit.

indices.breaker.fielddata.limit
(Dynamic) Limit for fielddata breaker. Defaults to 40% of JVM heap.

indices.fielddata.cache.size 的设置要比 indices.breaker.fielddata.limit 小。

一旦超出了 breaker 的使用量,那就会触发内存的熔断了。

这里做个假设吧,一个 ES 进程实例申请 jvm 内存 10GB,那么 indices.breaker.fielddata.limit 就默认为 heap 的 40%,也就是 4GB,这样 indices.fielddata.cache.size 的设定则要小于 40% 或者 4GB,比如 35% 或者 3.5GB,那么就会有 0.5GB 的 indices.breaker.fielddata.limit 冗余。

444253378fa9f16fe2dc51b195b74a4c.png

5.2 监控与清理

监控命令

GET _cat/fielddata?v

#查看索引的fielddata
GET _stats/fielddata?level=indices

#查看主机级别
GET _nodes/stats/indices/fielddata?fields=*

#查看主机上index级别字段级别
GET _nodes/stats/indices/fielddata?level=indices&fields=*

为了避免监控数据膨胀,一般是做到索引级别的使用监控,实际定位问题去使用字段级别的维度去人工定位。

清理命令

POST /my-index-000001/_cache/clear?fielddata=true

6、 小结和建议

不难看出,doc values 其实是对倒排索引的 fielddata 使用的变迁和优化,以一种列存的文件模式实现了聚合排序场景的需求使用。

Text 开启 fielddata 的实现方式相对比较粗糙,简单的申请 jvm 内存进行多个场景的数据构建计算,不仅需要不少的内存资源,也无法利用更多的计算资源和空间。

Doc values 则经过各种列存数据文件的精细设计,即满足了 fielddata 的需求场景,也降低了 jvm 内存的使用,又在数据压缩和快速读取上实现了最大化,替代 fielddata 大部分的使用场景。

但对于 text 文本字符串长文中的单字聚合场景,比如:实现 text 字段的词云效果,还必须使用 fielddata enable 属性。

2b79cc1d5fdf135d93fddf87721c3397.png

Kibana 8.X 如何做出靠谱的词云图?

其实不管是 fielddata 还是 doc values,ES 使用 fielddata cache 几乎都是满足聚合排序等查询需求(除 join 字段)。

但是 jvm heap 内存资源是紧张且宝贵的,为了安全使用 ES,加强堆内的资源进行有效的利用,在此总结了以下几个建议:

  • 合理设置 indices.fielddata.cache.size

  • 避免对 text 直接使用 fielddata,利用 doc values 替代其使用场景。

  • 建立模型,清洗数据,利用合适的字段进行排序聚合。比如 数字类型数据双字段,聚合使用 long,查询匹配使用 keyword。

  • terms/sampler/significant_terms 这些聚合方法中将 execution_hint 设置为 map,一般基数在百万以下的改为 map 方式会更优(字段值特别长的例外)。

  • 可以考虑对没有更新的历史数据进行 forcemerge,将 segment 数量减少到最小。

  • 尽量减少 ES 执行聚合的复杂度,超大数据体量多层次的聚合还是对系统资源的一次考验

  • 做好对 fielddata 内存的监控和及时的处理,有必要时直接清理

7、 参考资料

DocValues 存储格式及压缩实现

https://mp.weixin.qq.com/s/kP5Pza2xRtBlcJs5WYvgjA

Disk-Based Field Data a.k.a. Doc Values

https://www.elastic.co/cn/blog/disk-based-field-data-a-k-a-doc-values

Doc Values and Fielddata

https://www.elastic.co/guide/en/elasticsearch/guide/current/docvalues-and-fielddata.html

更多推荐

  1. Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!

  2.   Elasticsearch 使用误区之二——频繁更新文档

  3.  Elasticsearch 使用误区之三——分片设置不合理

  4. Elasticsearch 使用误区之四——不合理的使用 track_total_hits

  5. Elasticsearch Filter 缓存加速检索的细节,你知道吗?

  6. 深入解析 Elasticsearch IK 分词器:ik_smart 和 ik_max_word 的区别与应用场景

  7.    《一本书讲透 Elasticsearch》读者群的创新之路

616001d8fe06d66bee662dc2effbc402.png

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

和全球2000+ Elastic 爱好者一起精进!

elastic6.cn——ElasticStack进阶助手

121eddb0bb1e69440374a5d0ab1cae32.gif

抢先一步学习进阶干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2078805.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vite-plugin-ejs:打包时报错:hook is not a function

现象:打包时提示hook is not a function 解决方法1: 在node_modules中找到vite-plugin-ejs的index.js,将handler修改为transform: 解决方法2: 使用vite --version命令查看本机的vite版本,根据插件的写法选…

WMS仓储管理系统的这些功能模块一定要做好

在当今物流行业迅猛发展的背景下,仓储管理的智能化升级已成为企业提升竞争力的关键一环。智能立体仓库系统的构建,正是这一趋势下的重要里程碑,它以高度自动化、精准化的货物处理能力,重新定义了仓储作业的标准。而这一切的核心驱…

CAD波浪线画法2

cad波浪线怎么画出来 - 软件自学网下面给大家介绍的是cad波浪线怎么画出来的方法,具体操作步骤如下:https://rjzxw.com/jiaocheng/18774.html这个是对的,适合多个版本

网络安全系统性学习路线「全文字详细介绍」

🤟 基于入门网络安全打造的:👉黑客&网络安全入门&进阶学习资源包 一、基础与准备 网络安全行业与法规 想要从事网络安全行业,必然要先对行业建立一个整体的认知,了解网络安全对于国家和社会的作用&#xff0…

C++学习笔记——最大的数

一、题目描述 二、代码 #include <iostream> using namespace std; double bijiao(double ca,double cb,double cc) {double* t &ca;if(*t < cb) t&cb;if(*t < cc) t&cc;return *t; } int main() {double a,b,c; cin >> a >> b >>…

聚鼎科技:新人开一家装饰画店铺怎么快速起店

在当下这个看重审美和个性表达的时代&#xff0c;开设一家装饰画店铺无疑是迎合市场的明智选择。对于新人来说&#xff0c;快速且有效地启动一家装饰画店铺并非易事&#xff0c;但通过遵循一些关键步骤&#xff0c;可以大大缩短起步时间并提高成功率。 进行市场调研&#xff0c…

[Meachines] [Medium] Bastard Drupal 7 Module Services-RCE+MS15-051权限提升

信息收集 IP AddressOpening Ports10.10.10.9TCP:80,135,49154 $ nmap -p- 10.10.10.9 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 7.5 | http-methods: |_ Potentially risky methods: TRACE | http-robots.…

如何轻松合并 PDF 文件

管理和组织电子文件是个人和专业人士的一项重要技能。组合 PDF 文件是一项常见任务&#xff0c;可以帮助增强您的工作流程&#xff0c;从而更好地共享信息、协作项目和维护整洁的数字工作流程。在这篇博文中&#xff0c;我们将探讨如何在笔记本电脑或计算机上轻松合并 PDF 文件…

异步任务的艺术:Bull应用详解

Bull 是一个强大的 Node.js 库&#xff0c;它基于 Redis 构建&#xff0c;为异步任务队列提供了简单而强大的解决方案。 它支持多种任务处理模式&#xff0c;包括延迟任务、重复任务和优先级队列&#xff0c;使得发送电子邮件、生成报告或处理图像等耗时操作变得轻而易举。Bull…

书生.浦江大模型实战训练营——(十四)MindSearch 快速部署

最近在学习书生.浦江大模型实战训练营&#xff0c;所有课程都免费&#xff0c;以关卡的形式学习&#xff0c;也比较有意思&#xff0c;提供免费的算力实战&#xff0c;真的很不错&#xff08;无广&#xff09;&#xff01;欢迎大家一起学习&#xff0c;打开LLM探索大门&#xf…

达梦数据库兼容Quartz定时框架

1、背景 近期项目中需要使用达梦数据库&#xff0c;现将mysql数据库切换为达梦数据库&#xff0c;其中兼容Quartz定时框架报错如下&#xff1a; 2、解决方案 2.1 起初配置完&#xff1a;达梦数据库驱动直接启动项目直接报错&#xff0c; 后面在yml中配置数据库表名前缀&…

rac集群二几点重启ora.gipcd不能正常启动

集群起来后gipcd服务不能正常启动 检查gipcd日志&#xff1a; 2024-08-26 00:29:50.745: [GIPCXCPT][2] gipcPostF [gipcd_ExitCB : gipcd.c : 431]: EXCEPTION[ ret gipcretInvalidObject (3) ] failed to post obj 0000000000000000, flags 0x0 2024-08-26 00:29:50.745: […

企业培训APP开发指南:基于在线教育系统源码的实践

当下&#xff0c;基于在线教育系统源码开发企业培训APP成为了许多企业提高员工技能、优化培训流程的首选方案。 一、为什么选择基于在线教育系统源码开发企业培训APP&#xff1f; 1.定制化需求&#xff1a;每个企业的培训需求和目标都不尽相同&#xff0c;基于现有的在线教育…

一键安装最流畅的Win7系统家庭版!附详细安装教程

今日系统之家小编给大家带来运作最流畅的Win7系统家庭版&#xff0c;该版本系统经过精心优化&#xff0c;系统资源占用更少&#xff0c;运作变得更流畅。系统支持不同的安装方式&#xff0c;推荐用户使用硬盘一键安装方式&#xff0c;安装起来更简单&#xff0c;非常适合新手用…

汇川技术|Inoproshop软件菜单[工具、窗口、帮助]

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 其实对软件的学习就是看帮助加应用&#xff0c;根据帮助了解都有哪些功能&#xff0c;然后在应用中熟悉这些功能&#xff0c;随着应用的熟练&#xff0c;逐步总结出提升效率的技巧方法&#xff0c;从而逐步达到精通的…

探索 Go 语言中的数组和切片:深入理解顺序集合

在 Go 语言的丰富数据类型中&#xff0c;数组和切片是处理有序数据集合的强大工具&#xff0c;它们允许开发者以连续的内存块来存储和管理相同类型的多个元素。无论是在处理大量数据时的性能优化&#xff0c;还是在实现算法时对数据结构的需求&#xff0c;数组和切片都扮演着至…

无线领夹麦克风六大行业趋势揭秘:洞察市场风向谨防踩坑!

​近年来&#xff0c;无线领夹麦克风受到很多直播达人、视频创作者的推荐与青睐&#xff0c;作为一款实用便捷的音频设备&#xff0c;各个创作领域都广泛应用。如今无线领夹麦克风市场产品多样且品质各异&#xff0c;有些产品采用劣质材料&#xff0c;甚至存在信号不稳定等问题…

IP代理怎么测试网速:全面指南

在互联网时代&#xff0c;代理IP已经成为了很多人上网的重要工具。不管你是为了保护隐私&#xff0c;还是为了提高访问速度&#xff0c;代理IP都能提供很大的帮助。那么&#xff0c;如何测试代理IP的网速呢&#xff1f;今天我们就来聊聊这个话题。 什么是代理IP&#xff1f; 代…

SQL进阶技巧:如何按任意时段分析时间区间问题? | 分区间讨论【左、中、右】

目录 0 场景描述 1 数据准备 2 问题分析 方法1:分情况讨论,找出重叠区间 方法2:暴力美学法。按区间展开成日期明细表 3 拓展案例 4小结 0 场景描述 现有用户还款计划表 user_repayment ,该表内的一条数据,表示用户在指定日期区间内 [date_start, date_end] ,每天…

从零部件到汽车,Fortinet如何守护车主安全出行每一步

随着汽车产业蓬勃发展&#xff0c; 网络安全威胁也正在“紧盯”汽车全产业链。从制造、销售直至最终使用阶段&#xff0c;均面临着网络安全威胁的挑战&#xff1a;制造环节的软件与生产环境漏洞隐患、销售过程中数据泄露风险&#xff0c;以及使用阶段车载系统脆弱性和用户安全意…