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端的運行過程就是執行這三種命令的過程。

相關文章
相關標籤/搜索