【搜索引擎Solr】配置 Solr 以获得最佳性能

Apache Solr 是广泛使用的搜索引擎。有几个著名的平台使用 Solr;Netflix 和 Instagram 是其中的一些名称。我们在 tajawal 的应用程序中一直使用 Solr 和 ElasticSearch。在这篇文章中,我将为您提供一些关于如何编写优化的 Schema 文件的技巧。我们不会讨论 Solr 的基础知识,我希望您了解它的工作原理。

虽然您可以在 Schema 文件中定义字段和一些默认值,但您不会获得必要的性能提升。您必须注意某些关键配置。在这篇文章中,我将讨论这些配置,您可以使用它们在性能方面充分利用 Solr。

事不宜迟,让我们开始了解这些配置是什么。

1.配置缓存

Solr 缓存与索引搜索器的特定实例相关联,索引的特定视图在该搜索器的生命周期内不会更改。

为了最大化性能,配置缓存是最重要的一步。

配置`filterCache`:

过滤器缓存由 SolrIndexSearcher 用于过滤器。过滤器缓存允许您控制过滤器查询的处理方式,以最大限度地提高性能。FilterCache 的主要好处是当打开一个新的搜索器时,它的缓存可以使用旧搜索器的缓存中的数据进行预填充或"自动预热"。所以它肯定有助于最大限度地提高性能。例如:

go 复制代码
<filterCache
class="solr.FastLRUCache"
size="512"
initialSize="512"
autowarmCount="0"
/>

类:SolrCache 实现 LRUCache(LRUCache 或 FastLRUCache)

size:缓存中的最大条目数

initialSize:缓存的初始容量(条目数)。(参见 java.util.HashMap)

autowarmCount:要从旧缓存预填充的条目数。

配置`queryResultCache`和`documentCache`:

queryResultCache 缓存保存先前搜索的结果:基于查询、排序和请求的文档范围的文档 ID 的有序列表 (DocList)。

documentCache 缓存保存 Lucene Document 对象(每个文档的存储字段)。由于 Lucene 内部文档 ID 是瞬态的,因此该缓存不会自动预热。

您可以根据您的应用程序配置它们。它在您主要使用只读用例的情况下提供更好的性能。

假设您有一个博客,一个博客可以在帖子上有帖子和评论。在 Post 的情况下,我们可以启用这些缓存,因为在这种情况下,数据库读取远远超过写入。所以在这种情况下,我们可以为 Posts 启用这些缓存。

例如:

go 复制代码
<queryResultCache 
  class="solr.LRUCache"
  size="512" 
  initialSize="512" 
  autowarmCount="0"
/><documentCache 
  class="solr.LRUCache"               
  size="512"               
  initialSize="512"               
  autowarmCount="0"
/>

如果您主要使用只写用例,请在每次软提交时禁用 queryResultCache 和 documentCache,这些缓存会被刷新,并且不会产生太大的性能影响。因此请记住上面提到的博客示例,我们可以在评论的情况下禁用这些缓存。

2.配置SolrCloud

如今,云计算非常流行,它允许您管理可扩展性、高可用性和容错性。Solr 能够设置结合容错和高可用性的 Solr 服务器集群。

在 setupSolrCloud 环境中,您可以配置"主"和"从"复制。使用"主"实例来索引信息,并使用多个从属(基于需求)来查询信息。在主服务器上的 solrconfig.xml 文件中,包括以下配置:

go 复制代码
<str name="confFiles">
solrconfig_slave.xml:solrconfig.xml,x.xml,y.xml
</str>

查看 Solr Docs 了解更多详细信息。

3.配置`Commits`

为了使数据可用于搜索,我们必须将其提交到索引。在某些情况下,当您拥有数十亿条记录时,提交可能会很慢,Solr 使用不同的选项来控制提交时间,让您可以更好地控制何时提交数据,您必须根据您的应用程序选择选项。

"提交"或"软提交":

您可以通过发送 commit=true 参数和更新请求来简单地将数据提交到索引,它将对所有 Lucene 索引文件进行硬提交到稳定存储,它将确保所有索引段都应该更新,并且成本可能很高当你有大数据时。

为了使数据立即可用于搜索,可以使用附加标志 softCommit=true,它会快速提交您对 Lucene 数据结构的更改但不保证将 Lucene 索引文件写入稳定存储,此实现称为Near Real Time,一项提高文档可见性的功能,因为您不必等待后台合并和存储(如果使用 SolrCloud,则为 ZooKeeper)完成,然后再进行其他操作。

自动提交:

autoCommit 设置控制挂起更新自动推送到索引的频率。您可以设置时间限制或最大更新文档限制来触发此提交。也可以在发送更新请求时使用 `autoCommit` 参数定义。您还可以在 Request Handler 中定义如下:

go 复制代码
<autoCommit>
<maxDocs>20000</maxDocs>
<maxTime>50000</maxTime>
<openSearcher>false</openSearcher>
</autoCommit>

maxDocs:自上次提交以来发生的更新数。

maxTime:自最旧的未提交更新以来的毫秒数

openSearcher:执行提交时是否打开一个新的搜索器。如果这是错误的,则提交会将最近的索引更改刷新到稳定存储,但不会导致打开新的搜索器以使这些更改可见。默认值为真。

在某些情况下,您可以完全禁用 autoCommit,例如,如果您将数百万条记录从不同的数据源迁移到 Solr,您不希望在每次插入时都提交数据,甚至不希望在批量的情况下提交数据。每 2、4 或 6 千次插入都不需要它,因为它仍然会减慢迁移速度。在这种情况下,您可以完全禁用 `autoCommit` 并在迁移结束时进行提交,或者您可以将其设置为较大的值,例如 3 小时(即 3*60*60*1000)。您还可以添加 <maxDocs>50000000</maxDocs>,这意味着仅在添加 5000 万个文档后才会自动提交。发布所有文档后,手动或从 SolrJ 调用一次 commit - 提交需要一段时间,但总体上会快得多。

此外,在您完成批量导入后,减少 maxTime 和 maxDocs,以便您对 Solr 所做的任何增量帖子都会更快地提交。

4.配置动态字段

Apache Solr 的一项惊人功能是 dynamicField。当您有数百个字段并且您不想定义所有字段时,它非常方便。

动态字段与常规字段一样,只是它的名称中带有通配符。在索引文档时,不匹配任何明确定义的字段的字段可以与动态字段匹配。

例如,假设您的架构包含一个名为 *_i 的动态字段。如果您尝试使用 cost_i 字段索引文档,但架构中没有明确定义 cost_i 字段,则 cost_i 字段将具有为 *_i 定义的字段类型和分析。

但是你在使用dynamicField时必须小心,不要广泛使用它,因为它也有一些缺点,如果你使用投影(如"abc.*.xyz.*.fieldname")来获取特定的动态字段列,使用正则表达式解析字段需要时间。在返回查询结果的同时也增加了解析时间,下面是创建动态字段的示例。

go 复制代码
<dynamicField
name="*.fieldname"
type="boolean"
multiValued="true"
stored="true"
/>

使用动态字段意味着您可以在字段名称中拥有无限数量的组合,因为您指定了通配符,有时可能会很昂贵,因为 Lucene 为每个唯一字段(列)名称分配内存,这意味着如果您有一行包含列A、B、C、D 和另一行有 E、F、C、D,Lucene 将分配 6 块内存而不是 4 块,因为有 6 个唯一列名,所以即使有 6 个唯一列名,万一百万行,它可能会使堆崩溃,因为它将使用 50% 的额外内存。

5. 配置索引与存储字段

索引字段意味着您正在使字段可搜索,indexed="true" 使字段可搜索、可排序和可分面,例如,如果您有一个名为 test1 且 indexed="true" 的字段,那么您可以像 q= 一样搜索它test1:foo,其中 foo 是您要搜索的值,因此,仅将搜索所需的那些字段设置为 indexed="true",如果需要,其余字段应为 indexed="false"在搜索结果中。例如:

go 复制代码
<field name="foo" type="int" stored="true" indexed="false"/>

这意味着我们可以减少重新索引时间,因为在每次重新索引时,Solr 都会应用过滤器、标记器和分析器,这会增加一些处理时间,如果我们的索引数量较少的话。

6.配置复制字段

Solr 提供了非常好的功能,称为 copyField,它是一种将多个字段的副本存储到单个字段的机制。copyField 的使用取决于场景,但最常见的是创建单个"搜索"字段,当用户或客户端未指定要查询的字段时,该字段将用作默认查询字段。

对所有通用文本字段使用copyField并将它们复制到一个文本字段中,并使用它进行搜索,它会减少索引大小并为您提供更好的性能,例如,如果您有像ab_0_aa_1_abcd这样的动态数据,并且您想要复制所有 具有后缀 _abcd 到一个字段的字段。您可以在 schema.xml 中创建一个 copyField,如下所示:

go 复制代码
<copyField source="*_abcd" dest="wxyz"/>

source:要复制的字段的名称

dest:复制字段的名称

7. 使用过滤查询'fq'

在搜索中使用 Filter Query fq 参数对于最大化性能非常有用,它定义了一个查询,可用于限制可以返回的文档的超集,而不影响分数,它独立缓存查询。

Filter Queryfq 对于加速复杂查询非常有用,因为使用 fq 指定的查询独立于主查询进行缓存。当后面的查询使用相同的过滤器时,会发生缓存命中,并且过滤器结果会从缓存中快速返回。

