solrcloud分布式集群部署及索引操做实例

1、前期准备工做

相关工具:
1.虚拟机(VMware)
2.tomcat7 64位  下载地址: http://tomcat.apache.org/download-70.cgi
3.centos6.4  64位
4.linux下的64位jdk安装包,版本为6或以上
5. solr-4.3.1.tgz包  下载: http://archive.apache.org/dist/lucene/solr/
6. zookeeper-3.4.5.tar.gz包  下载: http://hadoop.apache.org/zookeeper/releases.html

环境:
虚拟机环境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代码   收藏代码
  1. <properties>     
  2.     <comment>IK Analyzer 扩展配置</comment>   
  3.     <!--用户能够在这里配置本身的扩展字典 -->   
  4.     <entry key="ext_dict">ext.dic;</entry>    
  5.     <!--用户能够在这里配置本身的扩展中止词字典-->   
  6.     <entry key="ext_stopwords">stopword.dic;stopword_chinese.dic;</entry>    
  7. </properties>   

  

 Ik分词器配置见http://lucien-zzy.iteye.com/blog/2002087

 

9.建立solr的数据目录/soft/solr-cores并在该目录下生成solr.xml 这是solr的核配置文件

 

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <solr persistent="true">  
  3. <logging enabled="true">  
  4. <watcher size="100" threshold="INFO" />  
  5. </logging>  
  6. <cores defaultCoreName="collection1" adminPath="/admin/cores" host="${host:}" hostPort="8080" hostContext="${hostContext:solr}" zkClientTimeout="${zkClientTimeout:15000}">  
  7. </cores>  
  8. </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代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <Context docBase="/soft/apache-tomcat-7.0.37/webapps/solr" debug="0" crossContext="true">  
  3. <Environment name="solr/home" type="java.lang.String" value="/soft/solr-cores" override="true"/>  
  4. </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代码   收藏代码
  1. 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代码   收藏代码
  1. 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代码   收藏代码
  1. [root@master  ~]# cd /soft/zookeeper-3.4.5/bin  
  2. [root@master  bin]# ./zkCli.sh -server 192.168.91.128:2181  
  3. ...  
  4. [zk: 192.168.91.128:2181(CONNECTED) 0] ls /  
  5. [configs, collections, zookeeper]  
  6. [zk: 192.168.91.128:2181(CONNECTED) 1] ls /configs  
  7. [myconf]  
  8. [zk: 192.168.91.128:2181(CONNECTED) 2] ls /configs/myconf  
  9. [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]  
  10. [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代码   收藏代码
  1. 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代码   收藏代码
  1. curl 'http://192.168.91.128:8080/solr/admin/cores?action=CREATE&collection=mycollection&name=mycollection_shard1_replica1&shard=shard1'  

 

Java代码   收藏代码
  1. 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代码   收藏代码
  1. import java.io.IOException;  
  2. import java.net.MalformedURLException;  
  3. import java.util.ArrayList;  
  4. import java.util.Collection;  
  5. import org.apache.solr.client.solrj.SolrQuery;  
  6. import org.apache.solr.client.solrj.SolrServer;  
  7. import org.apache.solr.client.solrj.SolrServerException;  
  8. import org.apache.solr.client.solrj.impl.CloudSolrServer;  
  9. import org.apache.solr.client.solrj.response.QueryResponse;  
  10. import org.apache.solr.common.SolrDocument;  
  11. import org.apache.solr.common.SolrDocumentList;  
  12. import org.apache.solr.common.SolrInputDocument;  
  13.   
  14. /** 
  15.  * SolrCloud 索引增删查测试 
  16.  * @author ziyuzhang 
  17.  * 
  18.  */  
  19. public class SolrCloud {        
  20.     private static CloudSolrServer cloudSolrServer;    
  21.         
  22.     private  static synchronized CloudSolrServer getCloudSolrServer(final String zkHost) {    
  23.         if(cloudSolrServer == null) {    
  24.             try {    
  25.                 cloudSolrServer = new CloudSolrServer(zkHost);    
  26.             }catch(MalformedURLException e) {    
  27.                 System.out.println("The URL of zkHost is not correct!! Its form must as below:\n zkHost:port");    
  28.                 e.printStackTrace();    
  29.             }catch(Exception e) {    
  30.                 e.printStackTrace();                    
  31.             }    
  32.         }    
  33.             
  34.         return cloudSolrServer;    
  35.     }    
  36.         
  37.     private void addIndex(SolrServer solrServer) {          
  38.         try {    
  39.             SolrInputDocument doc1 = new SolrInputDocument();    
  40.             doc1.addField("id""421245251215121452521251");    
  41.             doc1.addField("area""北京");    
  42.             SolrInputDocument doc2 = new SolrInputDocument();    
  43.             doc2.addField("id""4224558524254245848524243");    
  44.             doc2.addField("area""上海");    
  45.                 
  46.             SolrInputDocument doc3 = new SolrInputDocument();    
  47.             doc3.addField("id""4543543458643541324153453");    
  48.             doc3.addField("area""重庆");    
  49.                 
  50.             Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();    
  51.             docs.add(doc1);    
  52.             docs.add(doc2);    
  53.             docs.add(doc3);    
  54.       
  55.             solrServer.add(docs);               
  56.             solrServer.commit();    
  57.                 
  58.         }catch(SolrServerException e) {    
  59.             System.out.println("Add docs Exception !!!");    
  60.             e.printStackTrace();            
  61.         }catch(IOException e){    
  62.             e.printStackTrace();    
  63.         }catch (Exception e) {    
  64.             System.out.println("Unknowned Exception!!!!!");    
  65.             e.printStackTrace();    
  66.         }           
  67.             
  68.     }    
  69.         
  70.         
  71.     public void search(SolrServer solrServer, String String) {          
  72.         SolrQuery query = new SolrQuery();    
  73.         query.setQuery(String);    
  74.         try {    
  75.             QueryResponse response = solrServer.query(query);    
  76.             SolrDocumentList docs = response.getResults();    
  77.     
  78.             System.out.println("文档个数:" + docs.getNumFound());    
  79.             System.out.println("查询时间:" + response.getQTime());    
  80.     
  81.             for (SolrDocument doc : docs) {    
  82.                 String area = (String) doc.getFieldValue("area");    
  83.                 Long id = (Long) doc.getFieldValue("id");    
  84.                 System.out.println("id: " + id);    
  85.                 System.out.println("area: " + area);    
  86.                 System.out.println();    
  87.             }    
  88.         } catch (SolrServerException e) {    
  89.             e.printStackTrace();    
  90.         } catch(Exception e) {    
  91.             System.out.println("Unknowned Exception!!!!");    
  92.             e.printStackTrace();    
  93.         }    
  94.     }    
  95.         
  96.     public void deleteAllIndex(SolrServer solrServer) {    
  97.         try {    
  98.             solrServer.deleteByQuery("*:*");// delete everything!    
  99.             solrServer.commit();    
  100.         }catch(SolrServerException e){    
  101.             e.printStackTrace();    
  102.         }catch(IOException e) {    
  103.             e.printStackTrace();    
  104.         }catch(Exception e) {    
  105.             System.out.println("Unknowned Exception !!!!");    
  106.             e.printStackTrace();    
  107.         }    
  108.     }    
  109.         
  110.     /**  
  111.      * @param args  
  112.      */    
  113.     public static void main(String[] args) {      
  114.             final String zkHost = "192.168.91.128:2181,192.168.91.129:2181,192.168.91.130:2181";         
  115.             final String  defaultCollection = "mycollection";    
  116.             final int  zkClientTimeout = 20000;    
  117.             final int zkConnectTimeout = 1000;    
  118.                 
  119.             CloudSolrServer cloudSolrServer = getCloudSolrServer(zkHost);           
  120.             System.out.println("The Cloud SolrServer Instance has benn created!");              
  121.             cloudSolrServer.setDefaultCollection(defaultCollection);    
  122.             cloudSolrServer.setZkClientTimeout(zkClientTimeout);    
  123.             cloudSolrServer.setZkConnectTimeout(zkConnectTimeout);                     
  124.             cloudSolrServer.connect();    
  125.             System.out.println("The cloud Server has been connected !!!!");              
  126.             //测试实例!    
  127.             SolrCloud test = new SolrCloud();           
  128.     //        System.out.println("测试添加index!!!");         
  129.             //添加index    
  130.     //        test.addIndex(cloudSolrServer);    
  131.                 
  132.     //        System.out.println("测试查询query!!!!");    
  133.     //        test.search(cloudSolrServer, "id:*");    
  134.     //            
  135.     //        System.out.println("测试删除!!!!");    
  136.     //        test.deleteAllIndex(cloudSolrServer);    
  137.     //        System.out.println("删除全部文档后的查询结果:");    
  138.             test.search(cloudSolrServer, "zhan");        
  139.     //        System.out.println("hashCode"+test.hashCode());  
  140.                         
  141.              // release the resource     
  142.             cloudSolrServer.shutdown();    
  143.      
  144.     }    
  145.     
  146. }  

 

 

注:别忘了修改核心配置文件schema.xml,要有id 和 area,注意类型的匹配。

 

 

  转载请注明出处http://lucien-zzy.iteye.com/admin/blogs/2002463

相关文章
相关标签/搜索