linux solrcloud zookeeper分佈式集羣部署

        

SolrCloud 經過 ZooKeeper 集羣來進行協調,使一個索引進行分片,各個分片能夠分佈在不一樣的物理節點上,多個物理分片組成一個完成的索引 Collection。SolrCloud 自動支持 Solr Replication,能夠同時對分片進行復制,冗餘存儲。下面,咱們基於 Solr 最新的 4.4.0 版本進行安裝配置 SolrCloud 集羣。html

1. 安裝環境

我使用的安裝程序各版本以下:java

各個目錄說明:json

  • 全部的程序安裝在 /opt 目錄下,你能夠依照你的實際狀況下修改安裝目錄。bootstrap

  • ZooKeeper的數據目錄在: /data/zookeeper/dataapi

  • solrhome設置在: /usr/local/solrhome瀏覽器

2. 規劃SolrCloud

  • 單一SolrCloud數據集合: primarytomcat

  • ZooKeeper集羣: 3臺

  • SolrCloud實例: 3節點

  • 索引分片: 3

  • 複製因子: 2

手動將3個索引分片(Shard)的複本(Replica)分佈在3個 SolrCloud 節點上

三個節點:

  • 192.168.56.121

  • 192.168.56.122

  • 192.168.56.123

3. 安裝ZooKeeper集羣

因爲須要用到 ZooKeeper,故咱們先安裝好 ZooKeeper 集羣。

安裝 ZooKeeper 集羣以前,請確保每臺機器上配置 /etc/hosts文件,使每一個節點都能經過機器名訪問。

首先,在第一個節點上將 zookeeper-3.4.5.tar.gz 解壓到 /opt 目錄:

$ tar zxvf zookeeper-3.4.5.tar.gz -C /opt/

建立 ZooKeeper 配置文件 zookeeper-3.4.5/conf/zoo.cfg,內容以下:

tickTime=2000initLimit=10syncLimit=5dataDir=/data/zookeeper/dataclientPort=2181server.1=192.168.56.121:2888:3888server.2=192.168.56.122:2888:3888server.3=192.168.56.123:2888:3888

ZooKeeper 的數據目錄指定在 /data/zookeeper/data ,你也可使用其餘目錄,經過下面命令進行建立該目錄:

$ mkdir /data/zookeeper/data -p

而後,初始化 myid ,三個節點編號依次爲 1,2,3 ,在其他節點上分別執行命令(注意修改編號)。

$ echo "1" >/data/zookeeper/data/myid

而後,在第二個和第三個節點上依次重複上面的操做。這樣第一個節點中 myid 內容爲1,第二個節點爲2,第三個節點爲3。

最後,啓動 ZooKeeper 集羣,在每一個節點上分別啓動 ZooKeeper 服務:

$ cd /opt$ sh zookeeper-3.4.5/bin/zkServer.sh start

能夠查看 ZooKeeper 集羣的狀態,保證集羣啓動沒有問題:

[root@192.168.56.121 opt]# sh zookeeper-3.4.5/bin/zkServer.sh status
JMX enabled by default
Using config: /opt/zookeeper-3.4.5/bin/../conf/zoo.cfg
Mode: follower

4. 安裝Solr

你能夠參考《Apache Solr介紹及安裝》

簡單來講,執行如下命令:

