通过spark-solr执行分布式搜索

时间:2017-02-23 15:46:47

标签: apache-spark solr pyspark

我正在使用spark-solr来执行Solr查询。但是,我的搜索不会像他们应该的那样工作,因为由于某种原因,由spark生成的请求会阻止搜索的分发。我通过查看Solr日志发现了它,我看到在发送的请求中添加了distrib=false参数。当用distrib=true手动执行查询(不使用spark)时,结果很好。

我试图通过更改"solr.params"字典中的options值来设置spark发送的参数(我使用pyspark):

options = {
    "collection": "collection_name",
    "zkhost": "server:port",
    "solr.params": "distrib=true"
}

spark.read.format("solr").options(**options).load().show()

此更改没有任何效果:我仍然在日志中看到正在发送distrib=false参数。通过"solr.params"键传递的其他参数(例如fq=something)会对结果产生影响。但无论我做什么,看起来火花仍坚持发送distrib=false

如何通过spark-solr强制进行分布式搜索?

1 个答案:

答案 0 :(得分:0)

简单的解决方案是配置请求处理程序以使用不变量运行分布式查询。即使spark-solr试图在查询时间内更改它,不变量也会强制distrib参数具有true值。可以通过在solrconfig.xml中的请求处理程序条目的定义下添加以下行来完成对不变量的介绍:

<lst name="invariants">
   <str name="distrib">true</str>
</lst>

虽然引入不变量将解决问题,但我认为这是一种彻底的解决方案。这是因为解决方案涉及隐藏重载参数值的行为。通过引入不变量,您无法决定将distrib设置为false:即使您的请求明确这样做,distrib的值仍然是true。这在我看来风险太大,这就是为什么我建议另一个可能难以实施的解决方案,但不会受到这个缺陷的影响。

解决方案是实现一个查询组件,只有在收到distrib=true标志作为参数时才会强制forceDistrib=true

public class ForceDistribComponent extends SearchComponent {
   private static String FORCE_DISTRIB_PARAM = "forceDistrib";

   @Override
   public void prepare(ResponseBuilder rb) throws IOException {
      ModifiableSolrParams params = new ModifiableSolrParams(rb.req.getParams());
      if (!params.getBool(FORCE_DISTRIB_PARAM, false)) return;
      params.set(CommonParams.DISTRIB, true);
      params.set(FORCE_DISTRIB_PARAM, false);
      rb.req.setParams(params);
   }
}

构建组件后,您可以通过将组件添加到solrconfig.xml来配置solr以使用它,并将请求处理程序设置为使用它。

将组件添加到solrconfig.xml是通过将以下条目添加到solrconfig.xml文件来完成的:

<searchComponent name="forceDistrib" class="ForceDistribComponent"/>

配置请求处理程序以使用forceDistrib组件是通过将其添加到请求处理程序条目下的组件列表来完成的。它必须是列表中的第一个组件:

<arr name="components">
   <str>forceDistrib</str>
   <str>query</str>
   ...
</arr>

这个解决方案虽然比简单地引入不变量更复杂,但更安全。