SolrCloud使用教程、原理介绍 我心动了

合集下载

SolrCloud安装手册基于solr

SolrCloud安装手册基于solr

solrCloud集群安装手册—基于solrS. 2. 1、SolrCloud 集群架构概览1.1 SolrCloud 索引架构SolKloud 的索引存储中,三台服务器都要存索引。

1.2 ZooKeeper 架构ZooKeeper 集群,同时在三台服务器中配置ZooKeepero Shardl SolrCloudshardsShard2其中每一个分片有两份数据,一个是leader^ 同机器上,可以保证在某一台服务器down 掉后, 另一个是备份。

分别存储在不 仍可提供完整的数据服务。

c a har d25 hards —♦114.212-83.2430114.212.86.102O1I4.212.82.189 • 114,212.83.243 0114.212-82489—•114.212.86402/3.1JDK配置(1)解压JDK的压缩包至/usr/local/ U录下tar -zxvf JDK 压缩包位置-C /usr/local/(2)修改配置文件vi /etc/profile在下面添加如下内容export JAVA_HOME=/usr/local/jdkl.8.0_45exp ort CLASSPATH二•:${JAVA_HOME}/lib:${JAVA_HOME}/lib/tools・jarexport PATH=S{JAVA_HOME}/bin:$PATH然后在命令行中输入source /etc/profile输入命令java -version査看是否安装正确3.2Tomcat 配置(1)解压tomcat的压缩包至/home/dell/sofhvare tl录下tar -zx\・f ap aclie-tonicat-8.0.14.tar.gz(2)运行tomcat 中的staitiip.sh 运行tomcat(3)由于防火墙的原因无法访问8080端口,以下步骤为开放8080端口:/sbin/iptables -I INPUT -p tcp -dport 8080 寸ACCEPTservice iptables saveservice iptables restart或者直接禁用防火墙:停止/启动防火墙/sbin/service ip tables restart "重启/sbin/service ip tables stop —停止/sbi n/service ip tables start -启动1)重启后生效开启: chkconfig ip tables on 关闭:chkconfig iptables off2)即时生效,重启后失效开启:service ip tables start 关闭:service ip tablesstop然后访问服务器的8080端口査看tomcat是否安装正确。

Solr的原理及使用

Solr的原理及使用

Solr的原理及使⽤1.Solr的简介Solr是⼀个独⽴的企业级搜索应⽤服务器,它对外提供类似于Web-service的API接⼝。

⽤户可以通过http请求,向搜索引擎服务器提交⼀定格式的XML⽂件,⽣成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。

2.⼯作原理solr是基于Lucence开发的企业级搜索引擎技术,⽽lucence的原理是倒排索引。

那么什么是倒排索引呢?接下来我们就介绍⼀下lucence倒排索引原理。

假设有两篇⽂章1和2:⽂章1的内容为:⽼超在卡⼦门⼯作,我也是。

⽂章2的内容为:⼩超在⿎楼⼯作。

由于lucence是基于关键词索引查询的,那我们⾸先要取得这两篇⽂章的关键词。

如果我们把⽂章看成⼀个字符串,我们需要取得字符串中的所有单词,即分词。

分词时,忽略”在“、”的“之类的没有意义的介词,以及标点符号可以过滤。

我们使⽤Ik Analyzer实现中⽂分词,分词之后结果为:⽂章1:⽂章2:接下来,有了关键词后,我们就可以建⽴倒排索引了。

上⾯的对应关系是:“⽂章号”对“⽂章中所有关键词”。

倒排索引把这个关系倒过来,变成: “关键词”对“拥有该关键词的所有⽂章号”。

通常仅知道关键词在哪些⽂章中出现还不够,我们还需要知道关键词在⽂章中出现次数和出现的位置,通常有两种位置:a.字符位置,即记录该词是⽂章中第⼏个字符(优点是关键词亮显时定位快);b.关键词位置,即记录该词是⽂章中第⼏个关键词(优点是节约索引空间、词组(phase)查询快),lucene中记录的就是这种位置。

加上出现频率和出现位置信息后,我们的索引结构变为:实现时,lucene将上⾯三列分别作为词典⽂件(Term Dictionary)、频率⽂件(frequencies)、位置⽂件 (positions)保存。

其中词典⽂件不仅保存有每个关键词,还保留了指向频率⽂件和位置⽂件的指针,通过指针可以找到该关键字的频率信息和位置信息。

Solr搜索技术应用实战

Solr搜索技术应用实战

Solr搜索技术应用实战Solr是一个开源的搜索平台,它基于Apache Lucene构建,提供丰富的API和可扩展性,已经成为了许多开发者选择的搜索引擎。

随着数据量的增加和业务场景的多样化,Solr的应用越来越广泛。

本文将从Solr的实战应用入手,为开发者提供一些技巧和经验。

一、Solr集群搭建Solr的性能和可靠性与硬件配置和部署状态密切相关。

在生产环境中建议使用集群部署,可以分布式处理查询请求,增加搜索并发能力和容错性。

Solr集群中每个节点可以作为独立的搜索服务器,提供相同的搜索服务。

一个完整的Solr集群由多个节点组成,分为SolrCloud和非SolrCloud两种模式,SolrCloud是集群管理的一种模式,在SolrCloud模式下,Solr 集群可以更方便地进行扩容和管理。

以下是SolrCloud集群的简要步骤:1. 准备ZooKeeper,SolrCloud使用ZooKeeper进行集群管理。

2. 启动Solr节点,并与ZooKeeper进行连接。

3. 使用Solr控制台创建集合,集合分片在所有节点之间平均分配。

4. 访问SolrCloud集群的URL,进行搜索等操作。

二、Solr数据导入Solr并不能直接从数据库或文件中获取数据,需要使用数据导入扩展来实现数据导入。

Solr数据导入流程大致如下:1. 配置数据源和数据目标,Solr支持多种数据源,包括数据库、文件、RSS等。

2. 配置数据导入的转换器和分词器,将数据源的数据转化为Solr需要的格式。

3. 配置数据导入的定时策略,Solr可以定时从数据源获取数据并导入。

