1. 程式人生 > >Solr Cloud叢集部署和運維

Solr Cloud叢集部署和運維

1、什麼是SolrCloud

SolrCloud(solr 雲)是Solr提供的分散式搜尋方案,當你需要大規模,容錯,分散式索引和檢索能力時使用 SolrCloud。當一個系統的索引資料量少的時候是不需要使用SolrCloud的,當索引量很大,搜尋請求併發很高,這時需要使用SolrCloud來滿足這些需求。

2、Solr Cloud結構

SolrCloud為了降低單機的處理壓力,需要由多臺伺服器共同來完成索引和搜尋任務。實現的思路是將索引資料進行Shard(分片)拆分,每個分片由多臺的伺服器共同完成,當一個索引或搜尋請求過來時會分別從不同的Shard的伺服器中操作索引。

SolrCloud需要Solr基於Zookeeper部署,Zookeeper是一個叢集管理軟體,由於SolrCloud需要由多臺伺服器組成,由zookeeper來進行協調管理。

下圖是一個SolrCloud應用的例子:

對上圖進行圖解,如下:

物理結構

三個Solr例項( 每個例項包括兩個Core),組成一個SolrCloud。

邏輯結構

索引集合包括兩個Shard(shard1和shard2),shard1和shard2分別由三個Core組成,其中一個Leader兩個Replication,Leader是由zookeeper選舉產生,zookeeper控制每個shard上三個Core的索引資料一致,解決高可用問題。使用者發起索引請求分別從shard1和shard2上獲取,解決高併發問題。

 

collection

Collection在SolrCloud叢集中是一個邏輯意義上的完整的索引結構。它常常被劃分為一個或多個Shard(分片),它們使用相同的配置資訊。

比如:針對商品資訊搜尋可以建立一個collection。

collection=shard1+shard2+....+shardX

Core

每個Core是Solr中一個獨立執行單位,提供 索引和搜尋服務。一個shard需要由一個Core或多個Core組成。由於collection由多個shard組成所以collection一般由多個core組成。

Master或Slave

Master是master-slave結構中的主結點(通常說主伺服器),Slave是master-slave結構中的從結點(通常說從伺服器或備伺服器)。同一個Shard下master和slave儲存的資料是一致的,這是為了達到高可用目的。

Shard

Collection的邏輯分片。每個Shard被化成一個或者多個replication,通過選舉確定哪個是Leader。

 

3、Solr Cloud搭建

SolrCloud結構圖如下:

環境準備
CentOS-6.5-i386-bin-DVD1.iso
jdk-7u72-linux-i586.tar.gz
apache-tomcat-7.0.57.tar.gz
zookeeper-3.4.6.tar.gz
solr-4.10.3.tgz
伺服器7臺: 
zookeeper三臺:192.168.0.5,192.168.0.6,192.168.0.7
Solr三臺:192.168.0.1,192.168.0.2,192.168.0.3,192.168.0.4

環境安裝
CentOs 6.5安裝
略

jdk7安裝
略

zookeeper叢集安裝
解壓zookeeper 安裝包
tar -zxvf zookeeper-3.4.6.tar.gz
將zookeeper-3.4.6拷貝到/usr/local下並將目錄 名改為zookeeper
至此zookeeper的安裝目錄為/usr/local/zookeeper

進入zookeeper資料夾,建立data 和logs
建立目錄並賦於寫許可權
指定zookeeper的資料存放目錄和日誌目錄
拷貝zookeeper配製檔案zoo_sample.cfg

拷貝zookeeper配製檔案zoo_sample.cfg並重命名zoo.cfg 
cp /usr/local/zookeeper/conf/zoo_sample.cfg  /usr/local/zookeeper /conf/zoo.cfg
修改zoo.cfg
加入 dataDir=/usr/local/zookeeper/data
dataLogDir=/ usr/local/zookeeper/logss
server.1=192.168.0.5:2888:3888
server.2=192.168.0.6:2888:3888
server.3=192.168.0.7:2888:3888

zoo.cfg配製完後如下:

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/usr/local/zookeeper/data
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
#dataLogDir=/usr/local/zookeeper/logs
server.1=192.168.0.5:2888:3888
server.2=192.168.0.6:2888:3888
server.3=192.168.0.7:2888:3888

 

進入data資料夾 建立對應的myid檔案
例如server.1為192.168.0.5則 data資料夾下的myid檔案內容為1
server.2為192.168.0.6則 data資料夾下的myid檔案內容為2
依此類推
拷貝zookeeper資料夾到其他機器(192.168.0.6和192.168.0.7)
開啟zookeeper的埠
/sbin/iptables -I INPUT -p tcp --dport 2181 -j ACCEPT
/sbin/iptables -I INPUT -p tcp --dport 2888 -j ACCEPT
/sbin/iptables -I INPUT -p tcp --dport 3888 -j ACCEPT
/sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT   --這裡開啟tomcat 8080埠

/etc/rc.d/init.d/iptables save #將更改進行儲存
/etc/init.d/iptables restart #重啟防火牆以便改動生效


啟動三臺伺服器的zookeeper 
進入/usr/local/zookeeper /bin
./zkServer.sh start
檢視叢集狀態
./zkServer.sh status   
剛啟動可能會有錯誤,叢集中其他節點一併起來後就正常了



tomcat安裝
將apache-tomcat-7.0.57.tar.gz拷貝到/usr/local下並解壓
cd /usr/local
tar -zxvf apache-tomcat-7.0.57.tar.gz
solr單機部署
解壓solr.4.10.3.tgz
在其中一臺伺服器上解壓solr.4.10.3.tgz,將solr.4.10.3.tgz拷貝到/usr/local下,解壓縮:
tar -zxvf solr-4.10.3.tgz
壓縮後在/usr/local下有 solr-4.10.3目錄 。