$ unzip apache-tomcat-6.0.36.zip  -d /opt$ unzip solr-4.4.0.zip  -d /opt$ cd /opt$ chmod +x apache-tomcat-6.0.36/bin/*.sh$ cp solr-4.4.0/example/webapps/solr.war apache-tomcat-6.0.36/webapps/$ cp solr-4.4.0/example/lib/ext/* apache-tomcat-6.0.36/webapps/solr/WEB-INF/lib/$ cp solr-4.4.0/example/resources/log4j.properties apache-tomcat-6.0.36/lib/

在其餘節點上重複以上操做完成全部節點的 solr 的安裝。

5. 設置 SolrCloud 配置文件

一、 建立一個 SolrCloud 目錄,並將 solr 的 lib 文件拷貝到這個目錄:

$ mkdir -p /usr/local/solrcloud/solr-lib/$ cp apache-tomcat-6.0.36/webapps/solr/WEB-INF/lib/* /usr/local/solrcloud/solr-lib/

二、 經過 bootstrap 設置 solrhome :

這裏設置 solrhome 爲 /usr/local/solrhome,建立該目錄:

mkdir -p /usr/local/solrhome

而後,運行下面命令將 solrhome 下面的配置上傳到 zookeeper:

$ java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -zkhost 192.168.56.121:2181,192.168.56.122:2181,192.168.56.123:2181 -cmd bootstrap -solrhome

SolrCloud 集羣的全部的配置存儲在 ZooKeeper。 一旦 SolrCloud 節點啓動時配置了 -Dbootstrap_confdir 參數, 該節點的配置信息將發送到 ZooKeeper 上存儲。基它節點啓動時會應用 ZooKeeper 上的配置信息,這樣當咱們改動配置時就不用一個個機子去更改了。

三、SolrCloud 是經過 ZooKeeper 集羣來保證配置文件的變動及時同步到各個節點上,因此,須要將咱們本身的配置文件(在 /usr/local/solrcloud/conf/primary/conf 目錄下)上傳到 ZooKeeper 集羣中,配置名稱設爲 primaryconf:

$ java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -zkhost 192.168.56.121:2181,192.168.56.122:2181,192.168.56.123:2181 -cmd upconfig -confdir /usr/local/solrcloud/conf/primary/conf -confname primaryconf

說明:

  • zkhost 指定 ZooKeeper 地址,逗號分割

  • /usr/local/solrcloud/conf/ 目錄下存在名稱爲 primary 的目錄,該目錄下的配置是後面須要用到的。

  • primaryconf 爲在 ZooKeeper 上的配置文件名稱。

/usr/local/solrcloud/conf 結構以下:

$ tree /usr/local/solrcloud/conf
/usr/local/solrcloud/conf
├── primary
│   └── conf
│       ├── schema.xml
│       └── solrconfig.xml
└── solr.xml

2 directories, 3 files

schema.xml 內容以下:

<?xml version="1.0" encoding="UTF-8" ?><schema name="example" version="1.5">
    <fields>
        <field name="namespace" type="string" indexed="true" stored="true" />
        <field name="id" type="string" indexed="true" stored="true" />
        <field name="productId" type="long" indexed="true" stored="true" />
        <field name="category" type="long" indexed="true" stored="true" multiValued="true" />
        <field name="explicitCategory" type="long" indexed="true" stored="true" multiValued="true" />
        <field name="searchable" type="text_general" indexed="true" stored="false" />
        <field name="_version_" type="long" indexed="true" stored="true" multiValued="false"/>
        <dynamicField name="*_searchable" type="text_general" indexed="true" stored="true" />

        <dynamicField name="*_i" type="int" indexed="true" stored="true" />
        <dynamicField name="*_is" type="int" indexed="true" stored="true" multiValued="true" />
        <dynamicField name="*_s" type="string" indexed="true" stored="true" />
        <dynamicField name="*_ss" type="string" indexed="true" stored="true" multiValued="true" />
        <dynamicField name="*_l" type="long" indexed="true" stored="true" />
        <dynamicField name="*_ls" type="long" indexed="true" stored="true" multiValued="true" />
        <dynamicField name="*_t" type="text_general" indexed="true" stored="true" />
        <dynamicField name="*_txt" type="text_general" indexed="true" stored="true" multiValued="true" />
        <dynamicField name="*_b" type="boolean" indexed="true" stored="true" />
        <dynamicField name="*_bs" type="boolean" indexed="true" stored="true" multiValued="true" />
        <dynamicField name="*_d" type="double" indexed="true" stored="true" />
        <dynamicField name="*_ds" type="double" indexed="true" stored="true" multiValued="true" />
        <dynamicField name="*_p" type="double" indexed="true" stored="true" />

        <dynamicField name="*_dt" type="date" indexed="true" stored="true" />
        <dynamicField name="*_dts" type="date" indexed="true" stored="true" multiValued="true" />

        <!-- some trie-coded dynamic fields for faster range queries -->
        <dynamicField name="*_ti" type="tint" indexed="true" stored="true" />
        <dynamicField name="*_tl" type="tlong" indexed="true" stored="true" />
        <dynamicField name="*_td" type="tdouble" indexed="true" stored="true" />
        <dynamicField name="*_tdt" type="tdate" indexed="true" stored="true" />
    </fields>

    <uniqueKey>id</uniqueKey>

    <types>
        <fieldType name="string" class="solr.StrField" sortMissingLast="true" />
        <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" />

        <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0" />
        <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0" />
        <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0" />
        <fieldType name="tint" class="solr.TrieIntField" precisionStep="8" positionIncrementGap="0" />
        <fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" positionIncrementGap="0" />
        <fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" positionIncrementGap="0" />

        <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0" />
        <!-- A Trie based date field for faster date range queries and date faceting. -->
        <fieldType name="tdate" class="solr.TrieDateField" precisionStep="6" positionIncrementGap="0" />

        <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
            <analyzer type="index">
                <tokenizer class="solr.StandardTokenizerFactory" />
                <filter class="solr.LowerCaseFilterFactory" />
            </analyzer>
            <analyzer type="query">
                <tokenizer class="solr.StandardTokenizerFactory" />
                <filter class="solr.LowerCaseFilterFactory" />
            </analyzer>
        </fieldType>

    </types></schema>

solrconfig.xml 內容以下:

<?xml version="1.0" encoding="UTF-8" ?><config>
  <luceneMatchVersion>4.4</luceneMatchVersion>
  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>

  <schemaFactory class="ClassicIndexSchemaFactory"/>

  <updateHandler class="solr.DirectUpdateHandler2">
    <updateLog>
            <str name="dir">${solr.data.dir:}</str>
        </updateLog>
  </updateHandler>

  <requestHandler name="/get" class="solr.RealTimeGetHandler">
    <lst name="defaults">
      <str name="omitHeader">true</str>
    </lst>
  </requestHandler>

  <requestHandler name="/replication" class="solr.ReplicationHandler" startup="lazy" />

  <requestDispatcher handleSelect="true" >
    <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" formdataUploadLimitInKB="2048" />
    <httpCaching never304="true" />
  </requestDispatcher>

  <requestHandler name="standard" class="solr.StandardRequestHandler" default="true" />
  <requestHandler name="/analysis/field" startup="lazy" class="solr.FieldAnalysisRequestHandler" />
  <requestHandler name="/update" class="solr.UpdateRequestHandler"  />
  <requestHandler name="/update/json" class="solr.JsonUpdateRequestHandler" startup="lazy" />
  <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />

  <requestHandler name="/admin/ping" class="solr.PingRequestHandler">
    <lst name="invariants">
      <str name="q">solrpingquery</str>
    </lst>
    <lst name="defaults">
      <str name="echoParams">all</str>
      <str name="df">id</str>
    </lst>
  </requestHandler>

  <queryResponseWriter name="json" class="solr.JSONResponseWriter">
        <str name="content-type">text/plain; charset=UTF-8</str>
  </queryResponseWriter>

  <updateRequestProcessorChain name="sample">
     <processor class="solr.LogUpdateProcessorFactory" />
     <processor class="solr.DistributedUpdateProcessorFactory"/>
     <processor class="solr.RunUpdateProcessorFactory" />
  </updateRequestProcessorChain>

  <!-- config for the admin interface -->
  <admin>
    <defaultQuery>solr</defaultQuery>
    <pingQuery>q=solr&amp;version=2.0&amp;start=0&amp;rows=0</pingQuery>
    <healthcheck type="file">server-enabled</healthcheck>
  </admin></config>

四、建立 collection 並和配置文件關聯:

$ java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -zkhost 192.168.56.121:2181,192.168.56.122:2181,192.168.56.123:2181 -cmd linkconfig -collection primary -confname primaryconf

說明:

  • 建立的 collection 叫作 primary,並指定和 primaryconf 鏈接

五、查看 ZooKeeper 上狀態

在任意一個節點的 /opt 目錄下執行以下命令:

$  zookeeper-3.4.5/bin/zkCli.sh 

[zk: localhost:2181(CONNECTED) 0] ls /[configs,zookeeper,clusterstate.json,aliases.json,live_nodes,overseer,collections,overseer_elect][zk: localhost:2181(CONNECTED) 1] ls /configs[primaryconf,][zk: localhost:2181(CONNECTED) 1] ls /collections[primary]

查看 /configs/collections 目錄均有值,說明配置文件已經上傳到 ZooKeeper 上了,接下來啓動 solr。

6. Tomcat 配置與啓動

一、修改每一個節點上的 tomcat 配置文件,在環境變量中添加 zkHost 變量

編輯 apache-tomcat-6.0.36/bin/catalina.sh ,添加以下代碼:

JAVA_OPTS='-Djetty.port=8080 -Dsolr.solr.home=/usr/local/solrhome -DzkHost=192.168.56.122:2181,192.168.56.122:2181,192.168.56.123:2181'

/usr/local/solrhome/ 目錄建立 solr.xml :

<?xml version="1.0" encoding="UTF-8" ?><solr persistent="true" sharedLib="lib">
    <cores adminPath="/admin/cores" zkClientTimeout="${zkClientTimeout:15000}" hostPort="${jetty.port:8080}" hostContext="${hostContext:solr}"></cores></solr>

說明:

  • -Djetty.port:配置 solr 使用的端口,默認爲 8983,這裏咱們使用的是 tomcat,端口爲 8080

  • -Dsolr.solr.home:配置 solr/home

  • -zkHost: 配置 zookeeper 集羣地址,多個地址逗號分隔

最後,在 /opt 目錄下啓動 tomcat:

$ sh apache-tomcat-6.0.36/bin/startup.sh

經過 http://192.168.56.121:8080/solr/ 進行訪問,界面如圖提示 There are no SolrCores running. ,這是由於配置文件還沒有配置 solrcore。

There are no SolrCores running

7. 建立 Collection、Shard 和 Replication

手動建立 Collection 及初始 Shard

直接經過 REST 接口來建立 Collection,你也能夠經過瀏覽器訪問下面地址,以下所示:

$ curl 'http://192.168.56.121:8080/solr/admin/collections?action=CREATE&name=primary&numShards=3&replicationFactor=1'

若是成功,會輸出以下響應內容:

<response><lst name="responseHeader">
	<int name="status">0</int>
	<int name="QTime">2649</int></lst><lst name="success">
	<lst>
		<lst name="responseHeader">
			<int name="status">0</int>
			<int name="QTime">2521</int>
		</lst>
		<str name="core">primary_shard2_replica1</str>
		<str name="saved">/usr/local/solrhome/solr.xml</str>
	</lst>
	<lst>
		<lst name="responseHeader">
			<int name="status">0</int>
			<int name="QTime">2561</int>
		</lst>
		<str name="core">primary_shard3_replica1</str>
		<str name="saved">/usr/local/solrhome/solr.xml</str>
	</lst>
	<lst>
		<lst name="responseHeader">
		<int name="status">0</int>
		<int name="QTime">2607</int>
		</lst>
		<str name="core">primary_shard1_replica1</str>
		<str name="saved">/usr/local/solrhome/solr.xml</str>
	</lst></lst></response>

上面連接中的幾個參數的含義,說明以下:

  • name:               待建立Collection的名稱

  • numShards:          分片的數量

  • replicationFactor:   複製副本的數量

能夠經過 Web 管理頁面,訪問 http://192.168.56.121:8080/solr/#/~cloud,查看 SolrCloud 集羣的分片信息,如圖所示:

SolrCloud-collection-shard

實際上,咱們從192.168.56.121節點能夠看到,SOLR 的配置文件內容,已經發生了變化,以下所示:

<?xml version="1.0" encoding="UTF-8" ?><solr persistent="true" sharedLib="lib">
  <cores adminPath="/admin/cores" zkClientTimeout="20000" hostPort="${jetty.port:8080}" hostContext="${hostContext:solr}">
    <core shard="shard2" instanceDir="primary_shard2_replica1/" name="primary_shard2_replica1" collection="primary"/>
  </cores></solr>

同時,你還能夠看另外兩個節點上的 solr.xml 文件的變化。

手動建立 Replication

下面對已經建立的初始分片進行復制。 shard1 已經在 192.168.56.123 上,咱們複製分片到 192.168.56.121 和 192.168.56.122 上,執行以下命令:

$ curl 'http://192.168.56.121:8080/solr/admin/cores?action=CREATE&collection=primary&name=primary_shard1_replica_2&shard=shard1'$ curl 'http://192.168.56.122:8080/solr/admin/cores?action=CREATE&collection=primary&name=primary_shard1_replica_3&shard=shard1'

最後的結果是,192.168.56.123 上的 shard1,在 192.168.56.121 節點上有1個副本,名稱爲 primary_shard1_replica_2 ,在 192.168.56.122 節點上有一個副本,名稱爲 primary_shard1_replica_3 。也能夠經過查看 192.168.56.121 和 192.168.56.122 上的目錄變化,以下所示:

$  ll /usr/local/solrhome/
total 16
drwxr-xr-x 3 root root 4096 Mar 10 17:11 primary_shard1_replica2
drwxr-xr-x 3 root root 4096 Mar 10 17:02 primary_shard2_replica1
-rw-r--r-- 1 root root  444 Mar 10 17:16 solr.xml

你還能夠對 shard2 和 shard3 添加副本。shard2 已經在 192.168.56.121 上,咱們複製分片到 192.168.56.122 和 192.168.56.123 上,執行以下命令:

$ curl 'http://192.168.56.122:8080/solr/admin/cores?action=CREATE&collection=primary&name=primary_shard2_replica_2&shard=shard2'$ curl 'http://192.168.56.123:8080/solr/admin/cores?action=CREATE&collection=primary&name=primary_shard2_replica_3&shard=shard2'

shard3 已經在 192.168.56.122 上,咱們複製分片到 192.168.56.121 和 192.168.56.123 上,執行以下命令:

$ curl 'http://192.168.56.121:8080/solr/admin/cores?action=CREATE&collection=primary&name=primary_shard3_replica_2&shard=shard3'$ curl 'http://192.168.56.123:8080/solr/admin/cores?action=CREATE&collection=primary&name=primary_shard3_replica_3&shard=shard3'

咱們再次從 192.168.56.121 節點能夠看到,SOLR 的配置文件內容,又發生了變化,以下所示:

<?xml version="1.0" encoding="UTF-8" ?><solr persistent="true" sharedLib="lib">
  <cores adminPath="/admin/cores" zkClientTimeout="20000" hostPort="${jetty.port:8080}" hostContext="${hostContext:solr}">
    <core shard="shard1" instanceDir="primary_shard1_replica2/" name="primary_shard1_replica_2" collection="primary"/>
    <core shard="shard2" instanceDir="primary_shard2_replica1/" name="primary_shard2_replica_1" collection="primary"/>
    <core shard="shard3" instanceDir="primary_shard2_replica2/" name="primary_shard2_replica_2" collection="primary"/>
  </cores></solr>

到此爲止,咱們已經基於3個節點,配置完成了 SolrCloud 集羣。最後效果以下:

solrcloud-collection-shard-replica

8. 其餘說明

8.1 SolrCloud 的一些必要配置

schema.xml

必須定義 _version_ 字段:

<field name="_version_" type="long" indexed="true" stored="true" multiValued="false"/>

solrconfig.xml

updateHandler 節點下須要定義 updateLog:

    <!-- Enables a transaction log, currently used for real-time get.
         "dir" - the target directory for transaction logs, defaults to the
         solr data directory.  -->
    <updateLog>
      <str name="dir">${solr.data.dir:}</str>
      <!-- if you want to take control of the synchronization you may specify the syncLevel as one of the
           following where ''flush'' is the default. fsync will reduce throughput.
      <str name="syncLevel">flush|fsync|none</str>
      -->
    </updateLog>

須要定義一個 replication handler,名稱爲 /replication

<requestHandler name="/replication" class="solr.ReplicationHandler" startup="lazy" />

須要定義一個 realtime get handler,名稱爲/get:

	<requestHandler name="/get" class="solr.RealTimeGetHandler">
      <lst name="defaults">
        <str name="omitHeader">true</str>
     </lst>
    </requestHandler>

須要定義 admin handlers

<requestHandler name="/admin/" class="solr.admin.AdminHandlers" />

須要定義 updateRequestProcessorChain

 <updateRequestProcessorChain name="sample">
     <processor class="solr.LogUpdateProcessorFactory" />
     <processor class="solr.DistributedUpdateProcessorFactory"/>
     <processor class="solr.RunUpdateProcessorFactory" />
   </updateRequestProcessorChain>

solr.xml

cores 節點須要定義 adminPath 屬性:

<cores adminPath="/admin/cores" >

8.2 SolrCloud 分佈式檢索時忽略宕機的 Shard

<lst name=」error」>
	<str name=」msg」>no servers hosting shard:</str>
	<int name=」code」>503</int></lst>

加入下面參數,只從存活的 shards 獲取數據:

shards.tolerant=true

如:http://192.168.56.121:8080/solr/primary_shard2_replica1/select?q=*%3A*&wt=xml&indent=true&shards.tolerant=true

沒有打此參數,若是集羣內有掛掉的 shard,將顯示:

no servers hosting shard

8.3 自動建立 Collection 及初始 Shard

自動建立 Collection 及初始 Shard,不須要經過 zookeeper 手動上傳配置文件並關聯 collection。

一、在第一個節點修改 tomcat 啓動參數

JAVA_OPTS='-Djetty.port=8080 -Dsolr.solr.home=/usr/local/solrhome -DzkHost=192.168.56.122:2181,192.168.56.122:2181,192.168.56.123:2181 -DnumShards=3 -Dbootstrap_confdir=/usr/local/solrhome/primary/conf -Dcollection.configName=primaryconf '

而後啓動 tomcat。這個步驟上傳了集羣的相關配置信息(/usr/local/solrhome/primary/conf)到 ZooKeeper 中去,因此啓動下一個節點時不用再指定配置文件了。

二、在第二個和第三個節點修改 tomcat 啓動參數

JAVA_OPTS='-Djetty.port=8080 -Dsolr.solr.home=/usr/local/solrhome -DzkHost=192.168.56.122:2181,192.168.56.122:2181,192.168.56.123:2181 -DnumShards=3'

而後啓動 tomcat。

這樣就會建立3個 shard 分別分佈在三個節點上,若是你在增長一個節點,這節點會附加到一個 shard 上成爲一個 replica,而不會建立新的 shard。

9. 總結

本文記錄瞭如何 zookeeper、SolrCloud 的安裝和配置過程,solrcore 是經過 restapi 進行手動建立,而後又對自動建立 Collection 及初始 Shard 進行了說明。

10. 參考文章


原創文章,轉載請註明: 轉載自JavaChen Blog,做者:JavaChen
本文連接地址:http://blog.javachen.com/2014/03/10/how-to-install-solrcloud.html
本文基於署名2.5中國大陸許可協議發佈,歡迎轉載、演繹或用於商業目的,可是必須保留本文署名和文章連接。                        如您有任何疑問或者受權方面的協商,請郵件聯繫我。

Apache SolrCloud安裝

相關文章
相關標籤/搜索