solr-wiki—-solr分布式索引

Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。

What is Distributed Search?

当一个索引越来越大,达到一个单一的系统无法满足磁盘需求的时候,或者一次简单的查询实在要耗费很多的时间的时候,我们就可以使用solr的分布式索引 了。在分布式索引中,原来的大索引,将会分成多个小索引(索引并不定规模小,之前称之为小索引相对于之前的整个索引来讲的),solr可以将从这些小索引 返回的结果合并,然后返回给客户端。

 

如果当前的solr查询请求能够很快被处理,而你只是希望整个搜索系统的处理能力,那么你可以看看这篇文章http://wiki.apache.org/solr/CollectionDistribution。

 

Distributed Searching

参数“shards”能够使请求被分发到shards所指定的小索引上。

shards 的格式  :host:port/base_url[,host:port/base_url]*

目前只有查询请求才能够被分发。能够处理这种要求分发的请求的组件包括standard request handler 、以及它的子类、任何使用 支持分发的组件的其他handler。

 

目前支持分布式查询的组件有:

  • 查询组件-----根据一个请求返回一个文档集。
  • 面查询组件-----目前只支持排序的数字类的域。solr1.4将可以支持字符类型的域
  • 高亮显示组件
  • debug组件。

对于分布式搜索组件,你也可以参考   WritingDistributedSearchComponents 。

 

Distributed Searching Limitations

  • 索引的文档必须有一个 唯一键
  • 当拥有相同的id的文档被查询到时,solr将选择第一个文档。其他的结果将被丢弃。
  • No distributed idf
  • 不支持“竞价排名”组件 QueryElevationComponent
  • 在处理的过程中,也即是 stage过程中,索引是有可能发生变化的。这样在索引更新的时刻,可能会发现搜索的结果跟索引不匹配的现象。
  • 目前并不支持 时间类型的 facetting搜索。(将在solr1.4被支持)
  • 目前只支持 能够排序的域的 facet搜索
  • shard 的数量会受到get请求的方法的限制,大多数的web 服务器,只支持4000个字符左右的get请求。
  • 当“start”这个参数很大的时候,效率比较低下。举个例子,你发起一个请求,参数start=50000 ,rows=25 .被请求的索引的每个shard有500,000个文档。这时候,就会导致500,000条记录,在网络上被传输。

Distributed Deadlock

每个小索引,都有可能既接收顶级的 查询请求,也 向其他的小索引发出次级的查询请求。在这里,你就要小心了,http服务器中设置的能够处理的http请求的线程数一定要大于 这个小索引所接收到的 顶级请求和次级请求的总和。如果配置没有这样配好的话,一个由分发而产生的死锁很有可能会发生。

现在我们来试想下一种最简单的情况,只有两个小索引,每个小索引只能够起一个线程来处理Http 请求。两个索引都能接收顶级请求,并将请求分发给另一个索引。因为它们没有多余的线程可以处理多于一个的请求,所以 servlet容器就会阻塞 刚来的请求,这种情况一直持续到正在处理的请求被处理完毕。(但是,那个正在处理的请求永远也不会被处理完毕,因为它正在等待它分发出去的请求的回应,而 这个分发出去的请求被阻塞了)。

关于死锁,目前笔者想到的方法是设定分发请求的超时时间。这个应该不难实现。

 

Distributed Indexing

怎样建立小索引,这点随用户的喜好而定。一种很简单的方法决定那条记录放在那个索引上可以使用类似这样的一种公式 uniqueId.hashCode() % numServers。

Example

出于测试目的,我们在一台机器的两个不同的端口启动 solr 服务。

 

Shell代码  收藏代码
  1. #make a copy
  2. cd solr
  3. cp -r example example7574
  4. #change the port number
  5. perl -pi -e s/8983/7574/g example7574/etc/jetty.xml  example7574/exampledocs/post.sh
  6. #in window 1, start up the server on port 8983
  7. cd example
  8. java -server -jar start.jar
  9. #in window 2, start up the server on port 7574
  10. cd example7574
  11. java -server -jar start.jar
  12. #in window 3, index some example documents to each server
  13. cd example/exampledocs
  14. ./post.sh [a-m]*.xml
  15. cd ../../example7574/exampledocs
  16. ./post.sh [n-z]*.xml
  17. #now do a distributed search across both servers with your browser or curl
  18. curl 'http://localhost:8983/solr/select?shards=localhost:8983/solr,localhost:7574/solr&indent=true&q=ipod+solr'

发表评论