下面是使用过滤器查询的 curl 示例:

go 复制代码
POST
{
 "form_params": {
  "fq": "id=1234",
  "fl": "abc cde",
  "wt": "json"
 },
 "query": {
  "q": "*:*"
 }
}

过滤 qeury 参数也可以在单个搜索 qeury 中多次使用。查看 Solr Filter Qeury 文档以获取更多详细信息。

8. 使用构面查询

Apache Solr 中的 Faceting 用于将搜索结果分类为不同的类别,执行聚合操作(如按特定字段分组、计数、分组等)非常有帮助,因此,对于所有聚合特定查询,您可以使用 Facet 来 开箱即用地进行聚合,它也将成为性能提升器,因为它纯粹是为此类操作而设计的。

下面是向 solr 发送构面请求的 curl 示例。

go 复制代码
{
 "form_params": {
     "fq"            : "fieldName:value",
     "fl"            : "fieldName",
     "facet"         : "true",
     "facet.mincount": 1,
     "facet.limit"   : -1, 
     "facet.field"   : "fieldName",
     "wt"            : "json",
 },
 "query"      : {
     "q": "*:*",
 },
}

fq:过滤查询

fl:结果中要返回的字段列表

facet:true/false 启用/禁用构面计数

facet.mincount:排除计数低于 1 的范围

facet.limit:限制结果中返回的组数,-1 表示全部

facet.field:该字段应被视为构面(对结果进行分组)

结论:

将 Solr 投入生产时,性能改进是关键步骤。Solr 中有许多调整旋钮可以帮助您最大限度地提高系统的性能,其中一些我们在本博客中讨论过,在 solr-config 文件中进行更改以使用最佳配置,使用适当的索引选项或字段更新架构文件 类型,尽可能使用过滤器 queriesfq 并使用适当的缓存选项,但这又取决于您的应用程序。

这就结束了。

|-----------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|------------------|
| 本文 | https://architect.pub/configuring-solr-optimum-performance ||
| 讨论:知识星球【首席架构师圈】或者加微信小号【cea_csa_cto】或者加QQ群【792862318】 |||
| 公众号 | 【jiagoushipro】 【超级架构师】 精彩图文详解架构方法论,架构实践,技术原理,技术趋势。 我们在等你,赶快扫描关注吧。 | |
| 微信小号 | 【cea_csa_cto】 50000人社区,讨论:企业架构,云计算,大数据,数据科学,物联网,人工智能,安全,全栈开发,DevOps,数字化. | |
| QQ群 | 【792862318】深度交流企业架构,业务架构,应用架构,数据架构,技术架构,集成架构,安全架构。以及大数据,云计算,物联网,人工智能等各种新兴技术。 加QQ群,有珍贵的报告和干货资料分享。 | |
| 视频号 | 【超级架构师】 1分钟快速了解架构相关的基本概念,模型,方法,经验。 每天1分钟,架构心中熟。 | |
| 知识星球 | 向大咖提问,近距离接触,或者获得私密资料分享。 | |
| 喜马拉雅 | 路上或者车上了解最新黑科技资讯,架构心得。 | 【智能时刻,架构君和你聊黑科技】 |
| 知识星球 | 认识更多朋友,职场和技术闲聊。 | 知识星球【职场和技术】 |
| 微博 | 【智能时刻】 | 智能时刻 |
| 哔哩哔哩 | 【超级架构师】 | |
| 抖音 | 【cea_cio】超级架构师 | |
| 快手 | 【cea_cio_cto】超级架构师 | |
| 小红书 | 【cea_csa_cto】超级架构师 | |
| | | |

谢谢大家关注,转发,点赞和点在看。

相关推荐
Elastic 中国社区官方博客4 小时前
Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
jwolf24 小时前
摸一下elasticsearch8的AI能力:语义搜索/vector向量搜索案例
人工智能·搜索引擎
小马爱打代码8 小时前
Elasticsearch简介与实操
大数据·elasticsearch·搜索引擎
java1234_小锋17 小时前
Elasticsearch是如何实现Master选举的?
大数据·elasticsearch·搜索引擎
AiFlutter20 小时前
Java实现简单的搜索引擎
java·搜索引擎·mybatis
梦幻通灵1 天前
ES分词环境实战
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客1 天前
Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
大数据·运维·elasticsearch·搜索引擎·全文检索
infiniteWei1 天前
【Lucene】搜索引擎和文档相关性评分 BM25 算法的工作原理
算法·搜索引擎·lucene
天蓝蓝235282 天前
Lucene数据写入流程
java·mybatis·lucene
Elastic 中国社区官方博客2 天前
Elasticsearch:如何部署文本嵌入模型并将其用于语义搜索
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索