一、相关工具
1.虚拟机(VMware)
2.tomcat8 64位 下载地址: 3.centos7.0 64位 4.linux下的64位jdk安装包,版本为6或以上 本人 1.8 5. solr-4.3.1.tgz包 下载: 6. zookeeper-3.4.6 .tar.gz包 下载:二、部署环境
虚拟机环境centos7.0 64位系统 搭建三台虚拟机 网卡模式是NAT(测试环境推荐使用NAT,实际生产时可使用桥接以便外网访问)三、安装zookeeper集群
现有三台机器 192.168.10.137 192.168.10.138 192.168.10.145
在所有机器上进行
1、下载安装包解压 tar zxvf zookeeper-3.4.6 .tar.gz -C /export/ cd /export/ ln -s zookeeper-3.4.6 zookeeper 2、设置环境变量 vim /etc/profile export ZOOKEEPER_HOME=/export/zookeeper export PATH=$PATH:$ZOOKEEPER_HOME/bin 3、加载环境变量 source /etc/profile 4、配置zookeeper cd /export/zookeeper/conf cp zoo_sample.cfg zoo.cfg vim zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/export/zookeeper/data dataLogDir=/export/zookeeper/log clientPort=2181 server.1=192.168.10.137:2888:3888 server.2=192.168.10.138:2888:3888 server.3=192.168.10.145:2888:3888 5、dataDir和日志目录dataLogDir mkdir -p /export/zookeeper/data mkdir -p /export/zookeeper/log 6、在192.168.10.137上 在dataDir目录下创建myid文件 echo 1 > /export/zookeeper/data/myid myid中的数字与zoo.cfg中的"server.数字=ip或者域名:port1:port2"相对应, 配置文件中192.168.10.137对应的server.数字是1 所以myid的数字应为1 7、在192.168.10.138上 在dataDir目录下创建myid文件 echo 2 > /export/zookeeper/data/myid 8、在192.168.10.145上 在dataDir目录下创建myid文件 echo 3 > /export/zookeeper/data/myid 在所用机器上执行 9、修改权限 chown root -R /export/zookeeper/ chown root -R /export/zookeeper 10、启动zookeeper /export/zookeeper/bin/zkServer.sh start zookeeper的目录下有一个bin目录。使用zkServer.sh启动zookeeper服务。 启动命令:./zkServer.sh start 另一种启动zookeeper的方式:./zkServer.sh start-foreground //这种启动方式,能够查看zookeeper的 日志 关闭命令:./zkServer.sh stop 查看服务状态:./zkServer.sh status 11、观察zookeeper状态 1> 192.168.10.137 # /export/zookeeper/bin/zkServer.sh status JMX enabled by default Using config: /export/zookeeper/bin/../conf/zoo.cfg Mode: follower 2> 192.168.10.138 # /export/zookeeper/bin/zkServer.sh status JMX enabled by default Using config: /export/zookeeper/bin/../conf/zoo.cfg Mode: follower 3> 192.168.10.145 # /export/zookeeper/bin/zkServer.sh status JMX enabled by default Using config: /export/zookeeper/bin/../conf/zoo.cfg Mode: leader 12、此时zookeeper已安装并启动完毕四、Solrcloud分布式集群搭建
1.将apache-tomcat-8.5.20.tar.gz包上传至/usr/local/apache下并解压
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上传至/usr/local/apache/apache-tomcat-8.5.20/webapps下。 8.添加停词,扩展词,ik分词器:下载IKAnalyzer包,将IKAnalyzer解压文件夹下的stopword.dic和IKAnalyzer.cfg.xml复制到/usr/local/apache/apache-tomcat-8.5.20/webapps/solr/WEB-INF/classes下,再新建一个ext.dic,里面的格式和stopword.dic一致。并修改IKAnalyzer.cfg.xml如下所示,可以配置多个停止词或者扩展词库文件(具体详细内容可见)。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分词器配置见
9.创建solr的数据目录/usr/local/apache/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.创建 /usr/local/apache/apache-tomcat-8.5.20/conf/Catalina/localhost
11.在/usr/local/apache/apache-tomcat-8.5.20/conf/Catalina/localhost 下创建solr.xmlXml代码
<?xml version="1.0" encoding="UTF-8"?> <Context docBase="/usr/local/apache/apache-tomcat-8.5.20/webapps/solr" debug="0" crossContext="true"> <Environment name="solr/home" type="java.lang.String" value="/usr/local/apache/solr-cores" override="true"/> </Context> |
此文件为Solr/home的配置文件
12.修改tomcat/bin/cataina.sh 文件,在最上方加入
JAVA_OPTS="-DzkHost=192.168.10.137:2181,192.168.10.138:2181,192.168.10.145: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.10.137:2181,192.168.10.138:2181,192.168.10.145: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.10.137:2181,192.168.10.138:2181,192.168.10.145:2181 |
操作如图:
15.上传完成以后,我们检查一下ZooKeeper上的存储情况:
Java代码
[root ~]# cd /soft/zookeeper-3.4.5/bin [root 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界面无法访问,看不到任何有关SolrCloud的信息,如图所示:17.启动其他两个结点上的tomcat
18.查看ZooKeeper集群中数据状态:
这时,已经存在3个活跃的节点了,但是SolrCloud集群并没有更多信息,
访问后,同上面的图是一样的,没有SolrCloud相关数据。19.创建Collection、Shard和Replication
创建Collection及初始Shard:
通过REST接口来创建CollectionJava代码
curl 'http://192.168.10.137:8080/solr/admin/collections?action=CREATE&name=mycollection&numShards=3&replicationFactor=1' |
上面链接中的几个参数的含义,说明如下:
name 待创建Collection的名称 numShards 分片的数量 replicationFactor 复制副本的数量操作如图:
执行上述操作如果没有异常,已经创建了一个Collection,名称为mycollection,而且每个节点上存在一个分片。这时,也可以查看ZooKeeper中状态:
可以通过Web管理页面,访问查看SolrCloud集群的分片信息,如图所示:
由上图可以看到,对应节点上SOLR分片的对应关系:
shard1 192.168.10.137 slave2 shard2 192.168.10.138 slave1 shard3 192.168.10.145 master 实际上,我们从master节点可以看到,SOLR的配置文件内容,已经发生了变化,如下所示:我们可以再通过REST接口分别在slave1、slave2结点上创建两个collection,分别命名为mycollection1、mycollection2
创建后的访问链接如图:创建Replication:
下面对已经创建的初始分片进行复制: master结点 上的分片shard1已经存在slave2,现在我们复制分片到master和slave1上 执行操作:Java代码
curl 'http://192.168.10.137:8080/solr/admin/cores?action=CREATE&collection=mycollection&name=mycollection_shard1_replica1&shard=shard1' |
Java代码
curl 'http://192.168.10.138: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的配置文件内容,又发生了变化,如下所示:三、索引操作实例
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 索引增删查测试 * 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(); } } /** * 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,注意类型的匹配。
四、配置文件的更新
1、upconfig 更新配置文件命令
更改了solrconfig.xml和schema.xml等 需要更新到zookeeper集群中
Java代码
java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -cmd upconfig -zkhost 192.168.10.137:2181,192.168.10.138:2181,192.168.10.145:2181 -confdir /usr/local/solrcloud/config-files/ -confname myconf |
执行以上代码将修改的配置文件上传到zookeeper集群中
2、putfile上传单个文件命令
Java代码
java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -cmd putfile -zkhost 192.168.10.137:2181,192.168.10.138:2181,192.168.10.145:2181 -confdir /usr/local/solrcloud/config-files/schema.xml -confname myconf ------------------------------------------------------------------------------ java -classpath .:/usr/local/solrcloud/solr-lib/* org.apache.solr.cloud.ZkCLI -cmd linkconfig -collection collection1 -confname myconf -zkhost 192.168.10.137:2181,192.168.10.138:2181,192.168.10.145:2181 |
3、更新zookeeper集群的配置文件后,需要用命令reload,否则solr服务器实例还是用的原来那一套配置文件。
其中,前者参数是zk集群上的存储路径,后者参数是要上传文件的本地路径;如果zk集群中该文件存在则会报错,不能覆盖。改了配置一定重新加载,不然索引操作时会报异常。
action:执行的请求。
name:是collection名称。
五、
1、下载最新的mmseg4j包(mmseg4j-1.9.1.zip)
2、解压得到 三个包
3、将解压获得的三个包加入到/usr/local/apache/apache-tomcat-8.5.20/webapps/solr/WEB-INF/lib下
4、修改/usr/local/solrcloud/config-files 下的schema.xml文件 加入下面这段代码
<fieldType name="text_mmseg4j_complex" class="solr.TextField" positionIncrementGap="100" > <analyzer type="index"> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic"/> <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> </analyzer> <analyzer type="query"> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic"/> <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> </analyzer> </fieldType> <fieldType name="text_mmseg4j_maxword" class="solr.TextField" positionIncrementGap="100" > <analyzer> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" dicPath="dic"/> </analyzer> </fieldType> <fieldType name="text_mmseg4j_simple" class="solr.TextField" positionIncrementGap="100" > <analyzer> <!-- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="n:/OpenSource/apache-solr-1.3.0/example/solr/my_dic"/> --> <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="dic"/> </analyzer> </fieldType> <!-- mmseg4j--> |
5、在/usr/local/apache/solr-cores目录下新建 dic 文件夹 加入下面的文件
此目录对应的是 solr/home目录
6、执行 第四步 配置文件的更新