http://m.blog.csdn.net/blog/qing419925094/34444897 算法
Replication的實現原理。緩存
1. Replication的配置服務器
Replication在solrconfig.xml中默認是關閉的,要打開很簡單。對於Replication,首先須要肯定Solr服務的角色。Solr服務的角色有三種[master],[slave],[repeater]。這三種角色的配置以下:網絡
Master配置:ide
wKioL1ORrUSjuF5WAAHACrfhpPg906.jpgfetch
Slave配置:.net
wKiom1ORrYjBm0H2AAHm6b1jVEM579.jpg 日誌
Repeater配置:orm
wKioL1ORrWvCaLsxAAHS6MjYxf0489.jpg xml
Repeater就是一個solr服務器既是master,又是slave。爲何須要Repeater角色呢?咱們試想,若是一個master服務器同時帶上10個slave甚至100個slave,會出現什麼狀況?Master很容易就被累死了。就算不累死,網絡帶寬也會很容易被佔用乾淨。假如咱們須要4臺的集羣,可是每一個master又只能帶2臺slave,經過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而言是透明的。換句話說,master與slave之間的通訊是無狀態的http鏈接。Slave端經過發送不一樣的command從Server端取得數據,即在數據同步的過程當中,slave端是佔主導做用的。這也是爲何最好先從slave端入手。
一次replicate操做關鍵步驟以下:
固然還會有細節的處理,好比系統緩存同步、數據校驗,日誌記錄等等……處理全過程都是以SnapPuller.fetchLatestIndex()方法爲主線進行的,若是跟蹤源碼,則重點關注該方法。
2.2 master端的運行過程
因爲master端是被動的(即master接收slave端傳遞過來的命令,而後依照命令執行),因此master端的工做過程相對比較簡單。值得注意的是,經過master端能夠更好的理解solr索引更新的過程。
1.CMD_INDEX_VERSION 命令
經過該命令能夠獲得索引的latestVersion和latestGeneration。其中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端的運行過程就是執行這三種命令的過程。