solr replication原理探究

2019-03-27 00:22|来源: 网路

    无论是垂直搜索,还是通用搜索引擎,对外提供搜索服务其压力都比较大,经常有垂直电商在做活动的时候服务器宕机。对面访问压力比较大的情况,一般的应对方法就是【集群】+【负载均衡】。Solr提供了两种解决方案来对应访问压力。其一是Replication,其一是SolrCloud


Replication采用了master/slave  模式,用读写分离的思想来提高对外服务能力。但本质上还是单兵作战。Master/slave模式在数据库领域应用广泛,像MySQLRedis等主流的数据库都实现这一功能。Replication的另一个功能就是数据备份。


SolrCloud采用Zookeeper作为配置中心,对索引数据进行分片(shard),实现了真正的分布式搜索。像Hadoop,HBase,Storm等分布式系统都是建立在Zookeeper基础之上的。


 

个人认为二者没有谁优谁劣,应用场景不同而已。


 

本文主要探究Replication的实现原理。


1. Replication的配置


Replicationsolrconfig.xml中默认是关闭的,要打开很简单。对于Replication,首先需要确定Solr服务的角色。Solr服务的角色有三种[master],[slave],[repeater]。这三种角色的配置如下:


Master配置:


wKioL1ORrUSjuF5WAAHACrfhpPg906.jpg

Slave配置:


wKiom1ORrYjBm0H2AAHm6b1jVEM579.jpg 

Repeater配置:


wKioL1ORrWvCaLsxAAHS6MjYxf0489.jpg 

 

Repeater就是一个solr服务器既是master,又是slave。为什么需要Repeater角色呢?我们试想,如果一个master服务器同时带上10slave甚至100slave,会出现什么情况?Master很容易就被累死了。就算不累死,网络带宽也会很容易被占用干净。假如我们需要4台的集群,但是每个master又只能带2slave,通过repeater就很容易实现。


 

wKioL1ORrXuz9HybAADx_Qm5pYw487.jpg

2. replication的工作原理


通过配置我们知道replication的功能是通过ReplicationHandler来实现的。通过以ReplicationHandler为切入口,应该能很容易地追溯到replication的运行过程。


2.1 slave端的运行过程


Solr在启动的过程中会通过ReplicationHandler.inform()方法,按照slave的配置启动一个定时任务,定时向master端发起同步请求。任务的代码如下:


private void startExecutorService() {
    Runnable task = new Runnable() {
      @Override
      public void run() {
        if (pollDisabled.get()) {
          LOG.info("Poll disabled");
          return;
        }
        try {
          executorStartTime = System.currentTimeMillis();
          replicationHandler.doFetch(null, false);
        } catch (Exception e) {
          LOG.error("Exception in fetching index", e);
        }
      }
    };
    executorService = Executors.newSingleThreadScheduledExecutor(
        new DefaultSolrThreadFactory("snapPuller"));
    long initialDelay = pollInterval - (System.currentTimeMillis() % pollInterval);
    executorService.scheduleAtFixedRate(task, initialDelay, pollInterval, TimeUnit.MILLISECONDS);
    LOG.info("Poll Scheduled at an interval of " + pollInterval + "ms");
  }



   定时任务的时间间隔是


wKiom1ORrePTa48kAABxYCuklTw119.jpg

 

slave端对master而言是透明的。换句话说,masterslave之间的通信是无状态的http连接。Slave端通过发送不同的commandServer端取得数据,即在数据同步的过程中,slave端是占主导作用的。这也是为什么最好先从slave端入手。


一次replicate操作关键步骤如下:


wKioL1ORrcvBE2_gAAHtodF_OIs371.jpg

 

当然还会有细节的处理,比如系统缓存同步、数据校验,日志记录等等……处理全过程都是以SnapPuller.fetchLatestIndex()方法为主线进行的,如果跟踪源码,则重点关注该方法。

 

 

2.2 master端的运行过程


由于master端是被动的(master接收slave端传递过来的命令,然后依照命令执行),所以master端的工作过程相对比较简单。值得注意的是,通过master端可以更好的理解solr索引更新的过程。


1.CMD_INDEX_VERSION 命令


通过该命令可以得到索引的latestVersionlatestGeneration。其中lastestVersion其实就是索引的更新时间点,而latestGeneration就是存储在SegmentInfos中的generation信息。通过这两个信息的对比,就可以判断出slave端的索引是否需要更新。


2. CMD_GET_FILE_LIST命令


通过该命令可以得到需要同步的索引文件信息。


3. CMD_GET_FILE 命令


通过该命令可以下载文件。该命令执行次数由文件大小和CMD_GET_FILE_LIST得到的文件数量决定。下载文件每次最多下载1M,如果文件大于1M,则分多次下载。数据正确性的校验由Adler32 算法来完成。关于Adler32算法,这里不细说。关于详细代码,可以参看DirectoryFileStream.write()方法。


综上,一次replication操作在master端的运行过程就是执行这三种命令的过程。




