solr replication原理探究

原文出自:http://sbp810050504.blog.51cto.com/2799422/1423199java

不管是垂直搜索,仍是通用搜索引擎,对外提供搜索服务其压力都比较大,常常有垂直电商在作活动的时候服务器宕机。对面访问压力比较大的状况,通常的应对方法就是【集群】+【负载均衡】。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配置:ide


wKiom1ORrYjBm0H2AAHm6b1jVEM579.jpg 

Repeater配置:oop


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端发起同步请求。任务的代码以下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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端的运行过程就是执行这三种命令的过程。

相关文章
相关标签/搜索