本文介绍您在使用全文索引过程中可能遇到的一些问题和解决方法。

创建索引时设置shard个数和replica个数

创建索引时设置shard个数和replica个数需要满足以下规则:
  • 单个shard的最大document条数不能超过int的最大值,大概21亿。否则就会因lucene底层循环复用int值而导致覆盖。
  • 对于replicationFactor副本数,推荐默认设置为1,并且把autoAddReplicas属性设置为false。对于有特殊要求的,例如写入非常少,读非常多,且读可能会有大量热点,那可以考虑使用replicationFactor=2或者3,可以缓解读负载均衡。
  • 假设实例有n个服务节点,每个节点放m个shard,需要遵循如下公式:
    索引的总数据量 > n X m X 21亿
    如果一个服务节点的m个数太大了,例如超过节点CPU的个数,那就可能要考虑扩容集群或者升配。对于一个索引而言,每个服务节点放一个shard开始,即m=1,如果不满足再依次增加m的值,直到能满足上述公式为止即可。
  • 对于单个shard在条数不能超过int的最大值,大概21亿的情况下,它的存储也尽量不能太大,例如一个shard保存了20亿,按照1KB一个doc,总数据量达到2TB左右,这对一个server来说可能会有点大了,对应如果大量扫描操作会出现异常,推荐扩容节点,分担大量存储扫描取数据的压力。控制在单个shard的总量数据也不要太大。当然这个要结合查询特点和数据特点,例如单个document就10KB和200字节碰到这种情况都是不一样的。
    说明 shard和replica的个数后期可以调整,但建议在创建索引时提前设计好。

HBase同步数据到Search索引的延时是多少

索引同步的延时时间 = 数据同步延迟 + commit时间
没有堆积情况下, 同步延时主要为框架开销,毫秒级别(如果有积压情况下,延时会变长,需要增加节点来增加同步能力)默认commit时间为15秒,对于写很少的客户可以设置为1秒、3秒、5秒,对于写入量大的用户,不推荐设置过小,不然小文件会比较多,服务会频繁的执行文件合并操作,影响整体的性能。

使用预排序功能

排序是非常消耗资源的,在数据量特别大的时候,不仅查的慢,还特别占用系统资源,如果本身存储的数据已经按照某个字段预先排好序,检索性能会有明显的提升,特别是在大数据量上对比的时候,此特点效果更明显。下面简单描述下如何配置预排序:
  • 修改solrconfig.xml中的MergePolicy,具体操作请参见SolrConfig
  • 查询时指定参数segmentTerminateEarly=true,示例如下:
    <mergePolicyFactory class="org.apache.solr.index.SortingMergePolicyFactory">
    <str name="sort">timestamp desc</str>
    <str name="wrapped.prefix">inner</str>
    <str name="inner.class">org.apache.solr.index.TieredMergePolicyFactory</str>
    <int name="inner.maxMergeAtOnce">10</int>
    <int name="inner.segmentsPerTier">10</int>
    </mergePolicyFactory>
    示例中<str name="sort">timestamp desc</str>配置参数表示插入数据时会按照timestamp字段进行预先倒序排序,执行查询如下:
    curl "http://localhost:8983/solr/testcollection/query?q=*:*&sort=timestamp+desc&rows=10&segmentTerminateEarly=true"
    参数上加上segmentTerminateEarly=true后,显示效果会比没有设置预排序的快很多,尤其是排序数据量TB级别之后,效果更明显。
    说明
    • 查询时,指定的sort必须与配置的MergePolicy中指定的一致,否则不起效果。
    • 查询时需要指定segmentTerminateEarly参数,否则也会进行全排。
    • 使用了这个预排序返回的结果中,numFound是不准确的。