SolrCloud(solr 雲)是Solr提供的分佈式搜索方案,當你須要大規模,容錯,分佈式索引和檢索能力時使用 SolrCloud。當一個系統的索引數據量少的時候是不須要使用SolrCloud的,當索引量很大,搜索請求併發很高,這時須要使 用SolrCloud來知足這些需求。html
SolrCloud是基於Solr和Zookeeper的分佈式搜索方案,它的主要思想是使用Zookeeper做爲集羣的配置信息中心。java
它有幾個特點功能:web
1)集中式的配置信息spring
2)自動容錯數據庫
3)近實時搜索apache
4)查詢時自動負載均衡編程
顧名思義zookeeper就是動物園管理員,他是用來管hadoop(大象)、Hive(蜜蜂)、pig(小豬)的管理員, Apache Hbase和 Apache Solr 的分佈式集羣都用到了zookeeper;Zookeeper:是一個分佈式的、開源的程序協調服務,是hadoop項目下的一個子項目。json
1、配置管理vim
在咱們的應用中除了代碼外,還有一些就是各類配置。好比數據庫鏈接等。通常咱們都是使用配置文件的方式,在代碼中引入這些配置文件。可是當咱們只有一種配置,只有一臺服務器,而且不常常修改的時候,使用配置文件是一個很好的作法,可是若是咱們配置很是多,有不少服務器都須要這個配置,並且還多是動態的話使用配置文件就不是個好主意了。這個時候每每須要尋找一種集中管理配置的方法,咱們在這個集中的地方修改了配置,全部對這個配置感興趣的均可以得到變動。好比咱們能夠把配置放在數據庫裏,而後全部須要配置的服務都去這個數據庫讀取配置。可是,由於不少服務的正常運行都很是依賴這個配置,因此須要這個集中提供配置服務的服務具有很高的可靠性。通常咱們能夠用一個集羣來提供這個配置服務,可是用集羣提高可靠性,那如何保證配置在集羣中的一致性呢? 這個時候就須要使用一種實現了一致性協議的服務了。Zookeeper就是這種服務,它使用Zab這種一致性協議來提供一致性。如今有不少開源項目使用Zookeeper來維護配置,好比在HBase中,客戶端就是鏈接一個Zookeeper,得到必要的HBase集羣的配置信息,而後才能夠進一步操做。還有在開源的消息隊列Kafka中,也使用Zookeeper來維護broker的信息。在Alibaba開源的SOA框架Dubbo中也普遍的使用Zookeeper管理一些配置來實現服務治理。tomcat
2、名字服務
名字服務這個就很好理解了。好比爲了經過網絡訪問一個系統,咱們得知道對方的IP地址,可是IP地址對人很是不友好,這個時候咱們就須要使用域名來訪問。可是計算機是不能是別域名的。怎麼辦呢?若是咱們每臺機器裏都備有一份域名到IP地址的映射,這個卻是能解決一部分問題,可是若是域名對應的IP發生變化了又該怎麼辦呢?因而咱們有了DNS這個東西。咱們只須要訪問一個你們熟知的(known)的點,它就會告訴你這個域名對應的IP是什麼。在咱們的應用中也會存在不少這類問題,特別是在咱們的服務特別多的時候,若是咱們在本地保存服務的地址的時候將很是不方便,可是若是咱們只須要訪問一個你們都熟知的訪問點,這裏提供統一的入口,那麼維護起來將方便得多了。
3、分佈式鎖
其實在第一篇文章中已經介紹了Zookeeper是一個分佈式協調服務。這樣咱們就能夠利用Zookeeper來協調多個分佈式進程之間的活動。好比在一個分佈式環境中,爲了提升可靠性,咱們的集羣的每臺服務器上都部署着一樣的服務。可是,一件事情若是集羣中的每一個服務器都進行的話,那相互之間就要協調,編程起來將很是複雜。而若是咱們只讓一個服務進行操做,那又存在單點。一般還有一種作法就是使用分佈式鎖,在某個時刻只讓一個服務去幹活,當這臺服務出問題的時候鎖釋放,當即fail over到另外的服務。這在不少分佈式系統中都是這麼作,這種設計有一個更好聽的名字叫Leader Election(leader選舉)。好比HBase的Master就是採用這種機制。但要注意的是分佈式鎖跟同一個進程的鎖仍是有區別的,因此使用的時候要比同一個進程裏的鎖更謹慎的使用。
4、集羣管理
在分佈式的集羣中,常常會因爲各類緣由,好比硬件故障,軟件故障,網絡問題,有些節點會進進出出。有新的節點加入進來,也有老的節點退出集羣。這個時候,集羣中其餘機器須要感知到這種變化,而後根據這種變化作出對應的決策。好比咱們是一個分佈式存儲系統,有一箇中央控制節點負責存儲的分配,當有新的存儲進來的時候咱們要根據如今集羣目前的狀態來分配存儲節點。這個時候咱們就須要動態感知到集羣目前的狀態。還有,好比一個分佈式的SOA架構中,服務是一個集羣提供的,當消費者訪問某個服務時,就須要採用某種機制發現如今有哪些節點能夠提供該服務(這也稱之爲服務發現,好比Alibaba開源的SOA框架Dubbo就採用了Zookeeper做爲服務發現的底層機制)。還有開源的Kafka隊列就採用了Zookeeper做爲Cosnumer的上下線管理。
本教程的這套安裝是單機版的安裝,因此採用僞集羣的方式進行安裝,若是是真正的生產環境,將僞集羣的ip改下就能夠了,步驟是同樣的。
SolrCloud結構圖以下:
須要三個zookeeper節點
四個solr節點。
使用僞分佈式實現solr集羣。須要三個zookeeper實例,4個tomcat實例,能夠在一臺虛擬機上模擬。建議虛擬機1G以上內存。
三個zookeeper實例。Zookeeper也是java開發的因此須要安裝jdk。
一、Linux系統
二、Jdk環境。
三、Zookeeper。
第一步:把zookeeper的安裝包上傳到服務器
第二步:解壓縮。
[root@bogon ~]# tar -zxf zookeeper-3.4.6.tar.gz
[root@bogon ~]#
第三步:在/usr/local/目錄下建立一個solrcloud目錄。把zookeeper解壓後的文件夾複製到此目錄下三份。分別命名爲zookeeper一、二、3
[root@bogon ~]# mkdir /usr/local/solrcloud
[root@bogon ~]# mv zookeeper-3.4.6 /usr/local/solrcloud/zookeeper1
[root@bogon ~]# cd /usr/local/solrcloud
[root@bogon solrcloud]# ll
total 4
drwxr-xr-x. 10 1000 1000 4096 Feb 20 2014 zookeeper1
[root@bogon solrcloud]# cp -r zookeeper1/ zookeeper2
[root@bogon solrcloud]# cp -r zookeeper1/ zookeeper3
[root@bogon solrcloud]#
第四步:配置zookeeper。
一、在每一個zookeeper文件夾下建立一個data目錄。
二、在data文件夾下建立一個文件名稱爲myid,文件的內容就是此zookeeper的編號一、二、3
[root@bogon data]# echo 1 >> myid
[root@bogon data]# ll
total 4
-rw-r--r--. 1 root root 2 Sep 17 23:43 myid
[root@bogon data]# cat myid
1
[root@bogon data]#
在zookeeper二、3文件夾下分別建立data目錄和myid文件
[root@bogon solrcloud]# mkdir zookeeper2/data
[root@bogon solrcloud]# echo 2 >> zookeeper2/data/myid
[root@bogon solrcloud]# ll zookeeper2/data
total 4
-rw-r--r--. 1 root root 2 Sep 17 23:44 myid
[root@bogon solrcloud]# cat zookeeper2/data/myid
2
[root@bogon solrcloud]# mkdir zookeeper3/data
[root@bogon solrcloud]# echo 3 >> zookeeper3/data/myid
[root@bogon solrcloud]#
三、把zookeeper1下conf目錄下的zoo_sample.cfg文件複製一份更名爲zoo.cfg
四、修改zoo.cfg的配置
第五步:啓動zookeeper。進入zookeeper1/bin目錄下。
啓動zookeeper:./zkServer.sh start
關閉:./zkServer.sh stop
查看狀態:./zkServer.sh status
[root@bogon solrcloud]# zookeeper1/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/solrcloud/zookeeper1/bin/../conf/zoo.cfg
Mode: follower
[root@bogon solrcloud]# zookeeper2/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/solrcloud/zookeeper2/bin/../conf/zoo.cfg
Mode: leader
[root@bogon solrcloud]# zookeeper3/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/solrcloud/zookeeper3/bin/../conf/zoo.cfg
Mode: follower
[root@bogon solrcloud]#
第一步:建立4個tomcat實例,修改其端口。8080-8083
第二步:解壓solr-4.10.3.tar.gz壓縮包。從壓縮包中複製solr.war到tomcat。
第三步:啓動tomcat解壓war包。把solr-4.10.3目錄下example目錄下的關於日誌相關的jar包添加到solr工程中。
第四步:建立solrhome。修改web.xml指定solrhome的位置。
把solrhome中的配置文件上傳到zookeeper集羣。使用zookeeper的客戶端上傳。
客戶端命令位置:/root/solr-4.10.3/example/scripts/cloud-scripts
./zkcli.sh -zkhost 192.168.25.154:2181,192.168.25.154:2182,192.168.25.154:2183 -cmd upconfig -confdir /usr/local/solrcloud/solrhome1/collection1/conf -confname myconf
紅色字體部分的ip表示zookeeper集羣的ip地址以及對應的端口。
查看配置文件是否上傳成功:
[root@bogon bin]# ./zkCli.sh
Connecting to localhost:2181
[zk: localhost:2181(CONNECTED) 0] ls /
[configs, zookeeper]
[zk: localhost:2181(CONNECTED) 1] ls /configs
[myconf]
[zk: localhost:2181(CONNECTED) 2] ls /configs/myconf
[admin-extra.menu-top.html, currency.xml, protwords.txt, mapping-FoldToASCII.txt, _schema_analysis_synonyms_english.json, _rest_managed.json, solrconfig.xml, _schema_analysis_stopwords_english.json, stopwords.txt, lang, spellings.txt, mapping-ISOLatin1Accent.txt, admin-extra.html, xslt, synonyms.txt, scripts.conf, update-script.js, velocity, elevate.xml, admin-extra.menu-bottom.html, clustering, schema.xml]
[zk: localhost:2181(CONNECTED) 3]
修改solrhome下的solr.xml文件,指定當前實例運行的ip地址及端口號。
修改每一臺solr的tomcat 的 bin目錄下catalina.sh文件中加入DzkHost指定zookeeper服務器地址:
JAVA_OPTS="-DzkHost=192.168.25.154:2181,192.168.25.154:2182,192.168.25.154:2183" 紅色字體的ip表示zookeeper集羣的ip以及端口號
(可使用vim的查找功能查找到JAVA_OPTS的定義的位置,而後添加)
從新啓動tomcat
一個主節點多個備份節點,集羣只有一片。
建立一個兩片的collection,每片是一主一備。
使用如下命令建立:
http://192.168.25.154:8080/solr/admin/collections?action=CREATE&name=collection2&numShards=2&replicationFactor=2
刪除collection1.
http://192.168.25.154:8080/solr/admin/collections?action=DELETE&name=collection1
使用solrj操做集羣環境的索引庫。
1 public class SolrCloudTest { 2 3 @Test 4 public void testAddDocument() throws Exception { 5 //建立一個和solr集羣的鏈接 6 //參數就是zookeeper的地址列表,使用逗號分隔 7 String zkHost = "192.168.25.154:2181,192.168.25.154:2182,192.168.25.154:2183"; 8 CloudSolrServer solrServer = new CloudSolrServer(zkHost); 9 //設置默認的collection 10 solrServer.setDefaultCollection("collection2"); 11 //建立一個文檔對象 12 SolrInputDocument document = new SolrInputDocument(); 13 //向文檔中添加域 14 document.addField("id", "test001"); 15 document.addField("item_title", "測試商品"); 16 //把文檔添加到索引庫 17 solrServer.add(document); 18 //提交 19 solrServer.commit(); 20 } 21 22 @Test 23 public void deleteDocument() throws SolrServerException, IOException { 24 //建立一個和solr集羣的鏈接 25 //參數就是zookeeper的地址列表,使用逗號分隔 26 String zkHost = "192.168.25.154:2181,192.168.25.154:2182,192.168.25.154:2183"; 27 CloudSolrServer solrServer = new CloudSolrServer(zkHost); 28 //設置默認的collection 29 solrServer.setDefaultCollection("collection2"); 30 31 32 solrServer.deleteByQuery("*:*"); 33 solrServer.commit(); 34 } 35 }
修改spring的配置文件,添加集羣版的配置:
1 <!-- 集羣版 --> 2 <bean id="cloudSolrServer" class="org.apache.solr.client.solrj.impl.CloudSolrServer"> 3 <constructor-arg name="zkHost" value="192.168.25.154:2181,192.168.25.154:2182,192.168.25.154:2183"></constructor-arg> 4 <property name="defaultCollection" value="collection2"></property> 5 </bean>