solrCloud的使用

SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud。当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高,这时需要使用SolrCloud来满足这些需求。

 SolrCloud是基于Solr和Zookeeper的分布式搜索方案,它的主要思想是使用Zookeeper作为集群的配置信息中心。也就是管理集群的.

它有几个特色功能:

1)集中式的配置信息

2)自动容错

3)近实时搜索

4)查询时自动负载均衡

Solr集群的系统架构

如下图,上半部分是实现的过程,下半部分是原理,看下半部分,就是把所有的数据交给collection来管理,它下面可以分无数个分片,每个分片下可以有无数个节点,这些节点存储具体的数据,每个片下的节点存储的数据是相同的,一个主节点两个副节点,当并发量高的时候副节点也可以使用,也就是当数据存储不下的时候可以加分片,当并发量提升的时候,加节点.节点就相当于上半图的core索引库,分片就相当于solr服务器.

这个图中的collection不是solr单机版中的核,每个分片才是每一个核,把每个核都集中到一块就是集群

搭建solr集群,因为没那么多服务器,所以搭建一个伪集群,在一台服务器上实现,搭建前先搭建好一台solr服务器https://blog.csdn.net/kxj19980524/article/details/85238989我下面写的是直接在一台的基础上搭建的.

首先搭建一个zookeeper集群https://blog.csdn.net/kxj19980524/article/details/85528403

然后开始搭建solr集群,因为每个solr都是在一个tomcat上运行的,所以需要四个tomcat,复制四份tomcat到solr-cloud下

 然后复制单机版的solr分别放到每个tomcat的webapps下

然后进入tomcat01/conf/server.xml下改这三个端口号,tomcat02,和03,04也都改了,只要改成不同的就可以了.

tomcat02

tomcat03

04我就不截了,改好后把solrhome复制四份

然后进入到第一个tomcat的web.xml改成相应的solrhome的位置,把四个都改成相应的位置,我就不一一截图了.

然后进入第一个solrhome中修改solr.xml,把ip地址和端口改成想对应的.这就演示一个把其余三个都改了

然后建立zookeeper集群和solr集群的连接,进入tomcat01下的bin下的catalina.sh编辑它

JAVA_OPTS="-DzkHost=192.168.25.155:2181,192.168.25.155:2182,192.168.25.155:2183"

在这个地方加一行配置,端口号和ip改成zookeeper集群的端口ip就可以了,然后把其余三个tomcat也都加上同样的配置就可以了.

配置好,因为现在是集群了,但是每个solrhome下都有自己独自的配置域的配置文件,现在需要上传给zookeeper统一管理.使用zookeeper的客户端进行上传,客户端在解压缩的solr下面.

执行下面这个命令进行上传,把ip和端口改成zookeeper的ip端口

 ./zkcli.sh -zkhost 192.168.25.155:2181,192.168.25.155:2182,192.168.25.155:2183 -cmd upconfig -confdir /usr/local/solr-cloud/solrhome01/collection1/conf -confname myconf

执行完后查看一下是否上传成功了,进入到zookeeper下的客户端进行查看,就会看到上传成功的文件了,默认连接的是2181端口的zookeeper,也可以使用命令./zkCli.sh -server 192.168.25.155:2182来指定zookeeper的端口进行访问.

然后输入quit命令退出客户端,启动所有tomcat,编写脚本,然后给它权限,并启动

/usr/local/solr-cloud/tomcat01/bin/startup.sh
/usr/local/solr-cloud/tomcat02/bin/startup.sh
/usr/local/solr-cloud/tomcat03/bin/startup.sh
/usr/local/solr-cloud/tomcat04/bin/startup.sh

然后分别查看四个tomcat的启动状况看看是否启动成功

tail -f /usr/local/solr-cloud/tomcat01/logs/catalina.out

然后关闭防火墙,进行访问solr

现在只有一个索引库并且是一片,一个主节点三个备份节点,现在只能做负载均衡实现高并发,并不能实现扩大索引库的效果,所以需要执行命令,这个命令之间在浏览器路径执行就可以了,这个命令的意思是,创建一个controller2索引库,numShards的意思是分为两片replicationFactor的意思是每片两个节点一主一备,把ip改为自己的就可以了

http://192.168.25.155:8180/solr/admin/collections?action=CREATE&name=collection2&numShards=2&replicationFactor=2

执行完后再刷新solr页面,就会发现建好了

执行这个命令还可以把不用的controller1删除掉

http://192.168.25.155:8180/solr/admin/collections?action=DELETE&name=collection1

这个集群的整个搭建过程就完成了