solrhome
在/home下建立solr作為solrhome 並賦於讀寫許可權
部署solr.war
參考solr單機部署方法。
啟動tomcat 訪問 http://192.168.0.1:8080/solr 如圖,至此單機版solr配製完成

 

olrCloud部署
啟動zookeeper
solrCloud部署依賴zookeeper,需要先啟動每一臺zookeeper伺服器。

zookeeper管理配置檔案
由於zookeeper統一管理solr的配置檔案(主要是schema.xml、solrconfig.xml), solrCloud各各節點使用zookeeper管理的配置檔案。

將上邊部署的solr單機的conf拷貝到/home/solr下。
執行下邊的命令將/home/solr/conf下的配置檔案上傳到zookeeper:
sh /usr/local/solr-4.10.3/example/scripts/cloud-scripts/zkcli.sh -zkhost 192.168.0.5:2181,192.168.0.6:2181,192.168.0.7:2181 -cmd upconfig -confdir /usr/local/solr-4.10.3/example/solr/collection1/conf -confname myconf 

登陸zookeeper伺服器查詢配置檔案:
cd /usr/local/zookeeper/bin/
./zkCli.sh

 修改SolrCloud監控埠為8080:

修改每個solr的/home/solr/solrhome/solrconfig.xml檔案。

每一臺solr和zookeeper關聯

修改每一臺solr的tomcat 的 bin目錄下catalina.sh檔案中加入DzkHost指定zookeeper伺服器地址:

JAVA_OPTS="-DzkHost=192.168.0.5:2181,192.168.0.6:2181,192.168.0.7:2181"

 

啟動所有的solr服務

啟動每一臺solr的tomcat服務。

 

訪問solrcloud

訪問任意一臺solr,左側選單出現Cloud:

SolrCloud叢集配置

上圖中的collection1叢集只有一片,可以通過下邊的方法配置新的叢集。

建立新叢集collection2,將叢集分為兩片,每片兩個副本。

http://192.168.0.1:8080/solr/admin/collections?action=CREATE&name=collection2&numShards=2&replicationFactor=2

刪除叢集命令;

http://192.168.0.1:8080/solr/admin/collections?action=DELETE&name=collection1

執行後原來的collection1刪除,如下:

更多的命令請引數官方文件:apache-solr-ref-guide-4.10.pdf

 

啟動solrCloud注意

啟動solrCloud需要先啟動solrCloud依賴的所有zookeeper伺服器,再啟動每臺solr伺服器。

 

SolrCloud測試

建立索引:

測試1:在一臺solr上建立索引,從其它solr服務上可以查詢到。

測試2:一次建立100個文件甚至更多,通過觀察每個solr的core下邊都有索引文件,說明索引文件是分片儲存。

 

查詢索引:

從任意一臺Solr上查詢索引,返回一個完整的結果,說明查詢請求從不同的分片上獲取資料,最終返回叢集上所有匹配的結果。

solrJ訪問solrCloud

public class SolrCloudTest {
// zookeeper地址
private static String zkHostString = "192.168.101.7:2181,192.168.101.8:2181,192.168.101.9:2181";
// collection預設名稱,比如我的solr伺服器上的collection是collection2_shard1_replica1,就是去掉“_shard1_replica1”的名稱
private static String defaultCollection = "collection2";
// 客戶端連線超時時間	
private static int zkClientTimeout = 3000;
// zookeeper連線超時時間
private static int zkConnectTimeout = 3000;

// cloudSolrServer實際
private CloudSolrServer cloudSolrServer;

// 測試方法之前構造 CloudSolrServer
@Before
public void init() {
cloudSolrServer = new CloudSolrServer(zkHostString);
cloudSolrServer.setDefaultCollection(defaultCollection);
cloudSolrServer.setZkClientTimeout(zkClientTimeout);
cloudSolrServer.setZkConnectTimeout(zkConnectTimeout);
cloudSolrServer.connect();
}

// 向solrCloud上建立索引
@Test
public void testCreateIndexToSolrCloud() throws SolrServerException,
IOException {

SolrInputDocument document = new SolrInputDocument();
document.addField("id", "100001");
document.addField("title", "李四");
cloudSolrServer.add(document);
cloudSolrServer.commit();

}

// 搜尋索引
@Test
public void testSearchIndexFromSolrCloud() throws Exception {

SolrQuery query = new SolrQuery();
query.setQuery("*:*");
try {
QueryResponse response = cloudSolrServer.query(query);
SolrDocumentList docs = response.getResults();

System.out.println("文件個數:" + docs.getNumFound());
System.out.println("查詢時間:" + response.getQTime());

for (SolrDocument doc : docs) {
ArrayList title = (ArrayList) doc.getFieldValue("title");
String id = (String) doc.getFieldValue("id");
System.out.println("id: " + id);
System.out.println("title: " + title);
System.out.println();
}
} catch (SolrServerException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("Unknowned Exception!!!!");
e.printStackTrace();
}
}

// 刪除索引
@Test
public void testDeleteIndexFromSolrCloud() throws SolrServerException, IOException {

// 根據id刪除
UpdateResponse response = cloudSolrServer.deleteById("zhangsan");
// 根據多個id刪除
// cloudSolrServer.deleteById(ids);
// 自動查詢條件刪除
// cloudSolrServer.deleteByQuery("product_keywords:教程");
// 提交
cloudSolrServer.commit();
}
}