zoukankan      html  css  js  c++  java
  • Elasticsearch 堆内存

    转载自:https://www.lbbniu.com/6148.html

    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
    

    设置方式二:
    通过环境变量设置。
    这可以通过注释掉jvm.options文件中的Xms和Xmx设置并通过ES_JAVA_OPTS设置这些值来完成:

    ES_JAVA_OPTS="-Xms2g -Xmx2g" ./bin/elasticsearch 
    ES_JAVA_OPTS="-Xms4000m -Xmx4000m" ./bin/elasticsearch
    

    4、堆内存的决定因素

    堆内存的值取决于服务器上可用的内存大小。
    5、堆内存配置建议

    将最小堆大小(Xms)和最大堆大小(Xmx)设置为彼此相等。
    
    Elasticsearch可用的堆越多,可用于缓存的内存就越多。但请注意,太多的堆内存可能会使您长时间垃圾收集暂停。
    
    将Xmx设置为不超过物理内存的50%,以确保有足够的物理内存留给内核文件系统缓存。
    
    不要将Xmx设置为JVM超过32GB。
    

    大小建议:宿主机内存大小的一半和31GB,取最小值。

    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、我是内存土豪怎么办?

    1假设,我有一台带有1TB RAM的机器!

    32 GB的基线相当重要。那么当你的机器有很多内存时你怎么做?当前具有512-768 GB RAM的超级服务器变得越来越普遍。

    首先,我们建议避免使用这种大型机器。

    但是如果你已经有了这些机器,你有三种实用的选择:

    1. 你是否主要进行全文搜索?

    考虑给Elasticsearch提供4-32 GB,并让Lucene通过操作系统文件系统缓存使用剩余的内存。所有内存都会缓存段,并导致快速全文搜索。

    1. 你在做很多排序/聚合?

    大部分聚合数字,日期,地理位置和not_analyzed字符串?你很幸运,你的聚合将在内存缓存的文档值上完成!

    从4-32 GB的内存中给Elasticsearch一个地方,剩下的让操作系统在内存中缓存doc值。

    1. 你是否对分析过的字符串进行了很多排序/聚合(例如对于字标记或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

    要永久禁用它,你可能需要编辑你的/etc/fstab

    方式二:控制操作系统尝试交换内存的积极性。

    如果完全禁用交换不是一种选择,您可以尝试降低swappiness。该值控制操作系统尝试交换内存的积极性。这可以防止在正常情况下交换,但仍然允许操作系统在紧急内存情况下进行交换。

    对于大多数Linux系统,这是使用sysctl值配置的:

    vm.swappiness = 1

    的swappiness优于0,因为在某些内核版本上,swappiness为0可以调用OOM杀手。

    方式三:mlockall允许JVM锁定其内存并防止其被操作系统交换。

    最后,如果两种方法都不可行,则应启用mlockall。文件。这允许JVM锁定其内存并防止其被操作系统交换。在你的elasticsearch.yml中,设置这个:

    bootstrap.mlockall:true

    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、小结

    这是一篇官网文档&原理的整合文章,主要目的是梳理认知。

    切记:宿主机内存大小的一半和31GB,取最小值。
    

    13、参考

    基础:http://t.cn/RH4DDYu
    
    设置:http://t.cn/RmKbO1i
    
    建议:http://t.cn/RmKbjsF
    
    注意:http://t.cn/RmKbHp5
    
    堆:http://t.cn/RmKbRji
  • 相关阅读:
    今天面试一些程序员(新,老)手的体会
    UVA 10635 Prince and Princess
    poj 2240 Arbitrage
    poj 2253 Frogger
    poj 2485 Highways
    UVA 11258 String Partition
    UVA 11151 Longest Palindrome
    poj 1125 Stockbroker Grapevine
    poj 1789 Truck History
    poj 3259 Wormholes
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/12095809.html
Copyright © 2011-2022 走看看