本文出自 “每天进步一点点” 博客,请务必保留此出处http://sbp810050504.blog.51cto.com/2799422/1423199


转自:http://sbp810050504.blog.51cto.com/2799422/1423199

相关问答

更多
  • 我们生活中的数据总体分为两种:结构化数据和非结构化数据。 结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。 非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等。
  • 虽然我在这里遇到了一个老问题,但我迟到了一点。 答案是Solr Cloud在内部处理复制。 Solr Cloud wiki页面详细解释了这一点。 如果你设置了numShards = 2并添加更多的服务器(这样你总共有四个),分片将被复制到新的服务器 - 确保你的分片位于多个节点上。 直接回答你的问题; SolrCloud为你做了复制设置和逻辑,你应该让它做它自己的事情,而不是在混合中引入“手动”设置复制。 SolrCloud的重点在于隐藏复制和共享逻辑,允许您在可用时简单添加更多服务器。 当然,您可以创建逻 ...
  • 我希望你想要双向复制的主要原因是支持跨数据中心的情况。 也就是说,您希望将查询隔离到特定位置,但要在高延迟链接中保持同步。 如果您不需要这个,只需使用SolrCloud并让它处理复制。 您可以对索引进行分片并获得所需的更新吞吐量。 任何更新都可以转到任何节点,Solr会确保将其写入正确的位置。 如果您真的在考虑数据中心,Solr在6.0中添加了一些全新的数据中心支持,您可以在这里阅读: https : //sematext.com/blog/2016/04/20/solr-6-datacenter-repl ...
  • 如果您希望控制复制发生的时间,我建议禁用轮询并使用外部调度程序复制REST API。 我们也使用它来对master进行一些验证,然后让slave复制,这会影响最终用户。 If you are looking to control the time at which replication should happen, I would suggest to disable polling and make use of replication REST API with an external schedul ...
  • 所以我的第一个答案是我的第一个问题;) 最初设置此核心时,使用了像这样的导入查询。 SELECT * FROM [TABLE] 然后在data-import-handler中将字段映射为这样。 当Solr开始将SQL中[ENDTIME](datetime2)列的内容转换为日期时,会将其添加到导入查询中。 CAST(CAST(ENDTIME as datetime2(0)) as varchar(100)) as ENDT ...
  • 为了扩展问题的本质,PingRequestHandler将始终返回成功,除非.... 它的查询导致抛出异常。 它配置为使用运行状况检查文件,但找不到该文件。 因此,我的建议是您配置PingRequestHandler处理程序以使用运行状况检查文件。 然后,您可以在Solr系统上使用cron作业,其作业是检查文档是否存在,并相应地创建(或删除)运行状况检查文件。 如果不存在运行状况检查文件,则PingRequestHandler将抛出一个足够用于ELB的HTTP 503。 我使用的粗略算法...... 每分钟 ...
  • 正确的地方是更新请求处理器 ,您确保将sorlconfig.xml中的内容插入到您正在使用的所有udpate处理程序(包括DIH)中,并且单个URP将涵盖所有更新。 在URP中的java代码中,您可以轻松获取字段的值,然后将其添加到另一个字段中的所有其他字段等。这在doc编制索引之前发生。 the right place is an Update Request Processor, you make sure you plug that in sorlconfig.xml into all udpate ...
  • 最新的Solr作为独立黑匣子运行。 不要看Tomcat信息的古老教程,它们不再有用。 这是通过.NET客户端连接到它的一个单独问题。 对于客户端部分,SolrNet的源代码版本更新。 它应该与最新的Solr一起工作,主要问题是Solr的URL现在必须包含集合名称,所以http:// localhost:8983 / solr / collectionname 。 检查参数以设置核心或集合或类似。 还有Solr Express,你可能想看看。 Latest Solr runs as standalone bl ...
  • 您应该能够在论坛中找到Solr Master Slave Heirarchy Vs SolrCloud的比较,但这些是我对他们的理解/体验,所以要轻易消耗它。 该怎么做以及为什么? 这完全取决于您的业务需求。 我想说如果你的应用程序只是从SOLR中读取数据并且在从SOLR读取数据时需要高可用性,那么简单的一个主机到多个从机层次结构就足够了。 但是,如果您正在寻找SOLR写入的高可用性,那么SolrCloud是一个正确的选择 SolrCloud是更好的解决方案吗? 没有什么比这更好了,维护SolrCloud需 ...
  • 我正在将升级从4.7升级到5.3。 它实际上比你所做的要容易得多。 这是最简单的方法: 1.在同一个盒子上并行安装。 创建集合等... 2.将模式和solrconfig合并。 将新的和旧的并排打开,并将旧的和旧的一起复制到新的中。 有一些差异; 所以这很重要。 确保这个工作。 3.关闭Solr 4,将索引复制到新的Solr中。 4.索引应该没有问题。 但确保这个工作。 5.在新实例上执行特定于环境的任务,例如设置复制等。 Volia! 我在Solr面前有nginx,所以一旦升级完成,我就可以将nginx重定 ...