以下是一个Solr数据导入的示例配置文件:```<dataConfig><dataSource name=\"jdbcDataSource\" type=\"JdbcDataSource\" driver=\"com.mysql.jdbc.Driver\"url=\"jdbc:mysql:\/\/localhost:3306\/test\" user=\"root\" password=\"123456\"\/><document><entity name=\"book\" query=\"SELECT * FROM book\"><field column=\"id\" name=\"id\"\/><field column=\"title\" name=\"title\"\/><field column=\"author\" name=\"author\"\/><field column=\"description\" name=\"description\"\/><\/entity><\/document><\/dataConfig>```以上配置会将MySQL数据库中的book表的所有数据导入Solr,并映射到Solr的id、title、author和description字段中。

solrCloud部署简要说明

solrCloud部署简要说明

1.单机部署(1)将solr项目中的dzblcore目录复制到目标盘符中,如:/usr/local/solr下。

(2)将tomcat安装至某个目录,如/usr/local/apache-tomcat-7.0.55。

在/usr/local/apache-tomcat-7.0.55/bin/catalina.bat的setLocal上面添加如下以下内容:set JAVA_OPTS=-Dsolr.solr.home=/usr/local/solr/dzblcore(3)将solr项目打成war包放入/usr/local/apache-tomcat-7.0.55\webapps下(4)修改/usr/local/solr/dzblcore/conf下dataimport.properties文件,配置solr的地址及端口,增量更新及重做索引的时间。

(5)启动tomcat服务。

(6)浏览器地址输入:http://ip:port/solr进行访问2.集群部署A.Zookeeper集群配置,如果要配置3台zookeeper,则请在三台主机上面做以下操作:(1)下载zookeeper压缩包(目前使用较新的稳定版zookeeper-3.4.6)并解压,将解压后的文件夹复制到/usr/local/zookeeper中。

(2)将/usr/local/zookeeper/zookeeper-3.4.6/conf下的zoo_sample.cfg改名为zoo.cfg,并将内容进行修改:、# zookeeper的数据目录需要按目录自己创建该文件,否则报错dataDir=/usr/local/zookeeper/zookeeper-3.4.6/data# zookeeper的日志目录需要按目录自己创建该文件,否则报错dataLogDir=/ usr/local/zookeeper/zookeeper-3.4.6/logs#端口设置,各自设置各自的端口clientPort=2181#server1的IP,2888为Leader服务端口,3888为选举时所用的端口server.1= xxx.xxx.xxx.xxx:2888:3888server.2= xxx.xxx.xxx.xxx: 2888:3888server.3= xxx.xxx.xxx.xxx: 2888:3888说明:端口和IP自己可以按需求进行配置。

SolrCloud高可用集群搭建

SolrCloud高可用集群搭建

