use*_*259 5 lucene garbage-collection solr jvm
我们在生产中遇到了无法调试的 Solr 行为。首先是solr的配置:
Solr 版本: 6.5 , Master with 1 Slave 与下面提到的配置相同。
JVM 配置:
-Xms2048m
-Xmx4096m
-XX:+ParallelRefProcEnabled
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=50
Run Code Online (Sandbox Code Playgroud)
其余均为默认值。
索尔配置:
<autoCommit>
<!-- Auto hard commit in 5 minutes -->
<maxTime>{solr.autoCommit.maxTime:300000}</maxTime>
<openSearcher>false</openSearcher>
</autoCommit>
<autoSoftCommit>
<!-- Auto soft commit in 15 minutes -->
<maxTime>{solr.autoSoftCommit.maxTime:900000}</maxTime>
</autoSoftCommit>
</updateHandler>
<query>
<maxBooleanClauses>1024</maxBooleanClauses>
<filterCache class="solr.FastLRUCache" size="8192" initialSize="8192" autowarmCount="0" />
<queryResultCache class="solr.LRUCache" size="8192" initialSize="4096" autowarmCount="0" />
<documentCache class="solr.LRUCache" size="12288" initialSize="12288" autowarmCount="0" />
<cache name="perSegFilter" class="solr.search.LRUCache" size="10" initialSize="0" autowarmCount="10" regenerator="solr.NoOpRegenerator" />
<enableLazyFieldLoading>true</enableLazyFieldLoading>
<queryResultWindowSize>20</queryResultWindowSize>
<queryResultMaxDocsCached>${solr.query.max.docs:40}
</queryResultMaxDocsCached>
<useColdSearcher>false</useColdSearcher>
<maxWarmingSearchers>2</maxWarmingSearchers>
</query>
Run Code Online (Sandbox Code Playgroud)
主机 (AWS) 配置是:
RAM: 7.65GB
Cores: 4
Run Code Online (Sandbox Code Playgroud)
现在,我们的 solr 可以正常工作几个小时,有时甚至几天,但有时突然内存跳起来,GC 开始导致长时间的大停顿而没有太多恢复。当在硬提交后添加或删除一个或多个段时,我们最常看到这种情况。有多少文档被索引并不重要。附上的图像显示只有 1 个文档被索引,导致增加了一个段,直到我们重新启动 Solr,这一切都变得一团糟。
以下是来自 NewRelic 和 Sematext 的图片(请点击链接查看):
更新: 这是 SOLR 上次死亡时的 JMap 输出,我们现在将 JVM 内存增加到 12GB 的 xmx:
num #instances #bytes class name
----------------------------------------------
1: 11210921 1076248416 org.apache.lucene.codecs.lucene50.Lucene50PostingsFormat$IntBlockTermState
2: 10623486 934866768 [Lorg.apache.lucene.index.TermState;
3: 15567646 475873992 [B
4: 10623485 424939400 org.apache.lucene.search.spans.SpanTermQuery$SpanTermWeight
5: 15508972 372215328 org.apache.lucene.util.BytesRef
6: 15485834 371660016 org.apache.lucene.index.Term
7: 15477679 371464296 org.apache.lucene.search.spans.SpanTermQuery
8: 10623486 339951552 org.apache.lucene.index.TermContext
9: 1516724 150564320 [Ljava.lang.Object;
10: 724486 50948800 [C
11: 1528110 36674640 java.util.ArrayList
12: 849884 27196288 org.apache.lucene.search.spans.SpanNearQuery
13: 582008 23280320 org.apache.lucene.search.spans.SpanNearQuery$SpanNearWeight
14: 481601 23116848 org.apache.lucene.document.FieldType
15: 623073 19938336 org.apache.lucene.document.StoredField
16: 721649 17319576 java.lang.String
17: 32729 7329640 [J
18: 14643 5788376 [F
19: 137126 4388032 java.util.HashMap$Node
20: 52990 3391360 java.nio.DirectByteBufferR
21: 131072 3145728 org.apache.solr.update.VersionBucket
22: 20535 2891536 [I
23: 99073 2377752 shaded.javassist.bytecode.Utf8Info
24: 47788 1911520 java.util.TreeMap$Entry
25: 34118 1910608 org.apache.lucene.index.FieldInfo
26: 26511 1696704 org.apache.lucene.store.ByteBufferIndexInput$SingleBufferImpl
27: 17470 1677120 org.apache.lucene.codecs.lucene54.Lucene54DocValuesProducer$NumericEntry
28: 13762 1526984 java.lang.Class
29: 7323 1507408 [Ljava.util.HashMap$Node;
30: 2331 1230768 [Lshaded.javassist.bytecode.ConstInfo;
31: 18929 1211456 com.newrelic.agent.deps.org.objectweb.asm.Label
32: 25360 1014400 java.util.LinkedHashMap$Entry
33: 41388 993312 java.lang.Long
Run Code Online (Sandbox Code Playgroud)
Solr 上的负载并不多 - 最多可以达到每分钟 2000 个请求。索引负载有时会突然爆发,但大多数时候它的负载非常低。但是如上所述,有时即使是单个文档索引也会使 solr 陷入困境,有时它就像一种魅力。
任何关于我们可能出错的地方的指示都会很棒。
我之前也遇到过同样的问题,但后来我调查并发现了一些漏洞,它突然增加了SOLR堆大小的消耗。
我曾经在数据库上的每个记录更新时对 SOLR 进行增量更新,如果文档大小较短,它可以正常工作。
但随着文档大小的增加,SOLR 每天会停止工作 5-8 次。发现的原因是,每当你增量更新一条记录时,SOLR会立即更新它,但稍后SOLR必须再次调整所有文档索引,因此在调整过程中,如果另一个增量请求到达,它会再次启动一个新的增量请求,并继续增加堆消耗,并且在某个时刻它停止响应。
我仍然没有找到该问题的正确工作解决方案,但我为此实施了一个解决方法,即停止文档的增量更新并使用频繁地重新索引整个核心(每天 2-3 次)