java - apache点燃2.10.0堆饥饿
问题描述
从 2.7.1 版本升级到 2.10.0 版本后,在节点启动后 24-36 小时后,节点会面临巨大的完整 GC 操作。
我们尝试增加堆大小但没有成功,这是节点的启动配置;
JVM_OPTS="$JVM_OPTS -Xms12g -Xmx12g -server -javaagent:/etc/prometheus/jmx_prometheus_javaagent-0.14.0.jar=8090:/etc/prometheus/jmx.yml -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=49165 -Dcom.sun.management.jmxremote.host=localhost -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1g -DIGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK=true -DIGNITE_WAL_MMAP=true -DIGNITE_BPLUS_TREE_LOCK_RETRIES=100000 -Djava.net.preferIPv4Stack=true"
JVM_OPTS="$JVM_OPTS -XX:+AlwaysPreTouch -XX:+UseG1GC -XX:+ScavengeBeforeFullGC -XX:+DisableExplicitGC -XX:+UseStringDeduplication -Xloggc:/var/log/apache-ignite/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCCause -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
这是 80 小时的 GC 分析报告:https ://gceasy.io/my-gc-report.jsp?p=c2hhcmVkLzIwMjEvMDgvMzEvLS1nYy5sb2cuMC5jdXJyZW50LnppcC0tNS01MS0yOQ==&channel=WEB
我们需要更多的堆大小还是需要注意一个BUG?
这是节点配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="gridLogger">
<bean class="org.apache.ignite.logger.log4j2.Log4J2Logger">
<constructor-arg type="java.lang.String" value="/etc/apache-ignite/ignite-log4j2.xml"/>
</bean>
</property>
<property name="communicationSpi">
<bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
<property name="usePairedConnections" value="true"/>
</bean>
</property>
<property name="failureDetectionTimeout" value="60000"/>
<property name="systemThreadPoolSize" value="128"/>
<property name="publicThreadPoolSize" value="128"/>
<property name="queryThreadPoolSize" value="128"/>
<property name="serviceThreadPoolSize" value="128"/>
<property name="stripedPoolSize" value="128"/>
<property name="dataStreamerThreadPoolSize" value="4"/>
<property name="rebalanceThreadPoolSize" value="16"/>
<!-- Explicitly enable peer class loading. -->
<property name="peerClassLoadingEnabled" value="true"/>
<!-- Enable deploymentSpi, /usr/share/apache-ignite/libs/segmentify directory will be checked every 5 seconds for changed files-->
<property name="deploymentSpi">
<bean class="org.apache.ignite.spi.deployment.uri.UriDeploymentSpi">
<property name="temporaryDirectoryPath" value="/tmp/temp_ignite_libs"/>
<property name="uriList">
<list>
<value>file://freq=5000@localhost/usr/share/apache-ignite/libs/segmentify/</value>
</list>
</property>
</bean>
</property>
<property name="cacheConfiguration">
<list>
<!-- Partitioned cache example configuration (Atomic mode). -->
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="default"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="backups" value="1"/>
</bean>
</list>
</property>
<!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="networkTimeout" value="60000"/>
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
<property name="addresses">
<list>
<!-- THERE ARE 10 NODES -->
</list>
</property>
</bean>
</property>
</bean>
</property>
<!-- Enabling Apache Ignite native persistence. -->
<property name="dataStorageConfiguration">
<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
<property name="defaultDataRegionConfiguration">
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="persistenceEnabled" value="true"/>
<property name="checkpointPageBufferSize" value="#{ 2L * 1024 * 1024 * 1024}"/>
<property name="maxSize" value="#{ 40L * 1024 * 1024 * 1024 }"/>
</bean>
</property>
<property name="storagePath" value="/srv/ignite/persist"/>
<property name="walPath" value="/srv/ignite/wal"/>
<property name="walArchivePath" value="/srv/ignite/wal"/>
<property name="walMode" value="LOG_ONLY"/>
<property name="walSegmentSize" value="#{ 256L * 1024 * 1024 }"/>
<property name="walFlushFrequency" value="5000"/>
<property name="maxWalArchiveSize" value="#{ 512L * 1024 * 1024 }"/>
<property name="writeThrottlingEnabled" value="true"/>
<property name="checkpointFrequency" value="300000"/>
<property name="checkpointWriteOrder" value="SEQUENTIAL" />
</bean>
</property>
</bean>
解决方案
(评论变得太大)
查看日志@reclaimed bytes,回收的大小稳步下降,直到您似乎几乎没有回收任何内存,完整的 gc:s 数量稳步增加(没有剩余的堆分配) 所以 JVM 一次又一次地尝试使用完整的 gc,直到最后完整的 gc 释放了大约 10 GB 的空间。
查看 Old Gen 图表,看起来有点像内存泄漏,但突然一切都清楚了。您会看到回收提供的东西越来越少,直到它没有提供任何东西并且 gc:s 的数量增加了。
很难说这件事,真的,不知道更多。
需要考虑的一些事情:
- 行为模式
(鉴于当前的设置,这会重复吗?)好的,这是重复的。 - 客户端行为 连接到系统的客户端的行为
是否与以前不同? - 配置
升级时,是否有任何配置更改?改变的默认行为等等? - 您提交的作品有什么变化吗?
增加堆空间很可能无济于事,反而会增加完整的 gc 时间。它可能做的是延迟饥饿的开始。
如果用法没有变化,那么唯一的原因是点燃。
抱歉,我无法提供更多帮助。
推荐阅读
- google-oauth - Pygsheets - 非交互式 oauth 身份验证
- three.js - 将平移、旋转和缩放应用于 THREE.BoxGeometry(..)
- c++ - 使用嵌套的 std::vector 在 C++ 中实现 3D 矩阵
- r - 如何使用 mutate 根据现有列中的状态缩写添加具有状态名称的列?
- c++ - 如何使用模板类头中的前向声明修复 C++ 循环依赖
- java - 解释这段代码中发生了什么?(帮助解释类)
- javafx - 一对
在游戏菜单中 - java - 使用选择排序按区域对形状数组进行排序
- ruby-on-rails - 如何测试模型中是否使用 Active Storage 发送了新文件?
- api - 使用来自 API 的动态数据创建水平滚动视图