solrcloud 高可用集群搭建一、环境准备 (3)二、环境安装 (4)1、CentOs 6.4安装 (4)1)配制用户 (4)2)修改当前机器名称 (4)3)修改当前机器ip (4)4)上传安装包(工具上传WinSCP) (5)2、jdk安装 (5)3、zookeeper集群安装 (6)1)解压zookeeper 安装包 (6)2)进入zookeeper-3.4.5文件夹,创建data 和log (6)3)拷贝zookeeper配制文件zoo_sample.cfg (6)4)修改zoo.cfg (7)5)进入data文件夹建立对应的myid文件 (8)6)制zookeeper-3.4.5文件夹到其他机器 (8)7)开启zookeeper的端口 (8)8)启动zookeeper (8)4、solr集群安装 (9)1)在solrcloud下新建solrhome,并赋于读写权限 (9)2)将上传的solr.4.6.0压缩包解压缩, (9)3)将solr.4.6.0/dist/solr-4.6.0.war 复制到/solrcloud/solrhome 并重命为solr.war (9)4)将上传的tomcat解压缩 (9)5)进入tomcat bin目录,启动tomcat (9)6)停tomcat 再次启动tomcat, webapps 下边多了解压出来的solr文件夹 (10)7)将/solrcloud/solr-4.6.0/example/solr 文件夹下所有东西复制到/solrcloud/solrhome (10)8)复制solr-4.6.0/example/lib/ext下所有jar包到tomcat 的lib下 (11)9)启动tomcat 访问http://localhost:8080/solr 如图,至此单机版solr配制完成 (11)一、环境准备CentOS-6.4-x86_64-minimal.isojdk-6u45-linux-i586-rpm.binzookeeper-3.4.5.tarsolr-4.6.0.zip服务器6台: 192.168.56.11- SolrCloud.Shard1.Leader192.168.56.12-SolrCloud.Shard2.Leader192.168.56.13-SolrCloud.Shard3.Leader192.168.56.14-SolrCloud.Shard1.Replica192.168.56.15-SolrCloud.Shard2.Replica192.168.56.16-SolrCloud.Shard3.Replica二、环境安装1、CentOs 6.4安装1)配制用户安装完后配制用户solrcloud 密码: solrcloud[root@localhost ~]# useradd solrcloud[root@ localhost ~]# passwd solrcloud2)修改当前机器名称vi etc/sysconfig/networkHOSTNAME=SolrCloud.Shard1.Leader3)修改当前机器ipvi /etc/sysconfig/network-scripts/ifcfg-eth0DEVICE=eth0HWADDR=08:00:27:5C:8C:BDTYPE=EthernetUUID=4fc0a398-f82b-49e5-8657-27bf5b260444ONBOOT=yesNM_CONTROLLED=yesIPADDR=192.168.56.11NETMASK=255.255.255.0重启服务service network restart4)上传安装包(工具上传WinSCP)创建文件夹mkdir /solrcloud赋写权限chmod 777 /solrcloud上传所需安装软件包到/solrcloud2、jdk安装默认jdk安装会报错,64位系统安装32位jdk报的错需要安装glic , yum install glibc.i686安装完后再安装jdk 进入/solrcloud目录./jdk-6u45-linux-i586-rpm.bin3、zookeeper集群安装(集群安装测试时以ip为例说明,正式上线后可以配主机名称)1)解压zookeeper 安装包tar -zxvf zookeeper-3.4.5.tar.gz2)进入zookeeper-3.4.5文件夹,创建data 和log创建目录并赋于写权限指定zookeeper的数据存放目录和日志目录3)拷贝zookeeper配制文件zoo_sample.cfg拷贝zookeeper配制文件zoo_sample.cfg并重命名zoo.cfgcp /solrcloud/zookeeper-3.4.5/conf/zoo_sample.cfg /solrcloud/zookerper-3.4.5/conf/zoo.cfg4)修改zoo.cfg加入dataDir=/solrcloud/zookeeper-3.4.5/datadataLogDir=/solrcloud/zookeeper-3.4.5/logserver.1=192.168.56.11:2888:3888server.2=192.168.56.12:2888:3888server.3=192.168.56.13:2888:3888server.4=192.168.56.14:2888:3888server.5=192.168.56.15:2888:3888server.6=192.168.56.16:2888:3888zoo.cfg配制完后如下:# The number of milliseconds of each ticktickTime=2000# The number of ticks that the initial# synchronization phase can takeinitLimit=10# The number of ticks that can pass between# sending a request and getting an acknowledgementsyncLimit=5# the directory where the snapshot is stored.# do not use /tmp for storage, /tmp here is just# example sakes.dataDir=/solrcloud/zookeeper-3.4.5/datadataLogDir=/solrcloud/zookeeper-3.4.5/log# the port at which the clients will connectclientPort=2181## Be sure to read the maintenance section of the# administrator guide before turning on autopurge.## /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=1server.1=192.168.56.11:2888:3888server.2=192.168.56.12:2888:3888server.3=192.168.56.13:2888:3888server.4=192.168.56.14:2888:3888server.5=192.168.56.15:2888:3888server.6=192.168.56.16:2888:38885)进入data文件夹建立对应的myid文件例如server.1=192.168.56.11 data文件夹下的myid文件内容为16)制zookeeper-3.4.5文件夹到其他机器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 #重启防火墙以便改动生效8)启动zookeeper进入bin./zkServer.sh start查看集群状态./zkServer.sh status 刚启动可能会有错误,集群中其他节点一并起来后就正常了4、solr集群安装1)在solrcloud下新建solrhome,并赋于读写权限2)将上传的solr.4.6.0压缩包解压缩,tar -zxvf solr-4.6.0.tgz3)将solr.4.6.0/dist/solr-4.6.0.war 复制到/solrcloud/solrhome 并重命为solr.warcp /solrcloud/solr-4.6.0/dist/solr-4.6.0.war /solrcloud/solrhome/solr.war 4)将上传的tomcat解压缩tar -zxvf apache-tomcat-6.0.29.tar.gz5)进入tomcat bin目录,启动tomcatcd /solrcloud/apache-tomcat-6.0.29/bin进入bin目录./startup.sh启动tomcat此时会在tomcat下的conf文件夹下多出一个目录Catalinacd /solrcloud/apache-tomcat-6.0.29/conf/Catalina/localhost新建solr.xml文件内容如下:<?xml version="1.0" encoding="UTF-8" ?><Context docBase="/solrcloud/solrhome/solr.war" debug="0" crossContext="false" > <Environment name="solr/home"type="ng.String"value="/solrcloud/solrhome"override="true" /></Context>docBase="/solrcloud/solrhome/solr.war" 指定为solrcloud/solrhome下复制出来solr的war 包6)停tomcat 再次启动tomcat, webapps 下边多了解压出来的solr文件夹进入solr/WEB-INF/ 下修改web.xml<!--<env-entry><env-entry-name>solr/home</env-entry-name><env-entry-value>/put/your/solr/home/here</env-entry-value><env-entry-type>ng.String</env-entry-type></env-entry>-->改为:<env-entry><env-entry-name>solr/home</env-entry-name><env-entry-value>/solrcloud/solrhome</env-entry-value><env-entry-type>ng.String</env-entry-type></env-entry>7)将/solrcloud/solr-4.6.0/example/solr 文件夹下所有东西复制到/solrcloud/solrhomecp -r /solrcloud/solr-4.6.0/example/solr/* /solrcloud/solrhome8)复制solr-4.6.0/example/lib/ext下所有jar包到tomcat 的lib下cp /solrcloud/solr-4.6.0/example/lib/ext/* /solrcloud/apache-tomcat-6.0.29/lib/ 复制solr-4.6.0/example/resources/log4j.properties 到solr/WEB-INF/class如果没有class先创建class文件夹,并赋于写权限cp /solrcloud/solr-4.6.0/example/resources/log4j.properties/solrcloud/apache-tomcat-6.0.29/webapps/solr/WEB-INF/class/9)启动tomcat 访问http://localhost:8080/solr 如图,至此单机版solr配制完成10)配制集群将zookeeper和tomcat关联192.168.56.11台机修改tomcat 的bin目录下catalina.sh文件在第二行加入JAVA_OPTS="-Dbootstrap_confdir=/solrcloud/solrhome/collection1/conf-Dcollection.configName=myconf-DzkHost=192.168.56.11:2181,192.168.56.12:2181,192.168.56.13:2181,192.168.56 .14:2181,192.168.56.15:2181,192.168.56.16:2181 -DnumShards=3"192.168.56.12-16 , 5台机都修改tomcat 的bin目录下catalina.sh文件在第二行加入JAVA_OPTS="-DzkHost=192.168.56.11:2181,192.168.56.12:2181,192.168.56.13:2181 ,192.168.56.14:2181,192.168.56.15:2181,192.168.56.16:2181"至此集群配制完毕创建集合http://192.168.56.11:8080/solr/admin/collections?action=CREATE&name=guangzhou&numShar ds=3&replicationFactor=3任何一个ip均可访问http://192.168.56.11:8080/solr/#/~cloud。

solr5.2 solrCloud配置说明

solr5.2 solrCloud配置说明

