Elasticsearch-内存结构

ElasticSearch的内存从大的结构可以分堆内存(On Heap)和堆外内存(Off Heap)。Off Heap部分由Lucene进行管理。On Heap部分存在可GC部分和不可GC部分,可GC部分通过GC回收垃圾对象,从而释放内存。不可GC部分不能通过GC回收垃圾对象,这部分会通过LRU算法进行对象清除并释放内存。更加具体的内存占用与分配如下图:

查看和删除缓存

cat nodes API | Elasticsearch Guide [8.12] | Elastic

Nodes stats API | Elasticsearch Guide [8.12] | Elastic

查看cache情况:
GET /_stats/query_cache?pretty&human
GET _cat/nodes?help 查看node参数
GET _cat/nodes?v&h=id,queryCacheMemory,queryCacheEvictions,requestCacheMemory,requestCacheHitCount,requestCacheMissCount,flushTotal,flushTotalTime清理节点查询缓存:
POST /twitter/_cache/clear?query=true清理 request 请求缓存:
POST /twitter/_cache/clear?request=true清理 field data 缓存:
POST /twitter/_cache/clear?fielddata=true 指定索引twitter和kimchy清理缓存:
POST /kimchy,twitter/_cache/clear清理全部的缓存: 
POST /_cache/clear

On Heap内存

这部分内存占用的模块包括:Indexing Buffer、Node Query Cache、Shard Request Cache、Field Data Cache以及Segments Cache。

Indexing Buffer 

索引写入缓冲区,用于存储新写入的文档,当其被填满时,缓冲区中的文档被refresh到 OS中的 segments 中。这部分空间是可GC被反复利用的。节点上所有 shard 共享indexing buffer。

indices.memory.index_buffer_size:10% # 占总内存比例或绝对值,默认10%
indices.memory.min_index_buffer_size:48M # 最小index buffer内存, 默认48M
indices.memory.max_index_buffer_size:自定义 # 最大index buffer内存, 无默认值

参考: Indexing buffer settings | Elasticsearch Guide [8.12] | Elastic

Node Query Cache (Filter Cache)

节点级别的缓存,节点上的所有分片共享此缓存,是Lucene层面的实现。缓存的是某个filter子查询语句在一个segment上的查询结果。如果一个segment缓存了某个filter子查询的结果,下次可以直接从缓存获取结果,无需再在segment内进行过滤查询。

每个segment有自己的缓存,缓存的key为filter子查询(query clause ),缓存内容为查询结果,这些查询结果是匹配到的document numbers,保存在位图FixedBitSet中。

缓存的构建过程是:对segment执行filter子查询,先获取查询结果中最大的 document number: maxDoc(document number是lucene为每个doc分配的数值编号,fetch的时候也是根据这个编号获取文档内容)。然后创建一个大小为 maxDoc的位图:FixedBitSet,遍历查询命中的doc,将FixedBitSet中对应的bit设置为1。

例如:查询结果的maxDoc是8,那么创建出的FixedBitSet就是:[0,0,0,0,0,0,0,0],可以理解为是一个长度为8的二值数组,初始值都是0,假设filter查询结果的doc列表是:[1,4,8],那么FixedBigSet就设置为:
[1,0,0,1,0,0,0,1],当查询有多个filter子查询时,对位图做交并集位运算即可。

用一个例子来说明Node Query Cache结构。如下图查询语句包含两个子查询,分别是对date和age字段的range查询,Lucene在查询过程中遍历每个 segment,检查其各自的LRUQueryCache能否命中filter子查询,segment 8命中了对age和date两个字段的缓存,将会直接返回结果。segment 2只命中了对age字段的缓存,没有命中date字段缓存,将继续执行查询过程。

image.png

缓存设置

Node query cache settings | Elasticsearch Guide [8.12] | Elastic

indices.queries.cache.count  #默认 10000, 最多缓存 10000个子查询的结果(LRU 的大小)
indices.queries.cache.size   #默认 10%, 最多使用堆内存的10%
index.queries.cache.enabled  是否启用query cache, true/false
indices.queries.cache.all_segments 默认是false, 用于是否在所有 Segment上启用缓存,

