Elasticsearch的堆内存该设置多大,为什么?

Elasticsearch的堆内存该设置多大,为什么?,第1张

文档摘录来自ES大佬 铭毅天下

宿主机内存的一半和31GB,两个值中,取最小值。

Java中的堆是JVM所管理的最大的一块内存空间,主要用于存放各种类的实例对象。在Java中,堆被划分成两个不同的区域:新生代(Young)、老年代(Old)。

新生代(Young)又被划分为三个区域:Eden、From Survivor、To Survivor。

这样划分的目的是为了使JVM能够更好的管理堆内存中的对象,包括内存的分片以及回收。

在虚拟机启动时创建。

堆内存的 唯一目的就是创建对象实例 ,所有的对象实例和数组都要在堆上分配。

堆是由垃圾回收来负责的,因此也叫做"GC堆",垃圾回收采用分代算法,堆由此分为新生代和老生代。

堆的优势是可以动态地分配内存大小 ,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。

缺点 是,由于要在运行时动态分配内存,存取速度较慢。当堆内存因为满了无法扩展的时候就会抛出java.lang.OutOfMemoryError:Java heap space异常。出现这种情况的解决办法具体参见java调优。

默认情况下,ES JVM使用堆内存最小和最大大小为2GB(5.X版本以上)。

早期版本默认1GB,官网指出:这明显不够。

在转移到生产环境时,配置足够容量的堆大小以确保ES功能和性能是必要的。

ES将通过Xms(最小堆大小)和Xmx(最大堆大小)设置来分配jvm.options中指定的整个堆。

堆内存对于ES绝对重要。它被许多内存数据结构用来提供快速 *** 作。但还有另外一个非常重要的内存使用者:Lucene.

Lucene旨在利用底层 *** 作系统来缓存内存中的数据结构。Lucene段(segment)存储在单个文件中。因为段是一成不变的,所以这些文件永远不会改变。这使得它们非常容易缓存,并且底层 *** 作系统将愉快地将热段(hot segments)保留在内存中以便更快地访问。这些段包括倒排索引(用于全文搜索)和文档值(用于聚合)。

Lucene的性能依赖于与 *** 作系统的这种交互。 但是如果我们把所有可用的内存都给了ES的堆内存,那么Lucene就不会有任何剩余的内存 。这会严重影响性能。

标准建议是将可用内存的50%提供给ES堆,而将其他50%空闲。它不会被闲置,Lucene会高兴地吞噬掉剩下的东西。

如果我们不需要在字段上做聚合 *** 作(例如,我们不需要fielddata),则可以考虑进一步降低堆。堆越小,我们可以从ES(更快的GC)和Lucene(更多内存缓存)中获得更好的性能。

在Java中,所有对象都分配在堆上并由指针引用。普通的对象指针(OOP)指向这些对象,传统上它们是CPU本地字的大小:32位或64位,取决于处理器。

对于32位系统,这意味着最大堆大小为4GB。对于64位系统,堆大小可能会变得更大, 但是64位指针的开销意味着仅仅因为指针较大而存在更多的浪费空间 。并且比浪费的空间更糟糕的是,当在主存储器和各种缓存(LLC,L1等等)之间移动值时,较大的指针 消耗更多的带宽

Java使用称为压缩OOPS的技巧来解决这个问题。而不是指向内存中的确切字节位置,而是表示指针引用对象偏移量。这意味着一个32位指针可以引用40亿个对象,而不是40亿个字节。最终,这意味着堆可以增长到约32GB的物理尺寸,同时仍然使用32位指针。

一旦穿越了这个神奇的32GB的边界,指针就会切换回普通的对象指针。每个指针的大小增加,使用 更多的CPU内存带宽 ,并且实际上会丢失内存。实际上,在使用压缩OOPS获得32GB以下堆的相同有效内存之前,需要大约40-50GB的分配堆。

以上小结为:即使我们有足够的内存空间,尽量避免跨越32GB的堆边界。

否则会导致浪费了内存,降低了CPU的性能,并使GC在大堆中挣扎。

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

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

方式一:最好的办法是在系统上完全禁用交换分区。

下面可以暂时关闭swap:

要永久禁用它,需要编辑我们的/etc/fstab

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

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

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

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

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

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

wood大叔:事实上,给ES分配的内存有一个魔法上限值26GB。这样可以确保启用zero based Compressed OOPS,这样性能才是最佳的。