solrCloud5.2配置说明1,到solr官网下载solr5.2.0,解压到D盘2,复制server目录到server1和server2两个目录3,server1/solr和server2/solr目录结构如下:server1\--gettingstarted\--conf\(从configsets\basic_configs\conf目录复制)--gettingstarted_shard1_replica1\--core.properties--gettingstarted_shard2_replica1\--core.properties--solr.xml--zoo.cfgserver2\--gettingstarted\--conf\(从configsets\basic_configs\conf目录复制)--gettingstarted_shard1_replica2\--core.properties--gettingstarted_shard2_replica2\--core.properties--solr.xml--zoo.cfg各个目录下core.properties内容如下Server目录core.propertiesserver1gettingstarted_shard1_replica1numShards=2name=gettingstarted_shard1_replica1shard=shard1collection=gettingstartedcoreNodeName=core_node1server1gettingstarted_shard2_replica1numShards=2name=gettingstarted_shard2_replica1shard=shard2collection=gettingstartedcoreNodeName=core_node2server2gettingstarted_shard1_replica2numShards=2name=gettingstarted_shard1_replica2shard=shard1collection=gettingstartedcoreNodeName=core_node3server2gettingstarted_shard2_replica2numShards=2name=gettingstarted_shard2_replica2shard=shard2collection=gettingstartedcoreNodeName=core_node44,server1和server2目录下新建start.cmd文件java-Dsolr.solr.home=./solr/gettingstarted-Dcollection.configName=gettingstarted-Dbootstrap_confdir=./solr/gettingstarted/conf-DzkHost=127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183-jar start.jar5,Server1#Module:server--module=server#minimum number of threadsthreads.min=10#maximum number of threadsthreads.max=200#thread idle timeout in millisecondsthreads.timeout=60000#buffer size for outputjetty.output.buffer.size=32768#request header buffer sizejetty.request.header.size=8192#response header buffer sizejetty.response.header.size=8192#should jetty send the server version header?jetty.send.server.version=true#should jetty send the date header?jetty.send.date.header=false#What host to listen on(leave commented to listen on all interfaces)#jetty.host=#Dump the state of the Jetty server,components,and webapps after startupjetty.dump.start=false#Dump the state of the Jetty server,before stopjetty.dump.stop=false#Enable delayed dispatch optimisationjetty.delayDispatchUntilContent=falsejsp-impl=apache#Module:http--module=http##HTTP port to listen onjetty.port=8981##HTTP idle timeout in millisecondshttp.timeout=30000Server2##端口修改为8982,其他都相同jetty.port=89825,启动zookeeper集群,执行server1/start.cmd和server2/start.cmd分别启动两个server。

Solr的原理及在项目中的使用实例.

Solr的原理及在项目中的使用实例.

