问题背景
公司内部从2015年9月开始部署了Solr5.3 搜素引擎服务,到今年年初Solr的版本已经发展到了Solr6.x,无奈开源社区的发张的确很快,因为Solr6服务端整合了Facebook的prestodb数据库的Sql解析引擎( http://prestodb-china.com/),可以让Solr6服务端支持简单的sql语句查询,一时间搜索引擎可以支持Sql语句查询,虽然目前只能支持很简单的单表查询语句和集中功能简单的聚合查询,总之Solr在nosql DB方面走出了坚实的一步。更加方便的是Solrj代码包中提供了一个实现了jdbc接口的API包,这样使得一般的开发工程师可以轻松编写基于搜索引擎的查询操作。
这么好的功能我们当然是尝试用一下的,所以当时以很快的速度在老版本Solr集群之上部署了新Solr6的collection,不过没有过多久发现了一个严重的问题。问题是,当调用类似以下API会出现问题:
http://10.1.5.19:8080/solr/admin/collections?action=CREATE&name=collection1 |
当调用admin/collections的API 来向集群提交一个创建新Collection的请求的时候,操作往往会超时,报序列化异常相关的异常,无论通过这个api创建的collection是solr5还是solr6的都会有问题,不能能成功创建。
其他几个api也无一例外的有这样的问题。比如:
curl 'http://localhost:8080/solr/admin/collections?action=DELETE&name=search4totalpay' |
原因分析
找原因的时候,很容易联想到是不是因为在原本只有solr5节点的集群中添加了版本为solr6的节点呢?最后看了一堆代码之后发现的确是因为在老集群中。
先来看一幅执行“/admin/collections” api的集群调用流程图,如下:
集群创建collection流程说明:
- 对solr集群任何一个节点发起/admin/collections?action=CREATE 这样的API请求(对应处理类:org.apache.solr.handler.admin.CollectionsHandler),
- 节点收收到请求之后,向zookeeper中写一个临时节点,节点内容是这次执行任务的内容(格式为json),在OverseerCollectionProcessor中的run() 方法中执行,最终执行任务会代理到org.apache.solr.cloud.OverseerCollectionProcessor.Runner 类上执行。
- 上图中背景标注为黄色的节点(该节点为监工节点,是由所有节点竞争出来的)认领zookeeper临时节点的任务,
- 监工(overseer)节点执行该节点中的任务,当action=CREATE时,就是向其他节点再分发创建collection replic节点的命令了,对应该的命令路径为“/admin/cores”
- 等到所有replic都创建成功之后,有overseer节点再向zookeeper中写一个执行成功的标记,最终用户就能感知到本次任务已经执行成功了(当然该任务的执行也能够通过异步的方式来执行)
到此,问题的关键点就明白了,关键在第二和第三步,由solr6向solr5节点(高版本节点向低版本)发送/admin/collections 这类请求是存在问题,Solr API在向前兼容上存在问题,但是测试中发现由solr5向solr6发送请求是没有问题,也就是Solr向后兼容没有问题
解决之法:
了解了问题点,现在就能着手解决了。很简单,只需要在Solr6引擎节点启的时候,将Solr6节点参与Overseer角色竞争的流程去掉,让Solr6节点没有机会成为Overseer角色,要达到这个目的,先要了解一下Overseer竞选相关的代码结构。
先看以下类图:
ZkController初始化时,会初始化LeaderElector对象,LeaderElector会将本地节点信息预先写到/overseer_elect/election 节点下参与leader竞选。solr有两种场景需要竞选Leader,一种是上面说到的集群监工负责执行提交给cloud任务,另外一个是执行share内master任务的节点。
执行逻辑分别被封装在OverseerElectionContext 和ShardLeaderElectionContextBase中。
需要修改的点是,ZkController中init()方法中:
private void init(CurrentCoreDescriptorProvider registerOnReconnect) { try { createClusterZkNodes(zkClient); zkStateReader.createClusterStateWatchersAndUpdate(); // start the overseer first as following code may need it's processing if (!zkRunOnly) { //▼▼▼▼▼▼20161022 baisui add for solr6和solr5的节点在同一个集群中,solr的节点会抢overseer的角色但是执行不正常所以就把它抢overseer的 // 的功能去掉,这样overseer的角色只会有solr5的节点抢夺到 overseerElector = new LeaderElector(zkClient){ @Override public int joinElection(ElectionContext context, boolean replacement) throws KeeperException, InterruptedException, IOException { return 0; } @Override public int joinElection(ElectionContext context, boolean replacement, boolean joinAtHead) throws KeeperException, InterruptedException, IOException { return 0; } @Override void retryElection(ElectionContext context, boolean joinAtHead) throws KeeperException, InterruptedException, IOException { } }; //▲▲▲▲▲▲ this.overseer = new Overseer(cc.getShardHandlerFactory().getShardHandler(), cc.getUpdateShardHandler(), CommonParams.CORES_HANDLER_PATH, zkStateReader, this, cloudConfig); ElectionContext context = new OverseerElectionContext(zkClient, overseer, getNodeName()); overseerElector.setup(context); overseerElector.joinElection(context, false); } Stat stat = zkClient.exists(ZkStateReader.LIVE_NODES_ZKNODE, null, true); if (stat != null && stat.getNumChildren() > 0) { publishAndWaitForDownStates(); } // Do this last to signal we're up. createEphemeralLiveNode(); } catch (IOException e) { log.error("", e); throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Can't create ZooKeeperController", e); } catch (InterruptedException e) { // Restore the interrupted status Thread.currentThread().interrupt(); log.error("", e); throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "", e); } catch (KeeperException e) { log.error("", e); throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "", e); } }
如上只需要重载LeaderElector的三个方法,joinElection(),retryElection()在方法体中什么事儿都不干就能让Solr节点竞选集群监工的流程去掉了。
总结
至此,Solr5和Solr6 可以在一个Zookeeper域中共存,正常执行了。当然,最简单的办法是,另外启一个zk集群,把solr6的索引完全放到一个独立的集群中去,但是这样无形中增加了集群维护成本,得不偿失。
相关推荐
Solr 7.4 集群安装是一个关键的IT任务,涉及到分布式搜索和数据分析的基础设施建设。Apache Solr是一款开源的企业级搜索平台,能够处理大量数据并提供快速、高效的全文检索服务。在Solr 7.4版本中,它引入了多项改进...
Solr 集群是指将多个 Solr 节点组合成一个集群,以提高查询速度和高可用性。本文档将指导您如何在 Linux 系统中搭建 Solr 集群。 一、环境准备 1. 解压缩相关软件包,包括 Tomcat8、JDK8、Solr7.2 和 ZooKeeper...
Solr集群搭建是一个复杂但重要的过程,用于实现大型、高可用性和可扩展性的搜索解决方案。Apache Solr是一款基于Lucene的开源全文搜索引擎,它提供了分布式搜索、近实时处理、多字段排序等功能。以下是对Solr集群...
5. **启动Solr和Zookeeper**: 启动所有节点的Tomcat和Zookeeper服务。 6. **创建并分发索引**: 在Zookeeper中创建新的索引集合,Solr会自动将它们分片和复制到各个节点。 五、Solr 4.9集群的管理和监控 1. **Solr ...
为了实现高可用性和负载均衡,通常会将Solr部署在分布式环境中,这就需要用到Zookeeper进行集群协调。而Tomcat作为Java应用服务器,常被用来运行Solr服务器。本文将详细介绍如何搭建Solr-Zookeeper-Tomcat集群。 一...
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
本文详细介绍了Solr的基础知识、单机安装配置流程、数据导入与同步方法,以及简要概述了Solr在Windows和Linux环境下的集群部署策略。通过本文的学习,读者能够掌握Solr的基本使用方法,并能在实际工作中应用这些技术...
在Solr 5.x和6.x版本中,中文分词器扮演着至关重要的角色,它负责将中文文本拆分成有意义的词汇,便于索引和查询。下面将详细介绍Solr中的中文分词器及其相关知识。 一、Solr中文分词器概述 在处理中文文档时,由于...
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
在企业级应用中,通常需要部署Solr集群来实现高可用性和数据分布,以处理大量的索引和查询请求。以下是详细的Solr集群安装部署步骤。 ### 1. 单节点安装部署 对于初学者来说,首先需要了解单节点安装,这是搭建...
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
总的来说,Solr集群结合IK分词器和Zookeeper,为企业级的全文搜索应用提供了高效、可扩展的解决方案。通过深入理解这些组件的工作原理和配置方法,开发者可以构建出强大的搜索系统,满足各种复杂的业务需求。
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
【课程大纲】第01讲 solr5简介第02讲 solr5之Schema第03讲 solr5之Solrconfig第04讲 solr5单机安装与配置第05讲 solrj基础(一)第06讲 solrj基础(二)第07讲 solrj之SolrBean第08讲 solrj语法详解第09讲 Solrj之...
整个过程分为几个阶段:准备软件环境、部署单机版Tomcat 7 + Solr 5.2.1、配置多Tomcat实例以支持Solr集群以及最后配置ZooKeeper集群来确保Solr集群的稳定性和高可用性。 **软件需求:** - **Tomcat 7:** 版本...
通过上述分析可以看出,SolrCloud 结合 Zookeeper 不仅解决了大规模索引和检索的问题,还提供了集中式配置管理、服务发现、分布式锁及集群管理等一系列高级特性,极大提升了分布式系统的稳定性和可扩展性。...
Solr集群是Apache Solr的一种分布式部署方式,它允许用户在多台服务器上分布数据,以提高搜索性能和可用性。在本场景中,我们主要关注如何在Linux环境下搭建一个基于Zookeeper的SolrCloud集群。 首先,我们需要准备...