接下来使用solrj管理solrCloud集群 ,在这之前先看一下单机版的Solrj管理方式https://blog.csdn.net/kxj19980524/article/details/85202324

导哪些包就不截图了在单机版都有,直接上代码了

package cn.e3mall.solrj;

import org.apache.solr.client.solrj.SolrQuery;
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;
import org.junit.Test;

public class TestSolrCloud {

	@Test
	public void testAddDocument() throws Exception {
		//创建一个集群的连接,应该使用CloudSolrServer创建。
		//zkHost:zookeeper的地址列表   参数是zookeeper的ip地址
		CloudSolrServer solrServer = new CloudSolrServer("192.168.25.163:2181,192.168.25.163:2182,192.168.25.163:2183");
		//设置一个defaultCollection属性。
		solrServer.setDefaultCollection("collection2");
		//创建一个文档对象
		SolrInputDocument document = new SolrInputDocument();
		//向文档中添加域
		document.setField("id", "solrcloud01");
		document.setField("item_title", "测试商品01");
		document.setField("item_price", 123);
		//把文件写入索引库
		solrServer.add(document);
		//提交
		solrServer.commit();
		
	}
	
	@Test
	public void testQueryDocument() throws Exception {
		//创建一个CloudSolrServer对象
		CloudSolrServer cloudSolrServer = new CloudSolrServer("192.168.25.163:2181,192.168.25.163:2182,192.168.25.163:2183");
		//设置默认的Collection
		cloudSolrServer.setDefaultCollection("collection2");
		//创建一个查询对象
		SolrQuery query = new SolrQuery();
		//设置查询条件
		query.setQuery("*:*");
		//执行查询
		QueryResponse queryResponse = cloudSolrServer.query(query);
		//取查询结果
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		System.out.println("总记录数:" + solrDocumentList.getNumFound());
		//打印
		for (SolrDocument solrDocument : solrDocumentList) {
			System.out.println(solrDocument.get("id"));
			System.out.println(solrDocument.get("title"));
			System.out.println(solrDocument.get("item_title"));
			System.out.println(solrDocument.get("item_price"));
		}
	}
}

上面这个是测试demo,在项目中使用的话参考https://blog.csdn.net/kxj19980524/article/details/85238989

这个里面是注入的单击版的,现在使用集群版的话别的不用改,只要把注入的对象换成集群的对象就可以了

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">

	<!-- 单机版solrJ -->
	<!-- <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
		<constructor-arg index="0" value="http://192.168.25.163:8080/solr/collection1"/>
	</bean> -->
	<!-- 集群版solrJ -->
	<bean id="cloudSolrServer" class="org.apache.solr.client.solrj.impl.CloudSolrServer">
		<constructor-arg index="0" value="192.168.25.163:2181,192.168.25.163:2182,192.168.25.163:2183"></constructor-arg>
		<property name="defaultCollection" value="collection2"></property>
	</bean>
</beans>

搜索框调用的方法根据搜索内容返回相对应的信息

package cn.e3mall.search.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.e3mall.common.pojo.SearchItem;
import cn.e3mall.common.pojo.SearchResult;

/**
 * 商品搜索dao
 * <p>Title: SearchDao</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
@Repository
public class SearchDao {
	
	@Autowired
	private SolrServer solrServer;

	/**
	 *根据查询条件查询索引库
	 * <p>Title: search</p>
	 * <p>Description: </p>
	 * @param query
	 * @return
	 */
	public SearchResult search(SolrQuery query) throws Exception {
		//根据query查询索引库
		QueryResponse queryResponse = solrServer.query(query);
		//取查询结果。
		SolrDocumentList solrDocumentList = queryResponse.getResults();
		//取查询结果总记录数
		long numFound = solrDocumentList.getNumFound();
		SearchResult result = new SearchResult();
		result.setRecordCount(numFound);
		//取商品列表,需要取高亮显示
		Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
		List<SearchItem> itemList = new ArrayList<>();
		for (SolrDocument solrDocument : solrDocumentList) {
			SearchItem item = new SearchItem();
			item.setId((String) solrDocument.get("id"));
			item.setCategory_name((String) solrDocument.get("item_category_name"));
			item.setImage((String) solrDocument.get("item_image"));
			item.setPrice((long) solrDocument.get("item_price"));
			item.setSell_point((String) solrDocument.get("item_sell_point"));
			//取高亮显示
			List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
			String title = "";
			if (list != null && list.size() > 0) {
				title = list.get(0);
			} else {
				title = (String) solrDocument.get("item_title");
			}
			item.setTitle(title);
			//添加到商品列表
			itemList.add(item);
		}
		result.setItemList(itemList);
		//返回结果
		return result;
	}
	
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值