Solr的原理及在项⽬中的使⽤实例.前⾯已经讲过如果安装及配置Solr服务器了, 那么现在我们就来正式在代码中使⽤Solr.1,这⾥Solr主要是怎么使⽤的呢?当我们在前台页⾯搜索商品名称关键词时, 我们这时是在Solr库中去查找相应的商品信息, 然后将搜索关键词⾼亮.2,那么Solr库中的商品信息⼜是如何添加的呢?当我们在给商品上架的时候, 将商品信息update 到mysql数据库中的bbs_product表中, 然后同样的将相应的信息添加到Solr库中.接下来就看代码的具体实现吧:⼀, 商品上架我们在这⾥点击上架按钮:list.jsp:1<div style="margin-top:15px;"><input class="del-button" type="button" value="删除" onclick="optDelete();"/><input class="add" type="button" value="上架" onclick="i sShow('${name}', '${brandId }', '${isShow }' ,'${pagination.pageNo }')"/><input class="del-button" type="button" value="下架" onclick="isHide();"/></div>点击上架触发isShow事件:1 <script type="text/javascript">2//上架3function isShow(name,brandId,isShow,pageNo){4//请⾄少选择⼀个5var size = $("input[name='ids']:checked").size();6if(size == 0){7 alert("请⾄少选择⼀个");8return;9 }10//你确定上架吗11if(!confirm("你确定上架吗")){12return;13 }14//提交 Form表单15 $("#jvForm").attr("action","/product/isShow.do?name="+ name +"&brandId="+brandId+"&isShow="+isShow+"&pageNo="+pageNo);16 $("#jvForm").attr("method","post");17 $("#jvForm").submit();1819 }20 </script>接着到Controller层:ProductController.java:1//添加页⾯2 @RequestMapping("/isShow.do")3public String isShow(Long[] ids, Model model){4 productService.isShow(ids);5return "forward:/product/list.do";6 }接着看Service层:ProdcutServiceImpl.java:1//上架 @Autowiredprivate SolrServer solrServer;2public void isShow(Long[] ids){3 Product product = new Product();4 product.setIsShow(true);5for (Long id : ids) {6//上下架状态7 product.setId(id);8 productDao.updateByPrimaryKeySelective(product);910//TODO 保存商品信息到Solr服务器11 SolrInputDocument doc = new SolrInputDocument();12//ID13 doc.setField("id", id);14//名称15 Product p = productDao.selectByPrimaryKey(id);16 doc.setField("name_ik", p.getName());17//图⽚URL18 doc.setField("url", p.getImgUrls()[0]);19//品牌 ID20 doc.setField("brandId", p.getBrandId());21//价格 sql查询语句: select price from bbs_sku where product_id = ? order by price asc limit 122 SkuQuery skuQuery = new SkuQuery();23 skuQuery.createCriteria().andProductIdEqualTo(id);24 skuQuery.setOrderByClause("price asc");25 skuQuery.setPageNo(1);26 skuQuery.setPageSize(1);27 List<Sku> skus = skuDao.selectByExample(skuQuery);28 doc.setField("price", skus.get(0).getPrice());29//...时间等剩下的省略3031try {32 solrServer.add(doc);33 mit();34 } catch (Exception e) {35// TODO Auto-generated catch block36 e.printStackTrace();37 }38//TODO 静态化39 }40 }这⾥使⽤SolrInputDocument 来保存商品信息, 其中doc.setField("name_ik", p.getName());的name_ik 是我们在solr 配置⽂件配置的IK 分词器的字段, doc.setField("url", p.getImgUrls()[0]); 这⾥我们也只是取第⼀张图⽚的url⽤来展⽰.这⾥我们还⽤到了skuQuery, 因为⼀个商品中不同的颜⾊不同的尺码都可能有不同的价格, 我们在这⾥是取到同⼀个productId下价格最⼩的来给显⽰~然后再就是将我们已经设置好的SolrInputDocument 通过SolrServer 来提交到Solr服务器. SolrServer是已经在spring中注册好了的, 在这⾥直接注⼊即可使⽤.spring来管理Solr:到了这⾥上架的功能就做好了, 这也是给后⾯Solr查询做好铺垫.⼆, 前台使⽤Solr查询到了这⾥就开始查看前台页⾯了, 前台页⾯是扒的⽹上的, 具体业务逻辑是⾃⼰修改的, 页⾯如下:这⾥需要特殊说明⼀下, 我们配置的全局拦截器变成了: / , ⽽且过滤掉静态资源, 配置如下:⾸先是babasport-portal project下的web.xml⽂件:1<?xml version="1.0" encoding="UTF-8"?>2<web-app version="2.5" xmlns="/xml/ns/javaee"3 xmlns:xsi="/2001/XMLSchema-instance"4 xsi:schemaLocation="/xml/ns/javaee5 /xml/ns/javaee/web-app_2_5.xsd">67<!-- Post过滤器 -->8<filter>9<filter-name>encoding</filter-name>10<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>11<init-param>12<param-name>encoding</param-name>13<param-value>UTF-8</param-value>14</init-param>15</filter>1617<filter-mapping>18<filter-name>encoding</filter-name>19<url-pattern>/</url-pattern>20</filter-mapping>2122<!-- 前端控制器 -->23<servlet>24<servlet-name>portal</servlet-name>25<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>26<init-param>27<param-name>contextConfigLocation</param-name>28<!-- 默认读取的是 WEB-INF/console-servlet.xml -->29<param-value>classpath:springmvc-portal.xml</param-value>30</init-param>31<load-on-startup>1</load-on-startup>32</servlet>3334<servlet-mapping>35<servlet-name>portal</servlet-name>36<!--37 /*: 拦截视图请求: .jsp .js .css ⼏乎不⽤,配置静态资源过滤38 /: 拦截所有,不拦截.jsp ⽂件, 但是同样拦截.js .css 如果使⽤也需要配置静态资源过滤(前台系统使⽤)39 *.do:拦截所有以.do请求, 后台开发应⽤*.do40-->41<url-pattern>/</url-pattern>42</servlet-mapping>43</web-app>View Code第⼆个就是babasport-portal project下的spring配置⽂件中设置过滤掉静态资源:1<!-- 过滤静态资源 -->2<mvc:resources location="/js/" mapping="/js/*.*"/>3<mvc:resources location="/css/" mapping="/css/*.*"/>4<mvc:resources location="/images/" mapping="/images/*.*"/>这样就就可以直接访问了.当我们输⼊2016 点击查询后会出现什么? 我把已经做好的页⾯展⽰⼀下:那么就进⼊到实际的开发当中:当我们在搜索框输⼊2016 且点击搜索时:然后到Controller层去找到search⽅法:1 @Autowired2private SearchService searchService;34//去⾸页5 @RequestMapping(value="/")6public String index(){7return "index";8 }910//搜索11 @RequestMapping(value="/search")12public String search(Integer pageNo, String keyword, String price, Long brandId, Model model){13//品牌结果集 Redis中14 List<Brand> brands = searchService.selectBrandListFromRedis();15 model.addAttribute("brands", brands);1617//map 装已经选择的条件18 Map<String, String> map = new HashMap<String, String>();19if(null != brandId){20for (Brand brand : brands) {21if(brandId.equals(brand.getId())){22 map.put("品牌", brand.getName());23break;24 }25 }26 }27//价格 0-99 1600以上28if(null != price){29 String[] split = price.split("-");30//如果切割后的长度等于2 就说明这是⼀个价格区间31if(split.length == 2){32 map.put("价格", price);33 }else {34 map.put("价格", price + "以上");35 }36 }37 model.addAttribute("map", map);3839 Pagination pagination = searchService.selectPaginationFromSolr(pageNo, keyword, price, brandId);40 model.addAttribute("pagination", pagination);41 model.addAttribute("keyword", keyword);42 model.addAttribute("price", price);43 model.addAttribute("brandId", brandId);4445return "search";46 }提⽰: 这⾥使⽤到了SolrService, 相信看我以前博⽂的朋友都知道这个地⽅还需要配置dubbo, 就是服务提供⽅和适⽤⽅, 这⾥为了简便直接略过, 实际开发中是必须要配置的, 否则就调⽤不了SolrService中的⽅法了.这个controller 中往search.jsp中put了很多东西, 具体这些东西什么⽤我们可以先不管, 我们先看下search.jsp页⾯.⽽且这个controller中查询brand 是从redis中查询出来的, 我们会在下⾯讲到这个.1<c:if test="${fn:length(map) != 0 }">2<div class="sl-b-selected J_brandSelected">3<span class="crumbs-arrow">已选条件:</span>4<c:forEach items="${map }" var="m">5<a title="依琦莲(yiqilian)" href="javascript:;" class="crumb-select-item">6<b>${m.key }:</b><em>${m.value }</em><i></i>7</a>8</c:forEach>9</div>10</c:if>上⾯这个地⽅就是为何要在controller设置map值了, 这个是显⽰已选择的过滤条件.1<c:if test="${empty brandId }">2<div class="J_selectorLine s-brand">3<div class="sl-wrap">4<div class="sl-key"><strong>品牌:</strong></div>5<div class="sl-value">6<div class="sl-v-list">7<ul class="J_valueList v-fixed">8<c:forEach items="${brands }" var="brand">9<li id="brand-38118" data-initial="j" style="display:block;">10<a href="javascript:;" onclick="fqBrand('${brand.id }')" title="${ }"><i></i>${ }</a> 11</li>12</c:forEach>13</ul>14</div>15</div>16</div>17</div>18</c:if>19<c:if test="${empty price }">20<div id="J_selectorPrice" class="J_selectorLine s-line">21<div class="sl-wrap">22<div class="sl-key"><span>价格:</span></div>23<div class="sl-value">24<div class="sl-v-list">25<ul class="J_valueList">26<li>27<a href="javascript:;" onclick="fqPrice('0-99')"><i></i>0-99</a>28</li>29<li>30<a href="javascript:;" onclick="fqPrice('100-299')"><i></i>100-299</a>31</li>32<li>33<a href="javascript:;" onclick="fqPrice('300-599')"><i></i>300-599</a>34</li>35<li>36<a href="javascript:;" onclick="fqPrice('600-999')"><i></i>600-999</a>37</li>38<li>39<a href="javascript:;" onclick="fqPrice('1000-1599')"><i></i>1000-1599</a>40</li>41<li>42<a href="javascript:;" onclick="fqPrice('1600')"><i></i>1600以上</a>43</li>44</ul>45</div>46</div>47</div>48</div>49</c:if>接下来我们来看下对应的js⽅法:1 <script type="text/javascript">2var price = '${price}';3var brandId = '${brandId}';4//过滤品牌id5function fqBrand(id){6if('' != price){7 window.location.href="/search?keyword="+ ${keyword} + "&brandId="+ id+"&price="+price;8 }else{9 window.location.href="/search?keyword="+ ${keyword} + "&brandId="+ id;10 }11 }1213//过滤价格14function fqPrice(id){15if('' != brandId){16 window.location.href = "/search?keyword=${keyword}" + "&brandId=" + brandId + "&price=" + id;17 }else{18 window.location.href = "/search?keyword=${keyword}" + "&price=" + id;19 }20 }21 </script>这个就可以实现添加过滤条件的选项了.三, 使⽤Redis 取出商品品牌列表⾸先当我们在后台添加或者修改品牌时, 我们应该同样将这个品牌添加到Redis中, 格式类似于: {"brandId":"brandName"} controller层:(当我们在后台添加或者修改品牌)1 @Autowired2private Jedis jedis;3//修改4public void updateBrandById(Brand brand){5//保存或修改时修改Redis中的品牌, hmset适合批量添加品牌6/*Map<String, String> map = new HashMap<String,String>();7 map.put(String.valueOf(brand.getId()), brand.getName());8 jedis.hmset("brand", map);*/9 jedis.hset("brand", String.valueOf(brand.getId()), brand.getName());10 brandDao.updateBrandById(brand);11 }redis中有了品牌列表后, 然后就是查询了:1 @Autowired2private Jedis jedis;3//查询Redis中的品牌结果集4public List<Brand> selectBrandListFromRedis(){5 List<Brand> brands = new ArrayList<Brand>();6 Map<String, String> hgetAll = jedis.hgetAll("brand");7 Set<Entry<String, String>> entrySet = hgetAll.entrySet();8for (Entry<String, String> entry : entrySet) {9 Brand brand = new Brand();10 brand.setId(Long.parseLong(entry.getKey()));11 brand.setName(entry.getValue());12 brands.add(brand);13 }1415return brands;16 }到了这⾥redis查询brand就完成了, 那么继续看下关于solr 是如何加⼊过滤条件的吧:1 @Autowired2private SolrServer solrServer;3//查询商品信息从Solr4public Pagination selectPaginationFromSolr(Integer pageNo, String keyword, String price, Long brandId){5 ProductQuery productQuery = new ProductQuery();6//当前页7 productQuery.setPageNo(Pagination.cpn(pageNo));8//每页数9 productQuery.setPageSize(8);1011 SolrQuery solrQuery = new SolrQuery();12//关键词商品名称13 solrQuery.set("q", "name_ik:"+keyword);14//回显数据15 StringBuilder params = new StringBuilder();16 params.append("keyword=").append(keyword);1718//排序19 solrQuery.addSort("price", ORDER.asc);2021//⾼亮22//1,设置, 打开⾼亮的开关23 solrQuery.setHighlight(true);24//2, 设置⾼亮字段25 solrQuery.addHighlightField("name_ik");26//3, 设置关键字⾼亮的样式 <span style='color:red'>2016</span>27//设置前缀和后缀28 solrQuery.setHighlightSimplePre("<span style='color:red'>");29 solrQuery.setHighlightSimplePost("</span>");3031//过滤条件品牌32if(null != brandId){33 solrQuery.addFilterQuery("brandId:"+brandId);34 params.append("&brandId=").append(brandId);35 }36//过滤价格 0-99 160037if(null != price){38 String[] split = price.split("-");39//如果切割后的长度等于2 就说明这是⼀个价格区间40if(split.length == 2){41 solrQuery.addFilterQuery("price:["+split[0]+" TO "+split[1]+"]");42 }else {43 solrQuery.addFilterQuery("price:["+split[0]+" TO *]");44 }45 params.append("&price=").append(price);46 }4748//分页 limit 开始⾏,每页数49 solrQuery.setStart(productQuery.getStartRow());50 solrQuery.setRows(productQuery.getPageSize());5152 QueryResponse response = null;53try {54 response = solrServer.query(solrQuery);5556 } catch (Exception e) {57 e.printStackTrace();58 }59//分析这个Map60//第⼀层Map: Key String == ID : Value: Map61//第⼆层Map: Key String == name_ik : Value: List62//获取到List: String 0,1,2....63 Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();646566 List<Product> products = new ArrayList<Product>();67//结果集68 SolrDocumentList docs = response.getResults();69//总条数70long numFound = docs.getNumFound();71for (SolrDocument doc : docs) {72 Product product = new Product();73//商品的ID74 String id = (String)doc.get("id");75 product.setId(Long.parseLong(id));7677//取第⼆层Map78 Map<String, List<String>> map = highlighting.get(id);79//取List集合80 List<String> list = map.get("name_ik");8182//商品名称83//String name = (String)doc.get("name_ik");84//product.setName(name);85 product.setName(list.get(0)); //list.get(0) 中的name是已经设置为⾼亮的8687//图⽚88 String url = (String)doc.get("url");89 product.setImgUrl(url);90//价格这⾥的价格本⾝是保存在bbs_sku表中的, ⽽我们在这⾥将price属性直接添加到了Product中91//因为我们在做上架的时候, 查询的是bbs_sku中price最⼩的值然后保存到solr中的, 所以这⾥我们就直接将price属性添加到product中了 92//这⾥的价格只有⼀个值93//Float price = (Float)doc.get("price");94 product.setPrice((Float)doc.get("price"));95//品牌ID96//Integer brandId = (Integer)doc.get("brandId");97 product.setBrandId(Long.parseLong(String.valueOf((Integer)doc.get("brandId"))));98 products.add(product);99 }100101 Pagination pagination = new Pagination(102 productQuery.getPageNo(),103 productQuery.getPageSize(),104 (int)numFound,105 products106 );107//页⾯展⽰108 String url = "/search";109 pagination.pageView(url, params.toString());110111return pagination;112 }这个就是本博⽂的重中之重了, code上⾯都加了注释, 相信还是⽐较容易理解的.。

