Solr分布式搜索技术实现分析

2019-03-27 01:16|来源: 网路

原文出处:http://www.cnblogs.com/gpcuster/archive/2012/10/10/2718341.html

概述

Solr单机支持的搜索数据量是有一定上限的,这个取决于搜索的复杂程度,服务器的硬件配置与业务的要求等等,所以将搜索功能分布化将是对于大数据搜索的一个必然趋势。

Solr1.3版本开始,自带了分布式搜索(Distributed Search)。这个功能使得Solr能够通过多服务器进行横行扩展,对数据进行水平拆分,从而支持海量数据的搜索功能。

Solr-3.6.1版本对分布式搜索的支持功能如下:

搜索功能模块

是否支持分布式搜索

Query component

Y

Facet component

Y

Highlighting component

Y

Spell Check Component

Y

Terms Component

Y

Stats component

Y

Term Vector Component

Y

Debug component

Y

Grouping component

Y

QueryElevationComponent

N

MoreLikeThis

N

Join

N

由于业务功能和时间的缘故,本文将只讨论Query component的技术实现逻辑。

注意事项

在使用Solr进行分布式搜索的时候,需要注意以下细节:

  • schema.xml中定义的unique key必须保存在索引中。因为Solr在进行2nd phrase搜索时需要使用这个unique key进行数据一致性的二次确认与获取搜索要求查询的字段数据。
  • 分布在不同服务器中的索引文件中包含的unique key不要有重复。因为Solr在进行1st phrase搜索时需要根据这些unique key进行排序与去重,如果unique key有重复,包含相同unique keydoc结果将随机返回。
  • 搜索结果不要有过多的翻页。因为Solr的分布式搜索中,会将需要翻页排序后的总结果全部返回给proxy solr server进行汇总排序,如果翻页过多,那么对网络带宽将会照成一定的压力。(英文原文:Makes it more inefficient to use a high "start" parameter. For example, if you request start=500000&rows=25 on an index with 500,000+ docs per shard, this will currently result in 500,000 records getting sent over the network from the shard to the coordinating Solr instance. If you had a single-shard index, in contrast, only 25 records would ever get sent over the network. (Granted, setting start this high is not something many people need to do.),解释:start值过大就意味着翻页很多次,为什么第一个shard会传500000个docs到第二个shard?因为要对分值进行排序,返回分值最高的25条,所以要将shard1和shard2的结果集合并,在合并后的结果集里返回分值最高的25条。
  • 注意HTTP连接数。因为Solr的分布式搜索中,服务器可能既是search server又是proxy server,一遍等待http请求应答有一遍处理http请求,多台服务器之间就可能会出现死锁。

分布式搜索逻辑实现

Query component的实现原则为:Multi-phased approach, allowing for inconsistency,具体的实现细节如下:

  1. 客户端发送搜索请求给Solr集群中的任意一台服务器SP
  2. SP服务器处理分布式查询请求
    1. Phase One
      1. 构建查询请求,只获取查询Docunique keysort field字段。
      2. 将构建好的请求通过HTTP发送给每一个Solr Shard节点。
      3. 等待Solr Shard节点返回查询结果。
      4. 根据排序规则,逐个合并Solr Shard节点返回的查询结果。
    2. Phase Two
      1. 构建查询请求,根据unique key查询客户端查询的相关字段数据。
      2. 将构建好的请求通过HTTP发送给每一个需要请求的Solr Shard节点。
      3. 等待Solr Shard节点返回查询结果。
      4. 逐个合并Solr Shard节点返回的查询结果,构建本次查询的最终结果。
      5. SP服务器将分布式查询结果返回给客户端

注意:当前的版本中,分布式查询中如果有某一个Shard异常,整体的查询将失败。

参考文档

看完这篇分析总体来说觉得分布式搜索还存在许多弊端,但是是4.0版本以前唯一的处理大数据搜索的方式了,将索引库分片单独存储,比如按省分片存储商家数据等等,有效的降低索引库的大小。对于其中某一个SHARD异常导致查询失败的情况,可以用TOMCAT集群来处理,通过索引的replication在多个TOMCAT之间同步索引,当一个群组瘫痪时,将请求发送到另外一个群组,不过分片过多的话,用到的TOMCAT服务器也越多,架构太复杂不便于维护了。

所以感觉实在是逼不得已才去使用分布式搜索。

去研究一下4.X版本的solrCloud看看对这些问题能不能解决。


转自:http://blog.csdn.net/xiao_jun_0820/article/details/8777145

相关问答

更多
  • 建议你找卓新思创的老师交流一下,技术方面还是有人带着学得快。我们公司最近也在推新技术学习,刚开始大家自己看教程,折腾了半年也没有成效。
  • Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http GSolret操作提出查找请求,并得到XML格式的返回结果
  • 一、DFS为何物? DFS 即微软分布式文件系统的简称,系统管理员可以利用它来有效的整合网络资源,并把这些资源以单一的层次结构呈现给网络用户。管理员利用它可以把资源发布成一 个树形结构,这样大大简化了为用户进行资源配置和对资源管理的工作量。我们可以在不同的机器上调整和移动文件,这不会影响到用户的访问。 二、为什么要使用DES? 1、DFS使用了现有网络中的Share权限,管理员不必进行新的配置 2、通过一个DFS树形结构用户就可以访问多个网络资源,而不用再把远程驱动器映射到本地共享资源中。 3、DFS可以配 ...
  • 分布式系统(distributed system)是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。内聚性是指每一个数据库分布节点高度自治,有本地的数据库管理系统。透明性是指每一个数据库分布节点对用户的应用来说都是透明的,看不出是本地还是远程。在分布式数据库系统中,用户感觉不到数据是分布的,即用户不须知道关系是否分割、有无复本、数据存于哪个站点以及事务在哪个站点上执行等。 故名思义,分布式 ...
  • 虽然我在这里遇到了一个老问题,但我迟到了一点。 答案是Solr Cloud在内部处理复制。 Solr Cloud wiki页面详细解释了这一点。 如果你设置了numShards = 2并添加更多的服务器(这样你总共有四个),分片将被复制到新的服务器 - 确保你的分片位于多个节点上。 直接回答你的问题; SolrCloud为你做了复制设置和逻辑,你应该让它做它自己的事情,而不是在混合中引入“手动”设置复制。 SolrCloud的重点在于隐藏复制和共享逻辑,允许您在可用时简单添加更多服务器。 当然,您可以创建逻 ...
  • 在Solr 4.7中添加了一个类MiniSolrCloudCluster,它实际上在本地“部署”(如果你只想要ram或在temp目录上)一个完整的solr集群,包括zookeeper,shards和所有东西,供你的测试使用。 你可以在这里找到jira: https : //issues.apache.org/jira/browse/SOLR-5865 我已经成功地使用它来对solr分布式组件进行测试,以Solr测试为例,如下所示: private static MiniSolrCloudCluste ...
  • 假设您的分片是: “localhost:8983 / solr”和“localhost:7574 / solr” 您可以使用solrj执行分布式搜索,例如: String shards = "localhost:8983/solr,localhost:7574/solr"; StringBuffer request = new StringBuffer(); request.append("&q=" + query); request.append("&shards=" + shards); SolrPar ...
  • 简单的解决方案是配置请求处理程序以使用不变量来运行分布式查询。 即使spark-solr试图在查询时间内改变它,该变量也会强制distrib参数具有true值。 通过在solrconfig.xml中的请求处理程序条目的定义下添加以下几行可以引入不变量: true 虽然引入不变量将会解决问题,但我认为这是一种彻底的解决方案。 这是因为解决方案涉及隐藏一个行为,在该行为中,您将参数值重载。 ...
  • 总之,没有。 Solr Distributed Search的工作方式是传入一个shards参数,该参数列出了运行查询的分片。 您查询的Solr分片然后将相同的查询传递给分片列表中列出的所有solr分片,等待结果然后合并它们。 它无法向每个分片传递不同的查询。 我通过这里的文档阅读: https : //wiki.apache.org/solr/DistributedSearch 您可以编写自定义代码来执行此操作,但这对您的用例来说似乎有些过分。 我只想在所有核心上运行相同的查询。 In short, no ...