总结:

1)只有Filter下的子Query才能参与Cache。
2)不能参与Cache的Query有TermQuery/MatchAllDocsQuery/MatchNoDocsQuery/BooleanQuery/DisjunnctionMaxQuery。
3)MultiTermQuery/MultiTermQueryConstantScoreWrapper/TermInSetQuery/Point*Query的Query查询超过2次会被Cache,其它Query要5次。
4)默认每个段大于10000个doc或每个段的doc数大于总doc数的30%时才允许参与cache。
5)结果集比较大的Query在Cache时尽量增加使用周期以免频繁Cache构建DocIdset。
6)Segment被合并或者删除,那么也会清理掉对应的缓存。

Shard Request Cache

Shard Request Cache简称Request Cache,他是分片级别的查询缓存,每个分片有自己的缓存,属于ES层面的实现。ES默认情况下最多使用堆内存的1%用作 Request Cache,这是一个节点级别的配置。内存的管理使用LRU算法。

Request Cache的主要作用是对聚合的缓存,聚合过程是实时计算,通常会消耗很多资源,缓存对聚合来说意义重大。

由于客户端请求信息直接序列化为二进制作为缓存key的一部分,所以客户端请求的json顺序,聚合名称等变化都会导致cache无法命中。

缓存时机: size=0的hits.total, aggregations, and suggestions

失效或回收:

  • 新的segment写入到分片后,缓存会失效,因为之前的缓存结果已经无法代表整个分片的查询结果。
  • now等时间函数不会缓存

缓存配置

Shard request cache settings | Elasticsearch Guide [8.12] | Elastic

index.requests.cache.enable: true/fase request cache开关
indices.requests.cache.size: 1%  request cache占总堆百分比,默认1%

Field Data Cache

默认Elasticsearch2.0 开始,在非 text 字段开启 doc_values,基于 doc_values 做排序和聚合,可以减少对FielddataCache的依赖,减少内存消耗,减少节点 OOM 的概率,由于doc_values的特性性能上也不会有多少损失,doc_value是一种正向索引结构以顺序预读的方式进行获取,所以随机获取就很慢了。

Elasticsearch(后面简称ES)除了强大的搜索功能外,还可以支持排序,聚合之类的操作。搜索需要用到倒排索引,而排序和聚合则需要使用 “正排索引”。说白了就是一句话,倒排索引的优势在于查找包含某个项的文档,而反过来确定哪些项在单个文档里并不高效。

doc_values和fielddata就是用来给文档建立正排索引的。他俩一个很显著的区别是,前者的工作地盘主要在磁盘,而后者的工作地盘在内存。

5.0 开始,text 字段默认关闭了 Fielddata 功能, Fielddata Cache 应当只用于 global ordinals。

Fielddata Cache大家做了解吧,使用它的也非常的少了,基本可以用doc_value代替了,doc_value使用不需要全部载入内存

image.png

缓存配置

Field data cache settings | Elasticsearch Guide [8.12] | Elastic

indices.fielddata.cache.size  38%/12G 设置fielddata cache大小,默认没有限制
indices.breaker.fielddata.limit fielddata熔断器,默认值堆的40%

失效或回收:segment 被合并后失效

Segment Cache(Segment FST Cache)

一个segment是一个完备的lucene倒排索引,倒排索引是通过词典 (Term Dictionary)到文档列表(Postings List)的映射关系实现快速查询的。由于词典和文档的数据量比较大,全部装载到heap里不现实,所以存储在硬盘上的。

为了快速定位一个词语在词典中的位置。Lucene为词典(Term Dictionary)做了一层词典索引(Term Index)。这个词典索引采用的数据结构是FST (Finite State Transducer)。Lucene在打开索引的时候将词典索引(Term Index)全量装载到内存中,即:Segment FST Cache,这部分数据永驻堆内内存,且无法设置大小,长期占用50% ~ 70%的堆内存。内存管理使用LRU算法。