solrcloud

solrcloud

solrcloud集群搭建1什么是SolrCloud1.1什么是SolrCloudSolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用SolrCloud。

当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高,这时需要使用SolrCloud来满足这些需求。

1.2SolrCl oud结构SolrCloud为了降低单机的处理压力,需要由多台服务器共同来完成索引和搜索任务。

实现的思路是将索引数据进行Shard(分片)拆分,每个分片由多台的服务器共同完成,当一个索引或搜索请求过来时会分别从不同的Shard的服务器中操作索引。

SolrCloud需要Solr基于Zookeeper部署,Zookeeper是一个集群管理软件,由于SolrCloud 需要由多台服务器组成,由zookeeper来进行协调管理。

下图是一个SolrCloud应用的例子:对上图进行图解,如下:1.2.1物理结构三个Solr实例(每个实例包括两个Core),组成一个SolrCloud。

1.2.2逻辑结构索引集合包括两个Shard(shard1和shard2),shard1和shard2分别由三个Core组成,其中一个Leader两个Replication,Leader是由zookeeper选举产生,zookeeper控制每个shard上三个Core的索引数据一致,解决高可用问题。

用户发起索引请求分别从shard1和shard2上获取,解决高并发问题。

1.2.2.1c ollectionCollection在SolrCloud集群中是一个逻辑意义上的完整的索引结构。

