Elasticsearch-内存结构

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

查看和删除缓存

查看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(详细参考这里) 。可以参考TRIE树进行理解。FST在时间复杂度和空间复杂度上都做了最大程度的优化,使得Lucene能够将Term Dictionary(词典)完全加载到内存,快速的定位Term找到响应的output(posting倒排列表)。

内存回收与释放:
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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【项目日记(七)】第三层: 页缓存的具体实现(上)

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:项目日记-高并发内存池⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你做项目   🔝🔝 开发环境: Visual Studio 2022 项目日…

three.js CSS3DRenderer、CSS3DObject渲染HTML标签

有空的老铁关注一下我的抖音&#xff1a; 效果&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red;position: relative;"><…

react 之 useInperativeHandle

useInperativeHandle是通过ref暴露子组件中的方法 1.场景说明-直接调用子组件内部的方法 import { forwardRef, useImperativeHandle, useRef } from "react"// 子组件const Son forwardRef((props, ref) > {// 实现聚焦逻辑const inputRef useRef(null)const …

【知识点】Java常用

文章目录 基础基础数据类型内部类Java IOIO多路复用重要概念 Channel **通道**重要概念 Buffer **数据缓存区**重要概念 Selector **选择器** 关键字final 元注解常用接口异常处理ErrorException JVM与虚拟机JVM内存模型本地方法栈虚拟机栈 Stack堆 Heap方法区 Method Area (JD…

npm安装报错,出现.staging

问题场景&#xff1a;同事发了一个本地的安装包&#xff0c;拿到了没仔细看&#xff0c;直接npm install&#xff0c;没有发现根目录下的package-lock.json。然后就发现安装一直不成功&#xff0c;还会卡主。并且在node_modules文件夹下还会出现.staging文件夹&#xff0c;正常…

计算机网络实验六

目录 实验6 静态路由与RIP协议配置 1、实验目的 2、实验设备 &#xff08;1&#xff09;内容一&#xff1a;&#xff08;静态路由配置&#xff09; &#xff08;2&#xff09;内容二&#xff1a;&#xff08;RIP协议配置&#xff09; 3、网络拓扑及IP地址分配 &#xff…

3593 蓝桥杯 查找最大元素 简单

3593 蓝桥杯 查找最大元素 简单 // C风格解法1&#xff0c;通过率100%&#xff0c;多组数据处理样式//str "abcdefgfedcba" //abcdefg(max)fedcba//str "xxxxx" //x(max)x(max)x(max)x(max)x(max)#include<bits/stdc.h>const int N 1e2 10;char …

无法在 word 中登录 Grammarly

目录 1. 情况描述 2. 解决方法 3. 原因分析 1. 情况描述 在浏览器中可以登录 Grammarly&#xff0c;但是在 word 中登录失败&#xff0c;大致如下图所示&#xff1a; 我自己没有截图&#xff0c;这是网上别人的图&#xff0c;但差不多都长这个样子。 2. 解决方法 我点击了…

量化交易学习4(投资组合基本认识)

1 如何衡量投资组合的收益率 1.1 投资组合收益率的计算方法 1.2 投资组合的绝对收益率和相对收益率 2 如何衡量投资组合的风险 2.1 风险的定义 风险是指在未来可能发生的不确定性事件所带来的潜在损失。 在投资领域中&#xff0c;风险通常指投资所面临的不确定性和潜在的损失…

react native错误记录

第一次运行到安卓失败 Could not find implementation class com.facebook.react.ReactRootProjectPlugin for plugin com.facebook.react.rootproject specified in jar:file:/D:/Android_Studio_Data/.gradle/caches/jars-9/o_3a1fd35320f05989063e7069031b710f/react-nativ…

钉钉群机器人-发送群消息

1、钉钉群创建机器人 添加完成后&#xff0c;要记住 Webhook 路径&#xff1b; 2、机器人接入文档网址 自定义机器人接入 - 钉钉开放平台 3、JAVA代码 import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.re…

JVM工作原理与实战(三十二):GC调优

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、GC调优 二、GC调优的核心指标 总结 前言 JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字节码&#xff0c;管理内存&#xff0c;确保安全&#xff0c;支持多线程和提供…

idea 中 tomcat 乱码问题修复

之前是修改 Tomcat 目录下 conf/logging.properties 的配置&#xff0c;将 UTF-8 修改为 GBK&#xff0c;现在发现不用这样修改了。只需要修改 IDEA 中 Tomcat 的配置就可以了。 修改IDEA中Tomcat的配置&#xff1a;添加-Dfile.encodingUTF-8 本文结束

网络协议与攻击模拟_13缓存DNS与DNS报文

一、缓存DNS服务器 1、引入缓存DNS 工作可能会遇到这样的场景&#xff0c;内网部署有一台缓存DNS服务器&#xff0c;这台服务器是由我们自己搭建的。为什么放在内网呢&#xff1f;因为我内网中的机器请求内网返回会比较快。第一次会慢点&#xff0c;因为有一个转发的过程&am…

arcgis javascript api4.x加载非公开或者私有的arcgis地图服务

需求&#xff1a; 加载arcgis没有公开或者私有的地图服务&#xff0c;同时还想实现加载时不弹出登录窗口 提示&#xff1a;​ 下述是针对独立的arcgis server&#xff0c;没有portal的应用场景&#xff1b; 如果有portal可以参考链接&#xff1a;https://mp.weixin.qq.com/s/W…

供应商规模成倍增长,医疗器械制造商如何让采购效率更进一步|创新场景50...

ITValue 随着企业的快速发展&#xff0c;采购供应链网络日益庞大&#xff0c;企业在供应商管理上面临着管理体系分散、风险难以管控&#xff0c;采购过程环节多等问题&#xff0c;供应商内外协同亟待解决。 作者&#xff5c;秦聪慧 专题&#xff5c;创新场景50 ITValue 制造企业…

SpringMVC处理ajax请求之@ResponseBody注解,将后端数据响应到浏览器

上一篇文章讲到SpringMVC处理ajax请求用到的RequestBody注解SpringMVC处理ajax请求&#xff08;RequestBody注解&#xff09;&#xff0c;ajax向后端传递的数据格式详解-CSDN博客&#xff0c;这个注解帮我们解决了如何将客户端的数据通过json数据传递到服务器&#xff0c;简单说…

SpringCloud-搭建Eureka服务模块

在构建分布式微服务体系中&#xff0c;搭建Eureka服务模块是实现服务注册与发现的关键一步。Spring Cloud作为领先的微服务框架&#xff0c;通过Eureka为我们提供了高效的服务治理能力。本文将深入探讨如何使用Spring Cloud&#xff0c;逐步引导读者完成Eureka服务模块的搭建。…

docker手动迁移镜像

1&#xff0c;将镜像保存在本地 docker save 镜像名称:版本号 > 镜像名称.tar 2&#xff0c;下载镜像 通过 ftp 工具或者命令&#xff0c;下载到本地 3&#xff0c;上传镜像到目标 docker 所在服务器 4&#xff0c;导入镜像 docker load < 镜像名称.tar

SpringCloud微服务入门

文章目录 SpringCloud组件有哪些SpringCloud中服务注册和发现是什么意思&#xff1f;如何实现nacos和eureka的区别 负载均衡是如何实现的Ribbon的负载均衡策略有哪些如何自定义负载均衡策略 什么是服务雪崩&#xff0c;怎么解决这个问题微服务是如何监控的项目中有没有做限流&a…