源生逻辑是怎样访问 FST 的:

  • 数据写入:ES 的一次 Refresh / Merge 动作,会生成一个新的 Lucene Segment,相应的在磁盘上生成该 Segment 对应的各种数据文件。其中 .tip 文件里面存储的就是该 Segment 各个字段的 FST 信息。在生成 .tip 文件后,Lucene 也会将每个字段( Field )的 FST 数据解析后,拷贝至该 Field 在 OnHeap 内存中的对象里,作为一个成员变量永驻内存,直到该 Segment 被删除 ( Index 被删除、Segment Merge 时 )。

  • 数据查询:查询时,直接访问 OnHeap 的 FST 。

内存回收与释放:
1.删除不用的索引
2.关闭索引(文件仍然存在于磁盘,只是释放掉内存),需要的时候可重新打开。
3.定期对不再更新的索引做force merge。实质是对segment file强制做合并,segment数量的减少可以节省大量的Segment Cache的内存占用。

Off Heap内存

Segments Memory

Lucene中的倒排索引以段文件(segment file)的形式存储在磁盘上,为了提高倒排索引的加载与检索速度,避免磁盘IO访问导致的性能损耗,Lucene会把倒排索引数据加载到磁盘缓存(操作系统一般会用系统内存来实现磁盘缓存),所以在进行内存分配的时候,需要考虑到这部分内存,一般建议是把50%的内存给Elasticsearch,剩下的50%留给Lucene。

熔断器

Circuit breaker settings | Elasticsearch Guide [8.12] | Elastic

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW高精度微小电容测量

LabVIEW高精度微小电容测量 在电子工程和科研领域,精确测量微小电容值是一项有一定要求的任务,尤其在涉及到高精度和低成本时。设计了一种基于LabVIEW高精度微小电容测量系统,旨在提供一个既经济又高效的解决方案。 该系统的核心在于使用FD…

【代码随想录24】93.复原 IP 地址 78.子集 90.子集II

目录 93.复原IP地址题目描述参考代码 78.子集题目描述参考代码 90.子集II题目描述参考代码 93.复原IP地址 题目描述 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 . 分隔。 例如…

爬虫工作量由小到大的思维转变---<第四十五章 Scrapyd 关于gerapy遇到问题>