1.1. 基本配置 elasticsearchconfig文件夹面两配置文 件:elasticsearch.ymllogging.yml第es基本配置文件第二志配置文件es使用log4j记录 志所logging.yml设置按普通log4j配置文件设置行面主要讲解elasticsearch.yml文件配置东西

cluster.name: elasticsearch

配置es集群名称默认elasticsearches自发现同网段es同网段集群用属性区同集群

node.name: "Franz Kafka"

节点名默认随机指定name列表名字该列表esjar包config文件夹name.txt文件其作者添加趣名字

node.master: true

指定该节点否资格选举node默认truees默认集群第台机器master台机挂重新选举master

node.data: true

指定该节点否存储索引数据默认true

index.number_of_shards: 5

设置默认索引片数默认5片

index.number_of_replicas: 1

设置默认索引副本数默认1副本

path.conf: /path/to/conf

设置配置文件存储路径默认es根目录config文件夹

path.data: /path/to/data

设置索引数据存储路径默认es根目录data文件夹设置存储路径用逗号隔例:

path.data: /path/to/data1,/path/to/data2

path.work: /path/to/work

设置临文件存储路径默认es根目录work文件夹

path.logs: /path/to/logs

设置志文件存储路径默认es根目录logs文件夹

path.plugins: /path/to/plugins

设置插件存放路径默认es根目录plugins文件夹

bootstrap.mlockall: true

设置true锁住内存jvm始swappinges效率降低所要保证swapES_MIN_MEM ES_MAX_MEM两环境变量设置同值并且保证机器足够内存配给es同要允许elasticsearch进程锁住内存linux通`ulimit -l unlimited`命令

network.bind_host: 192.168.0.1

设置绑定ip址ipv4或ipv6默认0.0.0.0

network.publish_host: 192.168.0.1

设置其节点该节点交互ip址设置自判断值必须真实ip址

network.host: 192.168.0.1

参数用同设置bind_hostpublish_host面两参数

transport.tcp.port: 9300

设置节点间交互tcp端口默认9300

transport.tcp.compress: true

设置否压缩tcp传输数据默认false压缩

http.port: 9200

设置外服务http端口默认9200

http.max_content_length: 100mb

设置内容容量默认100mb

http.enabled: false

否使用http协议外提供服务默认true启

gateway.type: local

gateway类型默认local即本文件系统设置本文件系统布式文件系统HadoopHDFSamazons3服务器

gateway.recover_after_nodes: 1

设置集群N节点启进行数据恢复默认1

gateway.recover_after_time: 5m

设置初始化数据恢复进程超间默认5钟

gateway.expected_nodes: 2

设置集群节点数量默认2旦N节点启立即进行数据恢复

cluster.routing.allocation.node_initial_primaries_recoveries: 4

初始化数据恢复并发恢复线程数默认4

cluster.routing.allocatio

确保将对内存最大值和最小值设置为相同大小,防止出现在运行时改变堆内存大小而消耗系统资源;

lucene会消耗大量的非堆内存,其被设计可以很好利用 *** 作系统的底层缓存机制,从而提升检索性能。标准建议将50%可用内存作为es的堆内存,剩下50%交给 *** 作系统及lucene,如不考虑对分词字符串的聚合 *** 作(不使用fielddata),可以降低对内存,这样对es及lucene的性能都会提升;

同时对内存最大不要超过32GB,Java 使用一个叫作 内存指针压缩(compressed oops)的技术来解决这个问题。 它的指针不再表示对象在内存中的精确位置,而是表示 偏移量 。这意味着 32 位的指针可以引用 40 亿个 对象 , 而不是 40 亿个字节。最终, 也就是说堆内存增长到 32 GB 的物理内存,也可以用 32 位的指针表示。

一旦你越过那个神奇的 ~32 GB 的边界,指针就会切回普通对象的指针。 每个对象的指针都变长了,就会使用更多的 CPU 内存带宽,也就是说你实际上失去了更多的内存。事实上,当内存到达 40–50 GB 的时候,有效内存才相当于使用内存对象指针压缩技术时候的 32 GB 内存。

内存交换到磁盘对服务器性能来说是致命的,最好的办法就是在你的 *** 作系统中完全禁用 swap。可以设置配置文件中的 mlockall 开关, 它的作用就是允许 JVM 锁住内存,禁止 *** 作系统交换出去。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/11255045.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存