jetty启动: wiki有教程;
实验遇到的问题:1. 在windows上不同jetty带起的solr实例注册不到zk上。
2. 在虚拟机启动了2个shard,windows上的实例无法同步到已经启动的shard上,曾以为是solr目录文件不一样的问题,替换虚拟机中的目录到windows 下依然不行。
tomcat+独立zookeeper:
1. 复制多份solr,和多份tomcat;配置单个solr运行在tomcat的实例(conf/Catalina/localhost/solr.xml); 注意如果在一台机器上tomcat服务器各种端口要避免重合!红字solr表示url的path。
2. 将collection的配置上传到zk上: 利用 cloud-scripts目录下的zkcli.sh脚本
cloud-scripts/zkcli.sh -cmd upconfig -confdir ~/apache-solr-4.0.0/example/solr/collection1/conf/ -confname coll1 -z vm:2181
其中 -confdir 是上传集合的配置, -z 配置ZK的服务地址,coll1会保存在/configs下
3. 在catalina.sh中加入JAVA_OPTS参数,JAVA_OPTS="-DzkHost=vm:2181" , 这是配置zk路径的。 如果第一台solr服务开始指定shard数量,还可以加入"-DnumShards=2",后续加入的机器可以不加这句
4. 启动tomcat 和solr项目,在http://url/solr/#/~cloud中可以看到集群情况
5. 经验总结:
5.1 如果不走第二步,那么需要把配置上传的语句(wiki中jetty启动有),写到tomcat的JAVA_OPTS里
5.2 solr目录下的solr.xml中几个参数含义(只是注册到ZK上的属性,不影响使用,但点击cloud上的机器你就转不到那了):
host:是注册到zookeeper集群的机器名.默认是机器名,可以改成机器的IP,那样就免去了更改系统hosts文件了.
hostPort:注册到zookeeper集群的访问该服务的端口号.(最好改成所在tomcat服务端口)
hostContext:注册到zookeeper集群的访问该服务器的web实例名.默认是solr
5.3 如果首台solr实例启动不注明shard数量,那么集群中就1个shard后续所有实例都会注册到这个上,形成replica。即,numShards:默认为1,(shard才是真正分布式搜索的服务)
5.4 zk会保留集群注册信息,如果zk数据不删除,solr再次启动,还会处在相同配置上。
5.5 如果开始只有一个shard,想热部署一个新的shard, 可以再solr.xml的 core上配置一个shard="shard2" 属性,启动之后自动加入集群之中。(这一步可以由5.6代替)
5.6 复制一份collection1 到collection2, 在一台solr实例中启动,之后集群可见,其他节点可以再管理后台add core,(云端的add core 比单点的要多两个参数:collection和shard, 并且collection的schema和config都是zk上的路径,因此第二步上传配置是必须的。体现了集群管理配置的特点,对应solr中ZkResourceLoader干的事)形成新的分布式搜索库。可以为同一个collection增加不同shard
5.7 solrcloud 4.0 master slave转换并没有想象中可靠,一般刚上线的master/slave都是正常状态,master挂机或者unload,slave多半变成等待恢复的状态而不是转为新master(master不在将不能进行写操作); 再恢复原master,slave多半出现恢复失败,但是当了新master。此时系统可用,任意一台机器down都不会影响读写(就算刚才新的master也挂了,原master也能顶上当master),务必进行重建等必要措施。
5.8 5.7的问题在solrcloud4.1得到了解决,随时停掉master 都能自动改变leader,
之前的还是不要了,新探索出4.3的部署,之前的路线更简单一点:
1. 解压solr-4.3.0, 把example拷贝出到新目录solrbase, 运行java -jar start.jar 把jetty自带的solr.war解压出来(不运行这一步解压不出solr所需要的所有lib,你以后要直接用cloud-script就不行)
2. 解压tomcat, 放到solrbase下,在tomcat/conf添加Catalina/localhost/solr.xml ,xml里添加如下内容:
<Context docBase="/xxx/tomcat/webapps/solr.war" debug="0" crossContext="true" >
<Environment name="solr/home" type="java.lang.String" value="/xxx/solrbase/solr" override="true" />
</Context>
3.将solrbase/webapps/solr.war拷贝到tomcat/webapps 下,tomcat的server.xml配置可以根据需要修改,尤其注意URIEncoding
4. 拷贝solrbase/lib/* solrbase/resources/* 到tomcat/lib下(4.3才新增的要求)
5. 修改tomcat/bin/catalina.sh 添加类似JAVA_OPTS="-Dhost=vm -Dport=8080 -Dbootstrap_confdir=/data/solrbase/solr/collection1/conf -Dcollection.configName=collection1 -DzkHost=vm:2181/solr"
!注意几个地方-Dhost 表示传入JVM的系统参数host, 这个就是填充solrbase/solr/solr.xml中的几个参数, 你可以先看看solrbase/solr/solr.xml <cores上面的几个参数,然后通过JAVA_OPTS的-D来传进来;指定zookeeper地址之后的/solr表示 solrcloud所需要的zk配置会放在/solr下,如果不指定,ZK根下会有一堆SOLR的各种配置;-Dbootstrap_confdir和 -Dcollection.configName=collection1 表示启动会把前者的配置上传到.../configs下,并且改名collection1,这是默认collection1例子所需要的配置,如果你不配置在这里,手动传上去也可以。
6. 打包solrbase 分发到其他机器上,启动tomcat/bin/startup.sh
7. 建议在solrcloud上的建立索引操作用collection API而不是每个solr实例慢慢add core
如果在schema.xml 定义中不存在text field ,在启动solr 时会出现下面的异常:org.apache.solr.common.SolrException: undefined field text。解决办法:只要在schema.xml 文件中增加一个text field ,这样在启动时就没有异常了。
如下:
<field name="text" type="text" stored="false" indexed="false"/>
2. <分词插件>
analyzer是tokenizer和filter的组合: 覆盖public TokenStreamComponents createComponents(String fieldName, Reader reader) 方法,首先通过各种Tokenizer从reader中获取tokenizer,给TokenFilter产生各种TokenStream result,再进行过滤.. 最后返回new TokenStreamComponents(tokenizer, result)
TokenizerFactory 需要重写Tokenizer create(Reader input)方法,smartcn直接返回了SentenceTokenizer
TokenFilterFactory 需要重写 TokenFilter create(TokenStream input) smartcn直接返回了WordTokenFilter(input)
上述两个方法可以给solr在schema.xml上配置分词的组合细节的,如果直接用analyzer,那就不用再xml中配置其他过滤器之类的。
可能一般需要自己的TokenFilter(smartcn的WordTokenFilter比较好理解); 4.0和3.0比在接口上有些许不同 需要特别留意。
IK分词器中并没有TokenFilter 概念,而是在Tokenizer 中直接完成分词过程(注意Tokenizer 和TokenFilter 都需要覆盖的是boolean incrementToken()方法,并在类里面保留当前token信息)
solr的分词基本与lucene的分词结构一致,多了直接暴露分词器内核的Factory
分词组建实现了ResourceLoaderAware的XXXFactory的路径由SolrResourceLoader控制,如果想动态加载词典,就在inform(ResourceLoader loader)中启动监控线程即可。
3. solrj开发
String url = "http://localhost:8080/solr/collection1"; //需要指定collection, 不指定就会使用solr.xml中的默认collection
HttpSolrServer server = new HttpSolrServer(url);
可以Pojo形式建文档
HttpSolrServer 核心包装了一个httpClient,会对请求结果根据responseWriter进行再次解析.