它常常被划分为一个或多个Shard(分片),它们使用相同的配置信息。

比如:针对商品信息搜索可以创建一个collection。

collection=shard1+shard2+....+shardX1.2.2.2C ore每个Core是Solr中一个独立运行单位,提供索引和搜索服务。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

SolrCloud使用教程、原理介绍发布于2013 年 8 月 24 日,属于搜索分类,7,446 浏览数SolrCloud 是基于 Solr 和 Zookeeper 的分布式搜索方案,是正在开发中的 Solr4.0 的核心组件之一,它的主要思想是使用 Zookeeper 作为集群的配置信息中心。

它有几个特色功能:①集中式的配置信息②自动容错③近实时搜索④查询时自动负载均衡。

下面看看 wiki 的文档:1、SolrCloudSolrCloud 是指 Solr 中一套新的潜在的分发能力。

这种能力能够通过参数让你建立起一个高可用、容错的 Solr 服务集群。

当你需要大规模,容错,分布式索引和检索能力时使用SolrCloud(solr 云)。

看看下面“启动”部分内容,快速的学会怎样启动一个集群。

后面有 3 个快速简单的例子,它们展现怎样启动一个逐步越来越复杂的集群。

检出例子之后,需要翻阅后面的部分了解更加细节的信息。

2、关于 SolrCores 和 Collections 的一点儿东西对于单独运行的 Solr 实例,它有个东西叫 SolrCore(Solr.xml 中配置的),它是本质上独立的索引块。

如果你打算多个索引块,你就创建多个 SolrCores。

当同时部署SolrCloud 的时,独立的索引块可以跨越多个 Solr 实例。

这意味着一个单独的索引块能由不同服务器设备上多个 SolrCore 的索引块组成。

我们把组成一个逻辑索引块的所有 SolrCores 叫做一个独立索引块儿(collection)。

一个独立索引块是本质上一个独立的跨越多个 SolrCore 索引块的索引块,同时索引块尽可能随着多余的设备进行缩放。

如果你想把你的两个 SolrCore Solr 建立成 SolrCloud,你将有 2 个独立索引块,每个有多个独立里的 SolrCores 组成。

3、启动下载 Solr4-Beta 或更高版本。

如果你还没了解,通过简单的Solr 指南让自己熟悉Solr。

注意:在通过指南了解云特点前,重设所有的配置和移除指南的文档.复制带有预先存在的 Solr 索引的例子目录将导致文档计数关闭Solr 内嵌使用了Zookeeper 作为集群配置和协调运作的仓储。

协调考虑作为一个包含所有 Solr 服务信息的分布式文件系统。

如果你想用一个其他的而不是 8983 作为 Solr 端口,去看下面’ Parameter Reference’部分下的关于solr.xml 注解例 A:简单的 2 个 shard 集群这个例子简单的创建了一个代表一个独立索引块的两个不同的 shards 的两个 solr 服务组成的集群。

从我们将需要两个 solr 服务器,简单的复制例子目录副本作为第二个服务器时,要确保没有任何索引存在。

