SOLR是最流行且高度可扩展的搜索引擎之一,它基于分布式索引技术运行。 Solr索引几乎可以基于任何类型的数据源(CSV数据或XML数据或从RDBMS数据库或标准文件系统中提取的数据)构建。
对于以RDBMS数据库作为后端构建的任何Web应用程序,如果需要在具有数百万行的表上执行搜索,或者需要执行连接多个表的查询,则可能需要花费大量时间才能完成得到回应。 这种后端服务使网站速度极慢。 在这些情况下,SOLR索引编制可能是有用的解决方案。 SOLR可以以反向索引文档的形式存储数据,该文档包含多个字段,每个字段都有一个名称和值。 SOLR的单个实例通常对于中小型数据库就足够了。 如果大型数据库需要在数十亿行上执行查询,则需要一种分布式索引解决方案,其中索引需要分布在多个分片和群集中。 SOLR云就是为此目的而设计的。 但是,管理SOLR云的节点,分片和副本是一项艰巨的任务,无法手动完成。 与外部Zookeeper集群配对可以通过将查询路由到正确的Solr实例来帮助进行SOLR云管理,以及诸如负载平衡和容错之类的其他好处。
但是,使用外部Zookeeper集成建立SOLR云集群非常复杂,对于开发人员而言似乎是一项艰巨的任务。 在本文中,我们将通过简单的步骤以及必要的代码片段和屏幕快照,讨论使用Zookeeper集群进行Solr云设置和实现。 我们将创建多个SOLR碎片,并通过zookeeper对其进行操作。 后来,通过使用SOLRJ API的spring boot micro服务对设置进行了测试。 SOLRJ是一个API,可帮助Java应用程序与SOLR通信并执行查询。 在下面显示的示例中,我已将Java 8用于JDK和Eclipse作为IDE。
1. Zookeeper设置
以下是设置Zookeeper集成的分步说明:
-
- 从URL https://zookeeper.apache.org/releases.html下载最新的Zookeeper
-
- 在每个conf文件中,将dataDir位置更新为
server.1=YourServerName:2888:3888
server.2= YourServerName:2889:3889
server.3= YourServerName:2890:3890
- 在上面的conf文件的dataDir属性中提到的相应位置创建3个文件夹。 (
/opt/user_projects/poc/tmp/1 , /opt/user_projects/poc/tmp/2, /opt/user_projects/poc/tmp/3
)。 - 在创建的每个文件夹中,制作一个新文件并将其命名为“ myid”,然后根据文件夹名称输入序列号(1或2或3)。
- 这样就完成了Zookeeper配置。
2. SOLR Cloud设置
现在让我们开始Solr云配置。
- 从URL http://lucene.apache.org/solr/downloads.html下载最新的Solr。
- 导航到solr安装文件夹下的服务器目录,并在其中创建4个solr文件夹。 在我的情况下,它是
/opt/user_projects/poc/solrpoc/solr-7.4.0/server': solr, solr2, solr3, solr4
如下图所示。
- 上面创建的每个solr文件夹都应具有solr.xml,并且必须在该文件中分配端口,如下所示。
${jetty.port:8993}
- 另外,您应该在同一文件夹中有一个configsets。 如果要使用数据库,则应具有data_driven_schema_configs。
- 修改端口后。 Solr设置已经准备就绪。
3.启动Zookeeper
- 在启动Zookeeper之前,请确保已设置JAVA_HOME。
- 为Zookeeper准备启动和停止脚本,然后将它们放在
/opt/user_projects/poc/solrpoc/zookeeper-3.4.12/startZookeeper.sh
和stopZookeeper.sh
,如下所示。
SOLR启动脚本
#!/bin/sh
echo "-----------------------------------"
echo "Starting all Solr Instances"
source /opt/sun_jdk/jdkversion/jdkversion.conf
bin/solr start -Duser.timezone="America/Los_Angeles" -c -s server/solr -p 8993 -z yourServer:8997,yourServer:8998,yourServer:8999 -noprompt
bin/solr start -Duser.timezone="America/Los_Angeles" -c -s server/solr2 -p 8994 -z yourServer:8997,yourServer:8998,yourServer:8999 -noprompt
bin/solr start -Duser.timezone="America/Los_Angeles" -c -s server/solr3 -p 8995 -z yourServer:8997,yourServer:8998,yourServer:8999 -noprompt
bin/solr start -Duser.timezone="America/Los_Angeles" -c -s server/solr4 -p 8996 -z yourServer:8997,yourServer:8998,yourServer:8999 -noprompt
echo ""
echo "Started all Solr Instances"
echo "---------------------------------"
- 为Solr准备启动和停止脚本,并将它们放在
/opt/user_projects/poc/solrpoc/solr-7.4.0/startSolr.sh
执行此脚本时,solr开始在指定的端口上运行。
4.设置收藏
-
- SOLR运行之后,确保将与数据库相关的jar复制到dist并在
solrconfig.xml
提到该依赖项。
- SOLR运行之后,确保将与数据库相关的jar复制到dist并在
- 执行完上述创建命令后,您可以转到Solr Admin UI并查看如下所示的集合。
- 创建集合后,我们可以如下所示运行Dataimport。 单击执行。
这样就完成了SOLR cloud
设置。
5.使用SOLRJ的SPRING BOOT客户端
现在,我们将讨论如何在基于Spring Boot的微服务中测试SOLR集群并使用SOLRJ API查询数据。 我提供了github链接,该链接提供了整个项目代码。
- 使用以下结构创建一个新的spring boot项目。
-
- 配置gradle依赖项以包括SOLRJ库。
SOLRJ util连接到Zookeeper
@Service
public class SolrUtil {
CloudSolrClient solrClient;
@SuppressWarnings("deprecation")
public CloudSolrClient createConnection(){
//You need to replace SERVERNAME with the server on which the zookeeper is running
String zkHostString = "SERVERNAME:8997,SERVERNAME:8998,SERVERNAME:8999"; //- DEV
if(solrClient == null){
solrClient = new CloudSolrClient.Builder().withZkHost(zkHostString).build();
}
return solrClient;
}
public SolrDocumentList getSolrResponse(SolrQuery solrQuery, String collection, CloudSolrClient solrClient) {
QueryResponse response = null;
SolrDocumentList list = null;
try {
QueryRequest req = new QueryRequest(solrQuery);
solrClient.setDefaultCollection(collection);
response = req.process(solrClient);
list = response.getResults();
} catch (Exception e) {
e.printStackTrace();//handle errors in this block
}
return list;
}
}
- 现在创建一个SolrSearchService,它可以调用查询,更新文档或在SOLR中删除,如下所示。
SOLRJ服务到CRUD Solr文档
@Service
public class SolrSearchService {
@Autowired
SolrUtil solrUtil;
private static final String collection = "UserSearchCloud";
public ResponseVO search(SearchRequestVO requestVO) {
CloudSolrClient solrClient = solrUtil.createConnection();
String query = requestVO.getQuery();
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(query);
solrQuery.setRows(50);
solrQuery.set("collection", collection);
solrQuery.set("wt", "json");
SolrDocumentList documentList = solrUtil.getSolrResponse(solrQuery, collection, solrClient);
ResponseVO responseVO = new ResponseVO();
if(documentList != null && documentList.size() >0){
responseVO.setDocumentList(documentList);
responseVO.setMessage("Success");
}else{
responseVO.setMessage("Failure");
responseVO.setErrorMessage("Records Not Found");
}
return responseVO;
}
public ResponseVO update(UpdateRequestVO requestVO) {
CloudSolrClient solrClient = solrUtil.createConnection();
UpdateResponse response = new UpdateResponse();
SolrDocument sdoc1 = null;
String id = requestVO.getId();
solrClient.setDefaultCollection(collection);
SolrInputDocument sdoc = new SolrInputDocument();
try {
sdoc1 = solrClient.getById(id);
} catch (SolrServerException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
if(sdoc1 != null){
sdoc.setField("FIRST_NAME",requestVO.getFirstName() != null ? requestVO.getFirstName() : sdoc1.get("FIRST_NAME"));
sdoc.setField("WORK_EMAIL",requestVO.getWorkEmail() != null ? requestVO.getWorkEmail() : sdoc1.get("WORK_EMAIL"));
sdoc.setField("LAST_NAME",requestVO.getLastName() != null ? requestVO.getLastName() : sdoc1.get("LAST_NAME"));
sdoc.setField("ADDRESS1",requestVO.getAddress1() != null ? requestVO.getAddress1() : sdoc1.get("ADDRESS1"));
sdoc.setField("ADDRESS2",requestVO.getAddress2() != null ? requestVO.getAddress2() : sdoc1.get("ADDRESS2"));
sdoc.setField("PHONE1",requestVO.getPhone1() != null ? requestVO.getPhone1() : sdoc1.get("PHONE1"));
sdoc.setField("JOB_TITLE",requestVO.getJobTitle() != null ? requestVO.getJobTitle() : sdoc1.get("JOB_TITLE"));
sdoc.setField("COMPANY_NAME",requestVO.getCompanyName() != null ? requestVO.getCompanyName() : sdoc1.get("COMPANY_NAME") );
sdoc.setField("CITY",requestVO.getCity() != null ? requestVO.getCity() : sdoc1.get("CITY"));
sdoc.setField("PHONE2",requestVO.getPhone2() != null ? requestVO.getPhone2() : sdoc1.get("PHONE2"));
sdoc.setField("USER_NAME",requestVO.getUserName() != null ? requestVO.getUserName() : sdoc1.get("USER_NAME"));
sdoc.setField("id",sdoc1.get("id"));
sdoc.setField("_version_","0");
try {
solrClient.add(sdoc);
response = solrClient.commit();
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
ResponseVO responseVO = new ResponseVO();
if(response != null && response.getResponse() != null){
responseVO.setMessage("Document Updated");
}else{
responseVO.setErrorMessage("Document Not Found");
}
return responseVO;
}
public ResponseVO delete(DeleteRequestVO requestVO) {
CloudSolrClient solrClient = solrUtil.createConnection();
UpdateResponse response = new UpdateResponse();
try {
solrClient.setDefaultCollection(collection);
response = solrClient.deleteById(requestVO.getId());
} catch (SolrServerException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
ResponseVO responseVO = new ResponseVO();
if(response != null){
responseVO.setMessage("Document Deleted");
}
return responseVO;
}
}
- 最后,您可以在启动Spring Boot服务之后从任何其他客户端测试服务。
这样就完成了整个端到端测试。
6.下载源代码
这是一个使用Zookeeper集成配置SOLR云并通过基于Spring boot的SOLRJ项目访问它的示例。
您可以在这里下载该项目的完整源代码: SOLRJ-ZOOKEEPER-INTEGRATION