Solr分布式搜索与索引分片
当使用传统索引分片时,您需要考虑如何查询文档。
强烈建议您在需要扩展或扩展时使用SolrCloud。下面描述的设置是遗留的,并且在SolrCloud存在之前使用。SolrCloud提供了一个真正的分布式功能集,支持诸如自动路由、leader选择,开放式并发和其他理想的分布式系统中所期望的健全性检查。
本页面上的所有内容都是针对特定于分布式搜索的传统设置。尝试 SolrCloud 的用户不应遵循下面的任何步骤或信息。
更新重新排序(即副本A可能会看到更新X然后是Y,副本B可能会看到更新Y然后是X)。deleteByQuery也以相同的方式处理重新排序,以确保副本是一致的。碎片的所有副本都是一致的,即使这些更新在不同的副本上以不同的顺序到达。
跨碎片分发文档
当不使用SolrCloud时,您需要在服务器场的每个分片上获取所有文档的索引。Solr仅在SolrCloud模式下以其真实形式支持分布式索引(路由)。
在传统分布式模式下,Solr不计算通用术语/文档频率。对于大多数大规模实施来说,Solr 在碎片级计算 TF/IDF 是不太可能的。但是,如果您的集合在服务器上的分布严重偏离,则可能会在搜索中发现具有误导性的关联结果。一般来说,最好是随机分发文件到你的碎片。
使用shards参数执行分布式搜索
如果查询请求包含shards参数,则Solr服务器将请求分布到作为参数列出的所有分片中。该shards参数使用以下语法:
host:port/base_url,host:port/base_url*
例如,下面的shards参数会导致搜索分布在两个Solr服务器上:solr1和solr2,它们都在端口8983上运行:
http://localhost:8983/solr/core1/select?shards=solr1:8983/solr/core1,solr2:8983/solr/core1&indent=true&q=ipod+solr
与其要求用户显式包含shards参数,不如将此参数配置为 solrconfig. xml 的 RequestHandler 部分中的默认值。
不要将shards参数添加到标准请求处理程序中;这样做可能会导致搜索查询进入无限循环。相反,请定义一个使用该shards参数的新请求处理程序,并将分布式搜索请求传递给该处理程序。
使用传统模式,只分布查询请求。这包括使用支持分布式搜索的标准组件对 SearchHandler (或从 org.apache.solr.handler.component.SearchHandler 扩展的任何处理程序)的请求。
与SolrCloud模式一样,当shards.info=true时,分布式响应将包含关于分片的信息(每个分片表示逻辑上不同的索引或物理位置)
以下组件支持分布式搜索:
- Query组件,它返回与查询匹配的文档
- Facet组件,它处理facet.query和facet.field,其中facet是由count(默认值)排序请求。
- Highlighting组件,这使得Solr的包括“突出显示”中的字段值匹配。
- Stats组件,它返回 DocSet 中数值字段的简单统计
- Debug组件,它有助于调试
分布式搜索的限制
在Solr中分布式搜索有以下限制:
- 索引的每个文档都必须有一个唯一的键。
- 如果Solr发现重复的文档ID,则Solr选择第一个文档并丢弃后续的文档。
- 如果在分布式搜索的第一阶段和第二阶段之间发生提交(commit),则分布式搜索的索引可能暂时不同步。这可能会导致这样一种情况:与查询匹配并随后更改的文档可能不再与查询匹配,但仍将被检索。但是,这种情况预计会非常罕见,并且只能针对单个查询请求。
- 分片的数量受GET方法的URI允许的字符数限制;大多数Web服务器通常至少支持4000个字符,但许多服务器限制URI长度以减少其遭受拒绝服务(DoS)攻击的风险。
- 通过在搜索请求中包含fl=id, [shard],可以在分布式搜索中返回每个文档的分片信息。这将返回分片URL。
- 在分布式搜索中,来自核心描述符的数据目录将覆盖 solrconfig. xml 中的任何数据目录。
- 更新命令可能被发送到正确配置分布式索引的任何服务器。文档添加和删除基于唯一文档ID的哈希值被转发到适当的server/shard。commit命令和deleteByQuery命令被发送到每个shards的服务器中。
以前的一个限制是,TF/IDF相关性计算只使用分片本地统计。这仍然是默认情况。如果您的数据不是随机分布的,或者需要更精确的统计数据,那么请记住配置ExactStatsCache。
通过分布式搜索避免分布式死锁
就像在SolrCloud模式中一样,inter-shard请求可能导致分布式死锁,可以按照“分布式请求”一节中的说明来避免 。
在两台本地服务器上测试索引分片
对于简单的功能测试,最简单的方法是在不同的端口上设置两个本地Solr服务器。(当然,在生产环境中,这些服务器将部署在不同的计算机上。)
- 制作两个Solr主目录并将solr.xml复制到新目录中:
mkdir example/nodes mkdir example/nodes/node1 # Copy solr.xml into this solr.home cp server/solr/solr.xml example/nodes/node1/. # Repeat the above steps for the second node mkdir example/nodes/node2 cp server/solr/solr.xml example/nodes/node2/.
- 启动两个Solr实例:
# Start first node on port 8983 bin/solr start -s example/nodes/node1 -p 8983 # Start second node on port 8984 bin/solr start -s example/nodes/node2 -p 8984
- 使用sample_techproducts_configs在两个节点上创建一个核心。
bin/solr create_core -c core1 -p 8983 -d sample_techproducts_configs # Create a core on the Solr node running on port 8984 bin/solr create_core -c core1 -p 8984 -d sample_techproducts_configs
- 在第三个窗口中,为每个服务器索引一个示例文档:
bin/post -c core1 example/exampledocs/monitor.xml -port 8983 bin/post -c core1 example/exampledocs/monitor2.xml -port 8984
- 在端口8983上的节点上搜索:
这应该带回一个文件。在端口8984上的节点上搜索:curl http://localhost:8983/solr/core1/select?q=*:*&wt=xml&indent=true
这也应该带回一个单一的文件。现在使用浏览器或者curl.在两台服务器上进行分布式搜索,在下面的例子中,传递一个额外的参数'fl'来将返回的字段限制为id和name。curl http://localhost:8984/solr/core1/select?q=*:*&wt=xml&indent=true
这应该包含两个文件,如下所示:curl http://localhost:8983/solr/core1/select?q=*:*&indent=true&shards=localhost:8983/solr/core1,localhost:8984/solr/core1&fl=id,name
<response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">8</int> <lst name="params"> <str name="q">*:*</str> <str name="shards">localhost:8983/solr/core1,localhost:8984/solr/core1</str> <str name="indent">true</str> <str name="fl">id,name</str> <str name="wt">xml</str> </lst> </lst> <result name="response" numFound="2" start="0" maxScore="1.0"> <doc> <str name="id">3007WFP</str> <str name="name">Dell Widescreen UltraSharp 3007WFP</str> </doc> <doc> <str name="id">VA902B</str> <str name="name">ViewSonic VA902B - flat panel display - TFT - 19"</str> </doc> </result> </response>