Solr Distributed Searching (分佈式搜索) 是 solr 1.3 的特性。大索引,可能有多種緣由要把它分紅N個小的索引,能夠把小索引放到其它的機器上,可是我沒這麼多機器怎麼辦呢?solr 1.3 有 multicore,恩,multicore 簡單使用 能夠看我那一篇文章。各個 core 各不干擾,能夠獨立作索引(作索引時,能夠分散到各個core上)。 html
現來看下 Distributed Searching 的效果,打開:http://localhost:8080/solr-cores/core0/select/?q=*%3A*&version=2.2&start=0&rows=10&indent=on&shards=localhost:8080/solr-cores/core0,localhost:8080/solr-cores/core1 能夠看到三條記錄,core0 一條,core1 二條。 tomcat
接着會有一個問題:原來不少程序調用 solr,用如 localhost:8080/solr-cores/select/?q=*%3A* 。又不想改原來的調用的代碼,能不能作到透明呢,探索... 分佈式
記得之前看 solr 文檔時能夠定義一些默認的查詢參數,那 shards 參數也應該能夠寫在配置裏。而後再 core0 的 solrconfig.xml 文件裏的 standard request handler 里加入這參數,如: 性能
<requestHandler name="standard" class="solr.SearchHandler" default="true"> <!-- default values for query parameters --> <lst name="defaults"> <str name="echoParams">explicit</str> <str name="shards">localhost:8080/solr-cores/core0,localhost:8080/solr-cores/core1</str> </lst> </requestHandler>
立刻運行下,但好長時間沒有結果,CPU使用率很高,深思了下,.... 估計是死循環,由於solr解析shards後,調用shard時,是用默認的request handler。而其中一個shard又是core0(自身),那就等於不會結果的遞歸。因此這種方法不行。要避免死循環,就不要core0來作合併,能夠找其它。因而我就加了一個tomcat實例如localhost:8080/solr來作代理(合併結果),結果成功運行。 url
想來想去,能不能不要另外一個tomcat實例呢,直接就用一個 core,繼續再探索... 。 spa
我再開一個 core 就命名爲 core,複製core0爲core。把原來core0/solrconfig.xml的配置的shards去掉,而後在 solr1.3/example/multicore/solr.xml里加,如: 代理
<?xml version="1.0" encoding="UTF-8" ?> <solr persistent="false"> <cores adminPath="/admin/cores"> <core name="core" instanceDir="core" /> <core name="core0" instanceDir="core0" /> <core name="core1" instanceDir="core1" /> </cores> </solr>
結果成功運行。其中,core0、core1是有數據的,而core是沒數據的,core只是運行合併。問題雖然能夠差強人意地解決。可是還有一個問題:原來的程序要調用solr,全部url不能改變,加了core是要改url 的,看源碼時發現它能夠爲core名定義別名,就是用「,」號隔開。改成以下: code
<?xml version="1.0" encoding="UTF-8" ?> <solr persistent="false"> <cores adminPath="/admin/cores"> <core name="core,," instanceDir="core" /> <core name="core0" instanceDir="core0" /> <core name="core1" instanceDir="core1" /> </cores> </solr>
"core,,"爲何是兩個","號呢?。"core,"解析不出兩個名,全部就無別名了。"core,,",解析出兩個名,一是:"core,一是:"" 空串。有了空串就能夠原來的url能夠到達core(合併的core)。 xml
至於死循環問題,同事在看源碼,看是否不用多加一個額外的core來合併。結果他發現一個shard.qt的參數能夠解決此問題,本質就是讓全部的shard調用不用默認request handler,shard.qt能夠作到這一點,使全部的shard調用都加qt參數。 htm
現來改成最後的方案,在core0與core1的solrconfig.xml里加一個request handler如:
<requestHandler name="shard" class="solr.SearchHandler" />
而後再core0的solrconfig.xml的默認request handler加shards參數,與shards.qt爲shard(shard request handler),如:
<requestHandler name="standard" class="solr.SearchHandler" default="true"> <!-- default values for query parameters --> <lst name="defaults"> <str name="echoParams">explicit</str> <str name="shards.qt">shard</str> <str name="shards">localhost:8080/solr-cores/core0,localhost:8080/solr-cores/core1</str> </lst> </requestHandler>
而後在,solr.xml裏的core(沒數據的去掉),把core0加上空的別名,如:
<core name="core0,," instanceDir="core0" />
固然也能夠在core1里加相同的參數,這樣core0與core1的功能是同樣的,就是兩個搜索的url均可以找到全部的數據,我認爲:每一個配置同樣,在索引分到其它機器的時候比較有做用(若是這樣,能夠不用multicore的形式,即原始形式),在外面看不出是幾個索引的,同時合併的任務也均勻一些。
Solr Distributed Searching 固然也會消耗,合併的core會向每一個shard的core發送兩次請求:第一次是找id;第二次是根據id再找文檔。若是有N個shard,能夠認爲有2N+1次請求,1是做合併的請求,其中2N的請求(發每一個shard發送的)是用二進制協議通訊,性能比xml協議好。