1 2 rm -r example/solr/collection1/data/*cp -r example example2下面的命令启动了一个 solr 服务同时引导了一个新的 solr 集群1 2 3 cd examplejava -Dbootstrap_confdir=./solr/collection1/conf-Dcollection.configName=myconf -DzkRun -DnumShards=2 -jar start.jar •-DzkRun 该参数将促使一个内嵌的 zookeeper 服务作为 Solr 服务的部分运行起来。

•-Dbootstrap_confdir=./solr/collection1/conf 当我们还没有 zookeeper 配置时,这个参数导致本地路径./solr/conf 作为“myconf”配置被加载.“myconf”来自下面的“collection.configName”参数定义。

•-Dcollection.configName=myconf 设置用于新集合的配置名。

省略这个参数将导致配置名字为默认的“configuration1”•-DnumShards=2 我们打算将索引分割到逻辑分区的个数。

浏览 http://localhost:8983/solr/#/~cloud 地址,看看集群的状态。

你从 zookeeper 浏览程序能看到 Solr 配置文件被加载成”myconf”,同时一个新的叫做”collection1”的文档集合被创建.collection1 下是碎片列表,这些碎片组成了那完整的集合。

现在我们想要启动我们的第二个服务器;因为我们没明确设置碎片 id ,它将自动被设置成shard2,启动第二个服务器,指向集群1 2 cd example2java -Djetty.port=7574 -DzkHost=localhost:9983 -jar start.jar•-Djetty.port=7574 只是一种用于让 Jetty servlet 容器使用不同端口的方法•-DzkHost=localhost:9983 指向全体包含集群状态的 Zookeeper 服务.这个例子中,我们运行的是一个内嵌在第一个 solr 服务器中的独立的 Zookeeper 服务.默认情况下,一个内嵌的Zookeeper 服务运行在 9983 端口上。

如果你刷新浏览器,你现在在 collection1 下应该看到两个shard1 和 shard2。

接下来,索引一些文档。

如果你想要快速完成一些,像 java 你能够使用 CloudSolrServer solrj 的实现和简单的用 Zookeeper 地址初始化它就可以了.或者也可以随便选择某个 solr 实例添加文档,这些文档自动的被导向属于他们的地方。

1 2 3 4 cd exampledocsjava -Durl=http://localhost:8983/solr/collection1/update-jar post.jar ipod_video.xmljava -Durl=http://localhost:8983/solr/collection1/update-jar post.jar monitor.xmljava -Durl=http://localhost:8983/solr/collection1/update-jar post.jar mem.xml现在,发起一个获得覆盖整个集合的分布式搜索服务搜索到的任何一个服务的结果的请求:1 http://localhost:8983/solr/collection1/select?q=*:*如果在任一个点你希望重新加载或尝试不同的配置,你能通过关闭服务器后简单的删除solr/zoo_data 目录方式删除所有 zookeeper 的云状态。

例 B:简单的支持副本的两个碎片集群有先前的例子,这个例子通过再创建 shard1 和 shard2 副本很容易创建起来。

额外的 shard 副本用于高可用性和容错性,或用于提高集群的检索能能力。

首先,通过前一个例子,我们已经有两个碎片和一些文档索引在里面了。

然后简单的复制那两个服务:1 2 cp-r example exampleB cp-r example2 example2B然后在不同的端口下启动这两个新的服务,每个都在各自的视窗下执行1 2 3 4 cd exampleBjava -Djetty.port=8900 -DzkHost=localhost:9983 -jar start.jar cd example2Bjava -Djetty.port=7500 -DzkHost=localhost:9983 -jar start.jar刷新 zookeeper 浏览页面,核实 4 个 solr 节点已经启动,并且每个 shard 有两个副本,因为我们已经告诉 Solr 我们想要 2 个逻辑碎片,启动的实例 3 和 4 自动的被负值为两个 shards 的副本。

现在,向任何一个服务器发送请求来查询这个集群1 http://localhost:7500/solr/collection1/select?q=*:*多次发送这个请求,来研究 solr 服务的日志。

你应该能够发现 Solr 实现跨副本的负载均衡请求,用不同的服务满足每一个请求。

浏览器发送请求的服务器里有一个顶层请求的日志描述,也会有被合并起来生成完成响应的子请求的日志描述。

为了证明故障切换的可用性,在任何一个服务器(除了运行 Zookeeper 的服务器)运行窗口下按下CTRL-C。

一旦那个服务实例停止运行,就向剩余运行的服务器的任何一个发送另一个查询请求,你应该仍然看到完整的结果。

SolrCloud 能够持续提供完整查询服务直到最后一个维护每一个碎片的服务器当机.你能通过明确地关闭各个实例和查询结果来证明这种高可用性。

如果你关掉维护某一个碎片的所有服务器,请求其他服务器时将会返回 503 错误结果。

要想从依然运行的碎片服务中返回可用的正确文档,需要添加shards.tolerant=true 查询参数。

SolrCloud 用多主服务+监控者服务实现。

这意味着某写节点或副本扮演一种特殊角色。

你不需要担忧你关掉的是主服务或是集群监控,如果你关掉它们中的一个,故障切换功能将自动选出新的主服务或新的监控服务,新的服务将无缝接管各自的工作。

任何 Solr 实例都能被升级为这些角色中的某个角色。

例 C:支持副本和完整 zookeeper 服务的两个碎片集群例 B 的问题是可以有足够多的服务器保证任何一个损坏的服务器的信息幸存下来,但确只有一个包含集群状态的 zookeeper 服务器。

如果那台 zookeeper 服务器损坏,分布式查询将仍然工作在上次zookeeper 保存的集群状态下,可能没有机会改变集群的状态了。

在 a zookeeper ensemble(zookeeper 集群)中运行多个 zookeeper 服务器保证 zookeeper 服务的高可用性。

每个 zookeeper 服务器需要知道集群中其他服务器,且这些服务器中的一个主服务器需要提供服务。

例如: 3 台组成的 zookeeper 集群允许任一个故障,而后通过剩余 2 个协商一个主服务继续提供服务。

5 台的需要允许一次 2 个服务器故障。

对于用于生产服务时,推荐运行一个额外的 zookeeper 集群而不是运行内嵌在 Solr 里面的zookeeper服务。

在这里你能阅读更多关于建立 zookeeper 集群的知识。

对于这个例子,为了简单点我们将用内嵌的 zookeeper 服务。

首先停止 4 个服务器并清理 zookeeper 数据1 rm-r example*/solr/zoo_data我们将分别在 8983,7574,8900,7500 端口运行服务。

相关文档
最新文档