【问题标题】:Getting Perm Gen space issue in running elasticsearch cluster在运行弹性搜索集群时遇到 Perm Gen 空间问题
【发布时间】:2016-01-03 14:34:30
【问题描述】:

我们正在运行带有 6 个节点的 elasticsearch-1.5.1 集群,最近几天我在集群中遇到 java.lang.OutOfMemoryError PermGen space 问题,这会影响节点同样会下降。我正在重新启动特定节点以启动。

我们试图通过给集群增加负载来解决这个问题,但不幸的是无法重现。但是有些我们如何在生产中一次又一次地遇到同样的问题。

这里是一些yml文件配置

index.recovery.initial_shards: 1
index.query.bool.max_clause_count: 8192
index.mapping.attachment.indexed_chars: 500000
index.merge.scheduler.max_thread_count: 1
cluster.routing.allocation.node_concurrent_recoveries: 15
indices.recovery.max_bytes_per_sec: 50mb
indices.recovery.concurrent_streams: 5

内存配置

ES_HEAP_SIZE=10g
ES_JAVA_OPTS="-server -Des.max-open-files=true"
MAX_OPEN_FILES=65535
MAX_MAP_COUNT=262144

使用以下配置更新问题

我怀疑与此问题相关的merge.policy.max_merged_segment。我们的集群中有 22 个索引。下面给出了索引的merge.policy.max_merged_segment

  • 7 个索引有 20gb
  • 3 个索引有 10gb
  • 12 个索引有 5GB

更新流程信息

esuser xxxxx 1 28 Oct03 ? 1-02:20:40 /usr/java/default/bin/java -Xms10g -Xmx10g -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -Dfile.encoding=UTF-8 -server -Des.max-open-files= true -Delasticsearch -Des.pidfile=/var/es/elasticsearch.pid -Des.path.home=/usr/es/elasticsearch -cp :/usr/es/elasticsearch/lib/elasticsearch-1.5.1.jar:/ usr/es/elasticsearch/lib/:/usr/es/elasticsearch/lib/sigar/ -Des.default.path.home=/usr/es/elasticsearch -Des.default.path.logs=/es/es_logs -Des.default.path.data=/es/es_data -Des.default.path.work= /es/es_work -Des.default.path.conf=/etc/elasticsearch org.elasticsearch.bootstrap.Elasticsearch


在搜索时我从 elasticsearch 集群获取的堆栈跟踪下方。但是在索引时间的事件中,我也遇到了同样的问题。根据我的观察,一些搜索/索引操作会增加 PermGen,如果即将进行的操作尝试使用 PermGen 空间,问题就来了。

[2015-10-03 06:45:05,262][WARN ][transport.netty          ] [es_f2_01] Message not fully read (response) for [19353573] handler org.elasticsearch.search.action.SearchServiceTransportAction$6@21a25e37, error [true], resetting
[2015-10-03 06:45:05,262][DEBUG][action.search.type       ] [es_f2_01] [product_index][4], node[GoUqK7csTpezN5_xoNWbeg], [R], s[INITIALIZING]: Failed to execute [org.elasticsearch.action.search.SearchRequest@5c2fe4c4] lastShard [true]
org.elasticsearch.transport.RemoteTransportException: Failed to deserialize exception response from stream
Caused by: org.elasticsearch.transport.TransportSerializationException: Failed to deserialize exception response from stream
    at org.elasticsearch.transport.netty.MessageChannelHandler.handlerResponseError(MessageChannelHandler.java:176)
    at org.elasticsearch.transport.netty.MessageChannelHandler.messageReceived(MessageChannelHandler.java:128)
    at org.elasticsearch.common.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.elasticsearch.common.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.elasticsearch.common.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at org.elasticsearch.common.netty.channel.Channels.fireMessageReceived(Channels.java:296)
    at org.elasticsearch.common.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:462)
    at org.elasticsearch.common.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:443)
    at org.elasticsearch.common.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:303)
    at org.elasticsearch.common.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.elasticsearch.common.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.elasticsearch.common.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
    at org.elasticsearch.common.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.elasticsearch.common.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.elasticsearch.common.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
    at org.elasticsearch.common.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)
    at org.elasticsearch.common.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337)
    at org.elasticsearch.common.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
    at org.elasticsearch.common.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
    at org.elasticsearch.common.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
    at org.elasticsearch.common.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.OutOfMemoryError: PermGen space

谁能帮我解决这个问题。谢谢

【问题讨论】:

  • 这对于 Elasticsearch 来说是不寻常的。这是什么ES版本?您在生产和测试环境中是否有相同的设置? ES的内存设置是什么?运行ps -ef | grep elasticsearch 并提供结果。
  • @AndreiStefan 新增进程grep细节,我已经在问题中分享了es版本,ES的内存设置。与生产环境相比,我在测试环境中没有确切的配置。
  • 这是异常的完整堆栈跟踪吗?是否也存在根异常?
  • 是的,这是我在日志中的完整堆栈...没有原因...实际异常是 PermGen
  • 不仅是配置。想想你运行的查询,你如何访问集群(客户端访问)等等。

标签: java elasticsearch out-of-memory permgen


【解决方案1】:

最好的解决方案是使用“Java 8”JVM。

虽然您可以修改 Java 7 JVM 正在使用的堆数量(通过设置 -XX:MaxPermSize=... 如果您使用的是 Oracle JVM),但如果您只是将 JVM 升级到版本 8,那么您不需要'甚至不需要调整 permgen 大小。

这是因为在 JVM 8 中,permgen 大小以非分区方式共享堆,这意味着只有在堆用完时才会用完 permgen 空间。

【讨论】:

  • 感谢您的信息。在生产中升级到 JAVA8 将解决 PermGen 问题,但是我现在无法升级,我可以明确设置 PermGenSize。即使我想知道根本原因并为此提供解决方案。
  • 根本原因是您使用的是 HotSpot JVM,它通过将大量使用的代码编译成机器代码来优化其运行速度。这是期望的行为,而不是错误。问题是一段时间后,它可能会发现太多代码需要优化,以至于没有空间来存储优化的机器代码。在较旧的 JVM 版本中,此代码只能存储在 JVM 内预先分配的内存区域中。在较新的 JVM 版本中,它存储在堆上。
  • 谢谢 Edwin... 我同意 Edwin,它的纯 JVM 内存利用率问题。问题是 PermGen 通常将类文件加载到 mem 中,我希望我的 config/app/settings/process 中的一些 mem 泄漏点可能会再次将类加载到 mem 中,并且无法从 mem 中卸载类。我仍在尝试找出内存泄漏位置。
  • 面临与上述问题类似的问题。建议的一种修复方法是添加 -XX:+CMSClassUnloadingEnabled 字段和 -XX:+UseConcMarkSweepGC。但是添加 CMSclassUnloadingEnabled 会降低性能是一个问题。有什么办法不降低性能,而是添加 CMSclassUnloadingEnabled 条目。
  • @ArivazhaganJeganathan 现在是 2015 年,再过几天就是 2016 年了。您不应该尝试通过调整参数来解决 permgen 空间问题,而应该通过升级到 Java 1.8 来解决它。 Java 1.9 的“特性冻结”已经完成,很快您将落后两个版本。升级。是的,这可能会很痛苦,但尽早感受到痛苦意味着你有更多的时间来做出最好的决定。迟迟不去感受那种痛苦意味着无论如何你都会发现所有你会发现的东西,但你没有时间做任何事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 2021-08-16
  • 2023-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多