关键的gemfire索引创建花费太多时间

时间:2019-04-08 06:54:51

标签: java garbage-collection gemfire spring-data-gemfire

我们正在使用Pivotal Gemfire作为数据缓存。最近,我们从gemfire 8.2.1迁移到了具有完全相同的区域,数据和索引的9.5.1。但是,特别是在一个区域上创建索引要花费太多时间,其条目计数为7284500。我们已经使用Spring数据gemfire v2.4.1.RELEASE定义了缓存服务器。以下是问题区域的配置:

<gfe:index id="someRegion_idx1" expression="o1.var1" from="/someRegion o1" />
<gfe:index id="someRegion_idx2" expression="o2.var2" from="/someRegion o2"/>
<gfe:index id="someRegion_idx3" expression="o3.var3" from="/someRegion o3"/>
<gfe:index id="someRegion_idx4" expression="o4.var4" from="/someRegion o4"/>
<gfe:index id="someRegion_idx5" expression="o5.var5" from="/someRegion o5"/>
<gfe:index id="someRegion_idx6" expression="o6.var6" from="/someRegion o6"/>
<gfe:index id="someRegion_idx7" expression="o7.var7" from="/someRegion o7"/>
<gfe:index id="someRegion_idx8" expression="o8.var8" from="/someRegion o8"/>

下面是索引定义:

<gfe:cache
    properties-ref="gemfireProperties"
    close="true"
    critical-heap-percentage=85
    eviction-heap-percentage=75
    pdx-serializer-ref="pdxSerializer"
    pdx-persistent="true"
    pdx-read-serialized="true"
    pdx-ignore-unread-fields="false" />

以下是缓存定义:

java -Xms50G -Xmx80G -XX:+UseConcMarkSweepGC 
-XX:+UseCMSInitiatingOccupancyOnly 
-XX:CMSInitiatingOccupancyFraction=70 
-XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark 
-XX:+UseParNewGC -XX:+UseLargePages 
-XX:+DisableExplicitGC 
-Ddw.appname=$APPNAME \
-Dgemfire.Query.VERBOSE=true \
-Dgemfire.QueryService.allowUntrustedMethodInvocation=true \
-DDistributionManager.MAX_THREADS=20 \
-DDistributionManager.MAX_FE_THREADS=10 \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=11809 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dconfig=/config/location/ \
com.my.package.cacheServer

以下是Java参数:

XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC

在没有 member-timeout 的情况下运行时,我们通常会在应用索引时遇到以下错误:

  

org.apache.geode.ForcedDisconnectException:成员未响应gemfire关键的心跳请求

我们尝试将{{1}}属性从5000增加到300000,但是仍然存在相同的问题。

添加了上述与GC相关的Java参数后,每个索引大约需要24分钟才能应用,但这一次没有错误。这导致服务器花费太多时间与大约15个其他区域一起使用。其他区域没有这样的问题。(该区域的数据量最大。其他区域的条目数约为500K至3M)

2 个答案:

答案 0 :(得分:4)

我从您的配置中看到一些需要调整的地方。对于其中一些,我将需要推测,因为我不知道您的一般使用期限堆消耗。

  1. Xmx必须等于Xms将两者都设置为80g,因为增大堆可能会导致重大问题
  2. 显式设置您的NewSize = MaxNewSize。如果我可以看到GC日志,则可以提供帮助,但是我将以该配置为起点。

将NewSize和MaxNewSize设置为9gb 将SurvivorRatio设置为1 将TargetSurvivorRatio设置为85 添加PrintTenuringDistribution标志以帮助我们进行微调。

  1. 我不是Scavenge标志的粉丝,因为如果对其进行微调,它们会引起更大的抖动。现在,您可以保留它们,但是我将删除ScavengeBeforeFullGC和ScavengeBeforeRemark。保留DisableExplicitGC标志。更重要的是,虽然我读到您的行为会因使用这些标志而改变,但是在索引创建时间和这些标志之间找到相关性是一个麻烦。更有可能的是,由于堆配置错误,成员变得无响应,所以让我们解决这个问题。

  2. 关于驱逐配置,我看到您说您在此“问题”区域中有7+百万个条目,但是您有一个驱逐算法,除了前1000个磁盘外,所有磁盘都溢出到磁盘上。为什么?磁盘溢出是用来处理突发事件的方法,而不是“给定的”方法。可能是磁盘问题导致了问题的某些方面。可能需要访问磁盘上的所有这些条目是一个问题。当所有条目实际上都在堆中时,您是否遇到过此问题?

  3. 启用具有设置为可打印gc详细信息,日期戳等的所有标志的GC日志。

  4. 如果您尚未为GemFire启用统计信息,请同时启用这些统计信息。

  5. 如果发现成员超时不足,则可能是环境中存在问题。应该解决这些问题,而不是考虑增加成员超时来掩盖这些问题。

答案 1 :(得分:3)

关于索引的创建时间-正如David指出的那样,您已经将该区域配置为将几乎所有数据存储在磁盘上。

这将使索引创建更加昂贵,因为索引创建过程必须从磁盘读取所有条目。

但是,如果在索引上使用define标志,则可以通过此配置使索引创建更快

<gfe:index id="someRegion_idx3" expression="o3.var3" from="/someRegion o3" define="true"/>

这将导致在ApplicationContext初始化结束时一次创建所有索引。因此,希望您的总时间将接近24分钟,因为GemFire只需扫描一次磁盘上的所有数据即可。

有关定义索引的更多信息,请参见https://docs.spring.io/spring-gemfire/docs/current/reference/html/#_defining_indexes

这并不能真正解释您的垃圾回收问题-我将在David的回答中找到更多详细信息。