关于ElasticSearch的堆内存设置与优化
1、什么是堆内存?
Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。
在 Java 中,堆被划分成两个不同的区域:
- 新生代 ( Young )、
- 老年代 ( Old )。
新生代 ( Young ) 又被划分为三个区域
:
- Eden、
- From Survivor、
- To Survivor。
这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。
2、堆内存的作用是什么?
在虚拟机启动时创建。
堆内存的唯一目的就是创建对象实例,所有的对象实例和数组都要在堆上分配。
堆是由垃圾回收来负责的,因此也叫做“GC堆”,垃圾回收采用分代算法,堆由此分为新生代和老年代。
堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。
但缺点是,由于要在运行时动态分配内存,存取速度较慢。当堆内存因为满了无法扩展时就会抛出java.lang.OutOfMemoryError:Java heap space异常。出现这种情况的解决办法具体参见java调优。
3、堆内存如何配置?
默认情况下,Elasticsearch JVM使用堆内存最小和最大大小为2 GB(5.X版本以上)。
早期版本默认1GB,官网指出:这明显不够。
在转移到生产环境时,配置足够容量的堆大小以确保Elasticsearch功能和性能是必要的。
Elasticsearch将通过Xms(最小堆大小)和Xmx(最大堆大小)设置来分配jvm.options中指定的整个堆。
举例如下:
设置方式一:
在jvm.option配置文件中设置堆内存。
-Xms2g
-Xmx2g
1
2
设置方式二:
通过环境变量设置。
这可以通过注释掉jvm.options文件中的Xms和Xmx设置并通过ES_JAVA_OPTS设置这些值来完成:
ES_JAVA_OPTS="-Xms2g -Xmx2g" ./bin/elasticsearch
ES_JAVA_OPTS="-Xms4000m -Xmx4000m" ./bin/elasticsearch
1
2
4、堆内存的决定因素
堆内存的值取决于服务器上可用的内存大小。
5、堆内存配置建议
将最小堆大小(Xms)和最大堆大小(Xmx)设置为彼此相等。
Elasticsearch可用的堆越多,可用于缓存的内存就越多。但请注意,太多的堆内存可能会使您长时间垃圾收集暂停。
将Xmx设置为不超过物理内存的50%,以确保有足够的物理内存留给内核文件系统缓存。
- 不要将Xmx设置为JVM超过32GB。
大小建议:
宿主机内存大小的一半和31GB,取最小值。
1
2
6、堆内存为什么不能超过物理机内存的一半?
堆对于Elasticsearch绝对重要。
它被许多内存数据结构用来提供快速操作。但还有另外一个非常重要的内存使用者:Lucene。
Lucene旨在利用底层操作系统来缓存内存中的数据结构。 Lucene段(segment)存储在单个文件中。因为段是一成不变的,所以这些文件永远不会改变。这使得它们非常容易缓存,并且底层操作系统将愉快地将热段(hot segments)保留在内存中以便更快地访问。这些段包括倒排索引(用于全文搜索)和文档值(用于聚合)。
Lucene的性能依赖于与操作系统的这种交互。但是如果你把所有可用的内存都给了Elasticsearch的堆,那么Lucene就不会有任何剩余的内存。这会严重影响性能。
标准建议是将可用内存的50%提供给Elasticsearch堆,而将其他50%空闲。它不会被闲置; Lucene会高兴地吞噬掉剩下的东西。
如果您不字符串字段上做聚合操作(例如,您不需要fielddata),则可以考虑进一步降低堆。堆越小,您可以从Elasticsearch(更快的GC)和Lucene(更多内存缓存)中获得更好的性能。
7、堆内存为什么不能超过32GB?
在Java中,所有对象都分配在堆上并由指针引用。普通的对象指针(OOP)指向这些对象,传统上它们是CPU本地字的大小:32位或64位,取决于处理器。
对于32位系统,这意味着最大堆大小为4 GB。对于64位系统,堆大小可能会变得更大,但是64位指针的开销意味着仅仅因为指针较大而存在更多的浪费空间。并且比浪费的空间更糟糕,当在主存储器和各种缓存(LLC,L1等等)之间移动值时,较大的指针消耗更多的带宽。
Java使用称为压缩oops的技巧来解决这个问题。而不是指向内存中的确切字节位置,指针引用对象偏移量。这意味着一个32位指针可以引用40亿个对象,而不是40亿个字节。最终,这意味着堆可以增长到约32 GB的物理尺寸,同时仍然使用32位指针。
一旦你穿越了这个神奇的〜32 GB的边界,指针就会切换回普通的对象指针。每个指针的大小增加,使用更多的CPU内存带宽,并且实际上会丢失内存。实际上,在使用压缩oops获得32 GB以下堆的相同有效内存之前,需要大约40-50 GB的分配堆。
以上小结为:即使你有足够的内存空间,尽量避免跨越32GB的堆边界。
否则会导致浪费了内存,降低了CPU的性能,并使GC在大堆中挣扎。
8、我是内存土豪怎么办?
假设,我有一台带有1TB RAM的机器!
1
32 GB的基线相当重要。那么当你的机器有很多内存时你怎么做?当前具有512-768 GB RAM的超级服务器变得越来越普遍。
首先,我们建议避免使用这种大型机器。
但是如果你已经有了这些机器,你有三种实用的选择:
1. 你是否主要进行全文搜索?
考虑给Elasticsearch提供4-32 GB,并让Lucene通过操作系统文件系统缓存使用剩余的内存。所有内存都会缓存段,并导致快速全文搜索。
2. 你在做很多排序/聚合?
大部分聚合数字,日期,地理位置和not_analyzed字符串?你很幸运,你的聚合将在内存缓存的文档值上完成!
从4-32 GB的内存中给Elasticsearch一个地方,剩下的让操作系统在内存中缓存doc值。
3. 你是否对分析过的字符串进行了很多排序/聚合(例如对于字标记或SigTerms等)?
不幸的是,这意味着你需要fielddata,这意味着你需要堆空间。
考虑在一台机器上运行两个或多个节点,而不是一个节点数量巨大的RAM。
尽管如此,仍然坚持50%的规则。
To土豪内存小结:
因此,如果您的机器具有128 GB的RAM,请运行两个节点,每个节点的容量低于32 GB。这意味着小于64 GB将用于堆,而Lucene将剩余64 GB以上。
如果您选择此选项,请在您的配置中设置cluster.routing.allocation.same_shard.host:true。这将阻止主副本分片共享同一台物理机(因为这会消除副本高可用性的好处)。
9、堆内存优化建议
方式一:最好的办法是在系统上完全禁用交。
这可以暂时完成:
sudo swapoff -a
1
要永久禁用它,你可能需要编辑你的/ etc / fstab。
方式二:控制操作系统尝试交换内存的积极性。
如果完全禁用交换不是一种选择,您可以尝试降低swappiness。该值控制操作系统尝试交换内存的积极性。这可以防止在正常情况下交换,但仍然允许操作系统在紧急内存情况下进行交换。
对于大多数Linux系统,这是使用sysctl值配置的:
vm.swappiness = 1
1
1的swappiness优于0,因为在某些内核版本上,swappiness为0可以调用OOM杀手。
方式三:mlockall允许JVM锁定其内存并防止其被操作系统交换。
最后,如果两种方法都不可行,则应启用mlockall。文件。这允许JVM锁定其内存并防止其被操作系统交换。在你的elasticsearch.yml中,设置这个:
bootstrap.mlockall:true
1
10、注意
修改JVM相关配置很容易,但容易产生难以测量的不透明效果,并最终将您的群集解调为缓慢,不稳定的混乱
在调试群集时,第一步通常是删除所有自定义配置。大约一半的时间,仅靠这一点就恢复了稳定性和性能。
11、最新认知
wood@Ctrip
事实上,给ES分配的内存有一个魔法上限值26GB,
这样可以确保启用zero based Compressed Oops,这样性能才是最佳的。
参考:https://elasticsearch.cn/question/3995
https://www.elastic.co/blog/a-heap-of-trouble
12、小结
这是一篇官网文档&原理的整合文章,主要目的是梳理认知。
13、参考
基础:http://t.cn/RH4DDYu
设置:http://t.cn/RmKbO1i
建议:http://t.cn/RmKbjsF
注意:http://t.cn/RmKbHp5
堆:http://t.cn/RmKbRji
————————————————
版权声明:本文为CSDN博主「铭毅天下」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/laoyang360/article/details/79998974
关于ElasticSearch的堆内存设置与优化的更多相关文章
- 【转】JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM堆内存设置
今天碰到了一个题目,讲的是关于堆内存的问题,题目如下 下面哪种情况会导致持久区jvm堆内存溢出? A.循环上万次的字符串处理 B.在一段代码内申请上百M甚至上G的内存 C.使用CGLib技术直接操 ...
- Java堆内存设置
转自:https://blog.csdn.net/Qiuzhongweiwei/article/details/81023645 堆内存设置 原理 JVM堆内存分为2块:永久空间和堆空间. 永久即持久 ...
- [转]JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM 堆内存设置原理
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM 堆内存设置原理(转)
堆内存设置 原理 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...
- JVM堆内存设置和测试
1. Java虚拟机内存结构 划分新生代和老年代,这样只在新生代分配内存,从而简化了新对象的分配.另外新生代和老年代使用不同的GC算法,可以更有效的清除不再需要的对象.从上图可以看出,JVM内存由yo ...
- Java中的堆内存设置对线程创建数的影响以及-Xss参数的记录
Java的线程对象是存储在堆上的,所以,能够创建多少个线程,受到堆空间的大小限制,同时也受到每个线程的大小的限制,假如线程对象内部有一个非常大的数组字段,那就非常影响能够创建的线程的大小 我们的例子: ...
- JVM 堆内存,参数优化
Java堆内存 http://www.importnew.com/19593.html JVM诊断之查看运行参数 JVM 垃圾回收器工作原理及使用实例介绍 https://www.ibm.com/de ...
随机推荐
- 使用adb连接Mumu模拟器
1)下载Mumu模拟器 2)运行Mumu模拟器 3)找到mumu安装目录下的MuMu\emulator\nemu\vmonitor\bin目录 4)在当前目录打开cmd,执行 adb connect ...
- bzoj5461 Minimax 题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5461 看到题目,必将m种权值离散化. 首先是一个显然的dp设计. 设$f(i,j)$表示第i个节点 ...
- 深度学习中loss总结
一.分类损失 1.交叉熵损失函数 公式: 交叉熵的原理 交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近.假设概率分布p为期望输出,概率分布q为实际输 ...
- template cannot be keyed. Place the key on real elements instead.
template cannot be keyed. Place the key on real elements instead. 一.总结 一句话总结: 原因:vue不支持在 template 元素 ...
- Linux下的IO监控与分析(转)
各种IO监视工具在Linux IO 体系结构中的位置 源自 Linux Performance and Tuning Guidelines.pdf 1 系统级IO监控 iostat iostat -x ...
- vmware vsphere各版本差别,及各套件差别
最近要开始全面支持虚拟化了,客户私有云环境用的多的为vmware vsphere,特地恶补下vmware vsphere的各个差别. 首先是vSphere,ESXi和vCenter 的区别. ESXi ...
- TX-LCN5.0.2分布式事务框架源码分析-关键线索罗列-txc部分
1.注解TxcTransaction2.在其注解接口附近查找aop配置:TransactionAspect3.runTransaction是在执行事务业务代码时的包装逻辑4.transactionSe ...
- 转:goproxy和go modules的初步使用
转:https://blog.csdn.net/qq_42403866/article/details/93654421 go module 管理比较方便. 启用: export GO111MODUL ...
- Deepin系统中手动开启swap的方法
Deepin系统中手动开启swap的方法 如何设置 swap(交换空间)的大小建议设置和你的实际物理内存一样大,如你的内存是8G的,则可将下面的count的值设为8192(当然这只是参考值,你可根据你 ...
- 946. Validate Stack Sequences
946. Validate Stack Sequences class Solution { public: bool validateStackSequences(vector<int> ...