環境:
虛擬機環境centos6.4 64位系統 三臺硬盤50G 內存的虛擬機 網卡模式是NAT(測試環境推薦使用NAT,實際生產時可以使用橋接以便外網訪問)
環境搭建:
1.安裝虛擬機 (這裏不作贅述)。
2.虛擬機安裝成功後,用java –version命令查看是否自帶OpenJdk,如有則卸載此jdk。(這裏不作贅述)
3.爲虛擬機安裝jdk(這裏不作贅述)。
4.爲每臺虛擬機配置結點映射(若不使用域名此步驟可忽略):以虛擬機master爲例,修改 /etc/hosts 文件以下圖 html
其中後面的master slave1和slave2是做爲別名以便於與network中的HOSTNAME作映射。
ZooKeeper集羣中具備兩個關鍵的角色:Leader和Follower。
集羣中全部的結點做爲一個總體對分佈式應用提供服務,集羣中每一個結點之間 都互相鏈接,
因此,在配置的ZooKeeper集羣的時候,每個結點的host到IP地址的映射都要配置上集羣中其它結點的映射信息。
ZooKeeper採用一種稱爲Leader election的選舉算法。在整個集羣運行過程當中,只有一個Leader,其餘的都是Follower,
若是ZooKeeper集羣在運行過程當中 Leader出了問題,系統會採用該算法從新選出一個Leader。
所以,各個結點之間要可以保證互相鏈接,必須配置上述映射。
ZooKeeper集羣啓動的時候,會首先選出一個Leader,在Leader election過程當中,某一個知足選舉算的結點就能成爲Leader。
整個集羣的架構能夠參考http://zookeeper.apache.org/doc/trunk/zookeeperOver.html#sc_designGoals
java
5.修改/etc/sysconfig裏的network配置文件(這裏以master爲例):HOSTNAME=master linux
2、正式solrCloud集羣搭建
Zookeeper Distributed模式集羣搭建 web
首先要明確的是,ZooKeeper集羣是一個獨立的分佈式協調服務集羣,「獨立」的含義就是說,
若是想使用ZooKeeper實現分佈式應用的協調與管 理,簡化協調與管理,任何分佈式應用均可以使用,
這就要歸功於Zookeeper的數據模型(Data Model)和層次命名空間(Hierarchical Namespace)結構,
詳細能夠參考http://zookeeper.apache.org/doc/trunk/zookeeperOver.html。在設計你的分佈式應用協調服務時,
首要的就是考慮如何組織層次命名空間。
Zookeeper集羣的機器個數推薦是奇數臺,半數機器掛掉,服務是能夠正常提供的
如今以master爲例搭建zookeeper集羣:
1.在根目錄下新建soft文件夾,將zookeeper.3.4.5.tar.gz包上傳至soft目錄下並解壓縮.
2.新建/soft/zookeeper-data 文件夾 //zookeeper的數據存儲位置
新建/soft/zookeeper-data/logs 文件夾 // zookeeper的日誌文件位置 算法
3.將/soft/ zookeeper-3.4.5/ conf 下的zoo_sample.cfg文件名改成zoo.cfg 並修改zoo.cfg文件以下圖: apache
或者使用域名 windows
tickTime:這個時間是做爲 Zookeeper 服務器之間或客戶端與服務器之間維持心跳的時間間隔,也就是每一個 tickTime 時間就會發送一個心跳。
initLimit:這個配置項是用來配置 Zookeeper 接受客戶端(這裏所說的客戶端不是用戶鏈接 Zookeeper 服務器的客戶端,而是 Zookeeper服務器集羣中鏈接到 Leader 的 Follower 服務器)初始化鏈接時最長能忍受多少個心跳時間間隔數。當已經超過 10 個心跳的時間(也就是tickTime)長度後 Zookeeper 服務器尚未收到客戶端的返回信息,那麼代表這個客戶端鏈接失敗。總的時間長度就是5*2000=10秒。
syncLimit:這個配置項標識 Leader 與 Follower 之間發送消息,請求和應答時間長度,最長不能超過多少個 tickTime 的時間長度,總的時間長度就是 2*2000=4 秒
dataDir:顧名思義就是 Zookeeper 保存數據的目錄,默認狀況下,Zookeeper 將寫數據的日誌文件也保存在這個目錄裏。
dataLogDir: Zookeeper的日誌文件位置。
server.A=B:C:D:其中 A 是一個數字,表示這個是第幾號服務器;B是這個服務器的 ip 地址;C 表示的是這個服務器與集羣中的 Leader服務器交換信息的端口;D 表示的是萬一集羣中的 Leader 服務器掛了,須要一個端口來從新進行選舉,選出一個新的 Leader,而這個端口就是用來執行選舉時服務器相互通訊的端口。若是是僞集羣的配置方式,因爲 B 都是同樣,因此不一樣的 Zookeeper 實例通訊端口號不能同樣,因此要給它們分配不一樣的端口號。
clientPort:這個端口就是客戶端鏈接 Zookeeper 服務器的端口,Zookeeper 會監聽這個端口,接受客戶端的訪問請求。 centos
4.配置完成後把配置發送到其餘兩臺機子
5.分別在每臺機器的/soft/zookeeper-data 下建立myid文件存儲該機器的標識碼 好比server.1 的標識碼就是 「1」 myid文件的內容就一行: 1
6.配置完成後依次啓動(注意啓動前必定要關閉防火牆,不然zookeeper查看啓動後的狀態會查看不到各自的角色)master、 slave1和slave2的zookeeper服務,啓動成功後查看啓動狀態以下: tomcat
master: 服務器
slave1:
slave2:
經過狀態查詢結果能夠看出,slave1被選做爲了Leader其他的兩個結點是Follower。
另外,能夠經過客戶端腳本,鏈接到ZooKeeper集羣上。對於客戶端來講,ZooKeeper是一個總體(ensemble),
鏈接到ZooKeeper集羣實際上感受在獨享整個集羣的服務,因此,你能夠在任何一個結點上創建到服務集羣的鏈接。
Solrcloud分佈式集羣搭建
1.將apache-tomcat-7.0.37-windows-x64包上傳至soft下並解壓
2.在本地解壓solr-4.3.1.tgz包,解壓後找到solr-4.3.1\example\webapps\solr.war並將solr.war解壓至solr文件夾。
3.將solr-4.3.1\example\lib\ext下的jar包放到solr\WEB-INF\lib下。
4.(以其中的一臺虛擬機master爲例)建立/usr/local/solrcloud目錄 /usr/local/solrcloud/config-files目錄和/usr/local/solrcloud/solr-lib目錄。
5.在/usr/local/solrcloud/config-files目錄下放置apache-solr-4.3.1\example\solr\collection1\conf 下的全部文件。
6.在目錄/usr/local/solrcloud/solr-lib目錄下放置solr\WEB-INF\lib下的全部jar包。
7.將solr上傳至/soft/apache-tomcat-7.0.37/webapps下。
8.添加停詞,擴展詞,ik分詞器:下載IKAnalyzer包,將IKAnalyzer解壓文件夾下的stopword.dic和IKAnalyzer.cfg.xml複製到tomcat/webapps/solr/WEB-INF/classes下,再新建一個ext.dic,裏面的格式和stopword.dic一致。並修改IKAnalyzer.cfg.xml以下所示,能夠配置多箇中止詞或者擴展詞庫文件(具體詳細內容可見http://lucien-zzy.iteye.com/blog/2002087)。
Xml代碼
- <properties>
- <comment>IK Analyzer 擴展配置</comment>
- <!--用戶能夠在這裏配置本身的擴展字典 -->
- <entry key="ext_dict">ext.dic;</entry>
- <!--用戶能夠在這裏配置本身的擴展中止詞字典-->
- <entry key="ext_stopwords">stopword.dic;stopword_chinese.dic;</entry>
- </properties>
Ik分詞器配置見http://lucien-zzy.iteye.com/blog/2002087
9.建立solr的數據目錄/soft/solr-cores並在該目錄下生成solr.xml 這是solr的核配置文件
Xml代碼
- <?xml version="1.0" encoding="UTF-8" ?>
- <solr persistent="true">
- <logging enabled="true">
- <watcher size="100" threshold="INFO" />
- </logging>
- <cores defaultCoreName="collection1" adminPath="/admin/cores" host="${host:}" hostPort="8080" hostContext="${hostContext:solr}" zkClientTimeout="${zkClientTimeout:15000}">
- </cores>
- </solr>
這裏,咱們並無配置任何的core元素,這個等到整個配置安裝完成以後,經過SOLR提供的REST接口,來實現Collection以及Shard的建立,從而來更新這些配置文件。
10.建立/soft/apache-tomcat-7.0.37/ conf/ Catalina 目錄 和/soft/apache-tomcat-7.0.37/conf/Catalina/localhost目錄
11.在/soft/apache-tomcat-7.0.37/conf/Catalina/localhost 下建立solr.xml
Xml代碼
- <?xml version="1.0" encoding="UTF-8"?>
- <Context docBase="/soft/apache-tomcat-7.0.37/webapps/solr" debug="0" crossContext="true">
- <Environment name="solr/home" type="java.lang.String" value="/soft/solr-cores" override="true"/>
- </Context>
此文件爲Solr/home的配置文件
12.修改tomcat/bin/cataina.sh 文件,在最上方加入
JAVA_OPTS="-DzkHost=master:2181,slave1:2181,slave2:2181"
或直接使用ip JAVA_OPTS="-DzkHost=192.168.91.128:2181,192.168.91.129:2181,192.168.91.130:2181"
加入以上內容其實就是指明瞭zookeeper集羣所在位置。
13.將以上配置分別發到其餘兩臺機子。
14.SolrCloud是經過ZooKeeper集羣來保證配置文件的變動及時同步到各個節點上,因此,須要將配置文件上傳到ZooKeeper集羣中:執行以下操做(如下ip都可使用域名進行操做)。
Java代碼
- java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -cmd upconfig -zkhost 192.168.91.128:2181,192.168.91.129:2181,192.168.91.130:2181 -confdir /usr/local/solrcloud/config-files/ -confname myconf
連接zookeeper的配置內容:
Java代碼
- java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -cmd linkconfig -collection collection1 -confname myconf -zkhost 192.168.91.128:2181,192.168.91.129:2181,192.168.91.130:2181
操做如圖:
15.上傳完成之後,咱們檢查一下ZooKeeper上的存儲狀況:
Java代碼
- [root@master ~]# cd /soft/zookeeper-3.4.5/bin
- [root@master bin]# ./zkCli.sh -server 192.168.91.128:2181
- ...
- [zk: 192.168.91.128:2181(CONNECTED) 0] ls /
- [configs, collections, zookeeper]
- [zk: 192.168.91.128:2181(CONNECTED) 1] ls /configs
- [myconf]
- [zk: 192.168.91.128:2181(CONNECTED) 2] ls /configs/myconf
- [admin-extra.menu-top.html, currency.xml, protwords.txt, mapping-FoldToASCII.txt, solrconfig.xml, lang, stopwords.txt, spellings.txt, mapping-ISOLatin1Accent.txt, admin-extra.html, xslt, scripts.conf, synonyms.txt, update-script.js, velocity, elevate.xml, admin-extra.menu-bottom.html, schema.xml]
- [zk: 192.168.91.128:2181(CONNECTED) 3]
16.啓動tomcat,首先啓動master結點上的tomcat
這時候,SolrCloud集羣中只有一個活躍的節點,並且默認生成了一個collection1實例,這個實例實際上虛擬的,由於經過web界面沒法訪問http://192.168.91.128:8080/solr/,看不到任何有關SolrCloud的信息,如圖所示:
17.啓動其餘兩個結點上的tomcat
18.查看ZooKeeper集羣中數據狀態:
這時,已經存在3個活躍的節點了,可是SolrCloud集羣並無更多信息,
訪問http://192.168.91.128:8080/solr/後,同上面的圖是同樣的,沒有SolrCloud相關數據。
19.建立Collection、Shard和Replication
建立Collection及初始Shard:
經過REST接口來建立Collection
Java代碼
- curl 'http://192.168.91.128:8080/solr/admin/collections?action=CREATE&name=mycollection&numShards=3&replicationFactor=1'
上面連接中的幾個參數的含義,說明以下:
name 待建立Collection的名稱
numShards 分片的數量
replicationFactor 複製副本的數量
操做如圖:
執行上述操做若是沒有異常,已經建立了一個Collection,名稱爲mycollection,並且每一個節點上存在一個分片。這時,也能夠查看ZooKeeper中狀態:
能夠經過Web管理頁面,訪問http://192.168.91.128:8080/solr/#/~cloud查看SolrCloud集羣的分片信息,如圖所示:
由上圖能夠看到,對應節點上SOLR分片的對應關係:
shard1 192.168.91.130 slave2
shard2 192.168.91.129 slave1
shard3 192.168.91.128 master
實際上,咱們從master節點能夠看到,SOLR的配置文件內容,已經發生了變化,以下所示:
咱們能夠再經過REST接口分別在slave一、slave2結點上建立兩個collection,分別命名爲mycollection一、mycollection2
建立後的訪問連接如圖:
建立Replication:
下面對已經建立的初始分片進行復制:
master結點 上的分片shard1已經存在slave2,如今咱們複製分片到master和slave1上
執行操做:
Java代碼
- curl 'http://192.168.91.128:8080/solr/admin/cores?action=CREATE&collection=mycollection&name=mycollection_shard1_replica1&shard=shard1'
Java代碼
- curl 'http://192.168.91.129:8080/solr/admin/cores?action=CREATE&collection=mycollection&name=mycollection_shard1_replica2&shard=shard1'
操做如圖:
訪問連接查看效果圖:
此時在master結點的slave2的shard1分片上多了兩個副本,名稱分別爲:mycollection_shard1_replica1和mycollection_shard1_replica2
咱們再次從master節點能夠看到,SOLR的配置文件內容,又發生了變化,以下所示:
到此爲止,咱們基於3個物理節點,配置完成了SolrCloud集羣多結點的配置。
3、索引操做實例
Java代碼
- import java.io.IOException;
- import java.net.MalformedURLException;
- import java.util.ArrayList;
- import java.util.Collection;
- import org.apache.solr.client.solrj.SolrQuery;
- import org.apache.solr.client.solrj.SolrServer;
- import org.apache.solr.client.solrj.SolrServerException;
- import org.apache.solr.client.solrj.impl.CloudSolrServer;
- import org.apache.solr.client.solrj.response.QueryResponse;
- import org.apache.solr.common.SolrDocument;
- import org.apache.solr.common.SolrDocumentList;
- import org.apache.solr.common.SolrInputDocument;
-
- /**
- * SolrCloud 索引增刪查測試
- * @author ziyuzhang
- *
- */
- public class SolrCloud {
- private static CloudSolrServer cloudSolrServer;
-
- private static synchronized CloudSolrServer getCloudSolrServer(final String zkHost) {
- if(cloudSolrServer == null) {
- try {
- cloudSolrServer = new CloudSolrServer(zkHost);
- }catch(MalformedURLException e) {
- System.out.println("The URL of zkHost is not correct!! Its form must as below:\n zkHost:port");
- e.printStackTrace();
- }catch(Exception e) {
- e.printStackTrace();
- }
- }
-
- return cloudSolrServer;
- }
-
- private void addIndex(SolrServer solrServer) {
- try {
- SolrInputDocument doc1 = new SolrInputDocument();
- doc1.addField("id", "421245251215121452521251");
- doc1.addField("area", "北京");
- SolrInputDocument doc2 = new SolrInputDocument();
- doc2.addField("id", "4224558524254245848524243");
- doc2.addField("area", "上海");
-
- SolrInputDocument doc3 = new SolrInputDocument();
- doc3.addField("id", "4543543458643541324153453");
- doc3.addField("area", "重慶");
-
- Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
- docs.add(doc1);
- docs.add(doc2);
- docs.add(doc3);
-
- solrServer.add(docs);
- solrServer.commit();
-
- }catch(SolrServerException e) {
- System.out.println("Add docs Exception !!!");
- e.printStackTrace();
- }catch(IOException e){
- e.printStackTrace();
- }catch (Exception e) {
- System.out.println("Unknowned Exception!!!!!");
- e.printStackTrace();
- }
-
- }
-
-
- public void search(SolrServer solrServer, String String) {
- SolrQuery query = new SolrQuery();
- query.setQuery(String);
- try {
- QueryResponse response = solrServer.query(query);
- SolrDocumentList docs = response.getResults();
-
- System.out.println("文檔個數:" + docs.getNumFound());
- System.out.println("查詢時間:" + response.getQTime());
-
- for (SolrDocument doc : docs) {
- String area = (String) doc.getFieldValue("area");
- Long id = (Long) doc.getFieldValue("id");
- System.out.println("id: " + id);
- System.out.println("area: " + area);
- System.out.println();
- }
- } catch (SolrServerException e) {
- e.printStackTrace();
- } catch(Exception e) {
- System.out.println("Unknowned Exception!!!!");
- e.printStackTrace();
- }
- }
-
- public void deleteAllIndex(SolrServer solrServer) {
- try {
- solrServer.deleteByQuery("*:*");// delete everything!
- solrServer.commit();
- }catch(SolrServerException e){
- e.printStackTrace();
- }catch(IOException e) {
- e.printStackTrace();
- }catch(Exception e) {
- System.out.println("Unknowned Exception !!!!");
- e.printStackTrace();
- }
- }
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- final String zkHost = "192.168.91.128:2181,192.168.91.129:2181,192.168.91.130:2181";
- final String defaultCollection = "mycollection";
- final int zkClientTimeout = 20000;
- final int zkConnectTimeout = 1000;
-
- CloudSolrServer cloudSolrServer = getCloudSolrServer(zkHost);
- System.out.println("The Cloud SolrServer Instance has benn created!");
- cloudSolrServer.setDefaultCollection(defaultCollection);
- cloudSolrServer.setZkClientTimeout(zkClientTimeout);
- cloudSolrServer.setZkConnectTimeout(zkConnectTimeout);
- cloudSolrServer.connect();
- System.out.println("The cloud Server has been connected !!!!");
- //測試實例!
- SolrCloud test = new SolrCloud();
- // System.out.println("測試添加index!!!");
- //添加index
- // test.addIndex(cloudSolrServer);
-
- // System.out.println("測試查詢query!!!!");
- // test.search(cloudSolrServer, "id:*");
- //
- // System.out.println("測試刪除!!!!");
- // test.deleteAllIndex(cloudSolrServer);
- // System.out.println("刪除全部文檔後的查詢結果:");
- test.search(cloudSolrServer, "zhan");
- // System.out.println("hashCode"+test.hashCode());
-
- // release the resource
- cloudSolrServer.shutdown();
-
- }
-
- }
注:別忘了修改核心配置文件schema.xml,要有id 和 area,注意類型的匹配。
轉載請註明出處:http://lucien-zzy.iteye.com/admin/blogs/2002463