为什么Solr for Windows需要这么多内存?

时间:2015-12-05 14:31:38

标签: solr lucene full-text-search solr5 fulltext-index

为什么Solr for Windows需要这么多内存?

我的Solr数据是SEO关键字(1-10个字,最多120个符号长度,8亿行)和其他一些数据。架构是:

<?xml version="1.0" encoding="UTF-8" ?>
<schema name="suggests" version="1.5">
<copyField source="suggest" dest="suggest_exact"/>

<types>
    <fieldType name="text_stem" class="solr.TextField" positionIncrementGap="100">
        <analyzer>
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.LowerCaseFilterFactory"/>
            <filter class="solr.SnowballPorterFilterFactory" language="Russian" />
        </analyzer>
    </fieldType>
    <fieldType name="text_exact" class="solr.TextField" positionIncrementGap="100">
        <analyzer>
            <tokenizer class="solr.StandardTokenizerFactory"/>
            <filter class="solr.LowerCaseFilterFactory"/>
        </analyzer>
    </fieldType>
    <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
</types>
<fields>
    <field name="suggest" type="text_stem" indexed="true" stored="true"/>
    <field name="suggest_exact" type="text_exact" indexed="true" stored="false"/>
    <field name="length" type="int" indexed="true" stored="true"/>
    <field name="position" type="int" indexed="true" stored="true"/>
    <field name="wordstat1" type="int" indexed="true" stored="true"/>
    <field name="wordstat3" type="int" indexed="true" stored="true"/>
    <field name="ln" type="int" indexed="true" stored="true"/>
    <field name="wc" type="int" indexed="true" stored="true"/>
 </fields>

Solr for Windows吃大约10 GB的RAM,有时需要更多(最多16 GB)。 现在我将它配置为使用SOLR_JAVA_MEM=-Xms8192m -Xmx16384m并且它可以工作,但是当它是4 GB或更少时 - Java崩溃并出现错误OutOfMemory。

那么,我做错了什么?如何配置Solr以减少RAM? 我可以提供solrconfig.xml的任何部分。

solrconfig.xml

<query>
    <maxBooleanClauses>1024</maxBooleanClauses>
    <filterCache class="solr.FastLRUCache"
                 size="512"
                 initialSize="512"
                 autowarmCount="0"/>
    <queryResultCache class="solr.LRUCache"
                     size="512"
                     initialSize="512"
                     autowarmCount="0"/>
    <documentCache class="solr.LRUCache"
                   size="512"
                   initialSize="512"
                   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>200</queryResultMaxDocsCached>

    <useColdSearcher>false</useColdSearcher>

    <maxWarmingSearchers>2</maxWarmingSearchers>

</query>

那么,我到底想要做什么。

我向Solr添加了800万行。而且并非全部 - 我有30亿行的数据集。行是SEO关键词,如&#34;求职&#34;,&#34;在纽约找工作&#34;等等#34;建议&#34;字段包含许多相同的常用字词,如&#34; job&#34;,&#34; download&#34;和别的。我想,那个词是&#34;下载&#34;存在于所有行的10%中。

我提供服务,用户可以在这里进行查询,例如&#34;下载&#34;并获取所有文件,其中包含单词&#34; download&#34;。

我创建了一个桌面软件(.NET),用于在服务的Web界面(PHP + MySQL)和Solr之间进行通信。该软件从Web服务获取任务,向Solr查询,下载Solr结果并将其提供给用户。

为了获得所有结果,我将GET查询发送到Solr,如:

http://localhost:8983/solr/suggests2/select?q=suggest:(job%20AND%20new%20AND%20york)&fq=length:[1%20TO%2032]&fq=position:[1%20TO%2010]&fq=wc:[1%20TO%2032]&fq=ln:[1%20TO%20256]&fq=wordstat1:[0%20TO%20*]&fq=wordstat3:[1%20TO%20100000000]&sort=wordstat3%20desc&start=0&rows=100000&fl=suggest%2Clength%2Cposition%2Cwordstat1%2Cwordstat3&wt=csv&csv.separator=;

正如您所看到的 - 我使用fq和排序而不使用分组。 也许有人看到我在Solr查询或方法中的错误 - 请随意告诉我这一点。 感谢。

1 个答案:

答案 0 :(得分:1)

您正在对未启用DocValues的TrieIntField进行排序。这意味着Solr将在堆上保留值的副本。有800M的值,就是那个3.2GB的堆。为docValues="true"字段设置wordstat3并重新编制索引应该会大幅降低该要求,但会牺牲一些性能。

请注意Solr(Lucene真的)在一个分片中不支持超过20亿个文档。这是一个硬性限制。如果您计划将30亿个文档编入同一逻辑索引,则必须使用多分片SolrCloud。