前言: 本章主要是解决一些gerapy遇到的问题,会持续更新这篇! 正文: 问题1: 1400 - build.py - gerapy.server.core.build - 78 - build - error occurred (1, [E:\\项目文件名\\venv\\Scripts\\python.exe, setup.py, clean, -a, bdist_uberegg, -d, C:\\Users\\Administrat…

vue3:24—组件通信方式

目录 1、props 2、自定义事件 (emit) 3、mitt(任意组件的通讯) 4、v-model【封装ui组件库用的多,平时用的少。和vue2有点不同】 5、$attrs 6、$refs和$parent 7、provide和inject 8、pinia(即vue2中…

OpenGL 入门(九)—Material(材质)和 光照贴图

文章目录 材质设置材质光的属性脚本实现 光照贴图漫反射贴图高光反射贴图 材质 材质本质是一个数据集,主要功能就是给渲染器提供数据和光照算法。 如果我们想要在OpenGL中模拟多种类型的物体,我们必须针对每种表面定义不同的材质(Material)属性。 我们…

04、全文检索 -- Solr -- 管理 Solr 的 core(使用命令和图形界面创建、删除 core,以及对core 目录下的各文件进行详细介绍)

目录 管理 Solr 的 core创建 Core方式1:solr 命令创建演示:使用 solr 命令创建 Core:演示:命令删除 Core(彻底删除) 方式2:图形界面创建Web控制台创建CoreWeb控制台删除 Core(未彻底…

代驾应用系统(ssm)

登录首页 管理员界面 代驾司机界面 普通用户界面 前台页面 1、系统说明 (1) 框架:spring、springmvc、mybatis、mysql、jsp (2) 系统分为前台系统、后端管理系统 2、欢迎留言联系交流学习讨论:qq 97820625…

高灵敏比色法IgG2a (mouse) ELISA kit

用于检测IgG2a(小鼠)的高灵敏度ELISA试剂盒,仅需90分钟即可得到实验结果 免疫球蛋白G(IgG)是一种免疫球蛋白单体,由两条(γ)重链和两条轻链组成。每个IgG分子包含两个抗原结合域和一…

前端基础复习(后端人员看前端知识)

企业级前端项目开发中,需要将前端开发所需要的工具、技术、流程、经验进行规范化和标准化,而不是零散的html、js、css文件堆叠在一起。 首先我们需配置前端的开发基础环境NodeJS,相当于后端人员java开发的JDK。然后搭建前端工程脚手架Vue-cl…

回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)

回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制) 目录 回归预测 | Matlab实现CPO-CNN-LSTM-Attention冠豪猪优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注…

Open3D 深度图像转点云

目录 一、算法原理1、算法过程2、主要函数3、算法源码二、代码实现三、结果展示1、深度图像2、点云四、测试数据

20240202在WIN10下使用whisper.cpp

20240202在WIN10下使用whisper.cpp 2024/2/2 14:15 【结论:在Windows10下,确认large模式识别7分钟中文视频,需要83.7284 seconds,需要大概1.5分钟!效率太差!】 83.7284/4200.1993533333333333333333333333…

Android Studio从零基础到APP上线(3)

第3章 简单控件 本章介绍App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图,容纳视图的常用布局,响应点击的按钮控件,显示图片的图像视图等。然后结合本章所学的知识,演示一个实战项目“简单计算器”的设计与实现。 3.1 文本显示 本节介绍如何在文本视图Tex…

【优先级队列(大顶堆 小顶堆)】【遍历哈希表键值对】Leetcode 347 前K个高频元素

【优先级队列(大顶堆 小顶堆)】【排序】Leetcode 347 前K个高频元素 1.不同排序法归纳2.大顶堆和小顶堆3.PriorityQueue操作4.PriorityQueue的升序(默认)与降序5.问题解决:找前K个最大的元素 :踢走最小的&…

Java多态原理

参考 虚方法 JVM杂记:对多态实现原理、虚方法表、虚方法、静态解析、动态链接的一些思考_多态和方法表的关系-CSDN博客 静态分派与动态分派 (JVM)Java虚拟机:静态分派 & 动态分派 原理解析 - 掘金 虚方法表 JVM 栈帧&am…

【C++】类和对象(3)

继续学习类和对象的最后一部分知识,主要有初始化列表、static成员、友元、内部类、匿名对象等。 目录 再谈构造函数 构造函数体赋值 初始化列表 explicit关键字 static成员 概念 特性 友元 友元函数 友元类 内部类 匿名对象 拷贝对象时的一些编译器优化…

跨境电商新风潮:充分发挥海外云手机的威力

在互联网行业迅速发展的大环境下,跨境电商、海外社交媒体营销以及游戏产业等重要领域都越来越需要借助海外云手机的协助。 特别是在蓬勃发展的跨境电商领域,像亚马逊、速卖通、eBay等平台,结合社交电商营销和短视频内容成为最有效的流量来源。…

2024-2-6-复习作业

1> 要求&#xff1a; 源代码&#xff1a; #include <stdio.h> #include <stdlib.h> void output(int arr[],int len) {for(int i0;i<len;i){printf("%d ",arr[i]);}puts(""); } void bubble_sort(int arr[],int len) {for(int i1;i<…

【Linux Day15 TCP网络通讯】

TCP网络通讯 TCP编程流程 接口介绍 socket()方法是用来创建一个套接字&#xff0c;有了套接字就可以通过网络进行数据的收发。创建套接字时要指定使用的服务类型&#xff0c;使用 TCP 协议选择流式服务&#xff08;SOCK_STREAM&#xff09;。 **bind()方法是用来指定套接字使…

JavaScript基础第二天

JavaScript基础第二天 今天我们学习if分支语句、三元表达式和switch-case语句。 1. if分支语句 1.1 语法 if (条件表达式){// 满足条件要执行的语句 } else {// 不满足条件要执行的语句 }if中的内容如果为true&#xff0c;就执行大括号的代码块&#xff0c;如果为false执行…