Solr數據備份包括如下這些文件:
- solr config文件包括:
- solr.xml, 它位於SOLR_HOME下
- schema.xml, solrconfig.xml,stopwords.txt,synonyms.txt等和你應用相關的配置文件,他們通常位於SOLR_HOME/conf下。
- lucene index文件,它通常位於SOLR_HOME/data下面。該目錄下面存放了真正的數據,我們主要就是討論如何備份這里的數據。
備份方法
備份lucene index數據文件也分成兩種方式:冷備份和熱備份。
所謂冷備份就是指關閉solr,然后將SOLR_HOME/data下面的所有數據拷貝到一個安全的位置。這種方法簡單,可靠,index數據文件不會產生不一致。但是缺點很明顯,就是系統要關閉,如果數據量大的話,整個復制過程會比較長。
幸好,solr提供了一種非常簡便的熱備份方法,也就是利用Solr Replication Handler!Replication Handler的主要作用是在一個load-balancing的solr部署架構中,將index數據復制到各個slave服務器上。但是,即使在沒有任何slave服務器的情況下,Replication Handler也可以用來在主服務器上創建index的副本。
那么讓我們來看看怎么使用這個功能,其實相當簡單,就是通過瀏覽器或curl等工具發送一個request,它的url是’http://master_server:port/solr/replication?command=backup’。這樣備份就創建好了。默認情況下,會創建一個類似“snapshot.20120812201917”這樣的文件夾,這個文件夾里面就包括了lucene index的數據備份。當然,你也可以指定該文件夾的位置,只需在url里面增加位置參數,如:&location=/foo/bar。
以alfresco中的solr為例,為了備份lucene的index,你需要發出如下請求:‘https://localhost:8443/solr/alfresco/replication?command=backup’(這里假設localhost是solr主服務器。url中的alfresco代表了solr core,alfresco系統中的solr使用了2個core,一個是alfresco——保存了當前alfresco中所有有效文檔的index,另一個是archive——保存了所有被刪除文檔的index)。然后,你可以在‘alf_data/solr/workspace/SpacesStore/snapshot.20120902041725’中找到你備份的數據(20120902041725代表時間戳。每次備份都會不同)。
假如以上的Replication Handler url在你系統中顯示“HTTP Status 404”,別着急,那是因為你還沒有配置Replication Handler。你只需要在solrconfig.xml中增加如下的配置:
<requestHandler name=”/replication” >
<lst name=”master”>
<str name=”confFiles”>schema.xml,stopwords.txt</str>
<str name=”backupAfter”>startup</str>
<str name=”backupAfter”>optimize</str>
</lst>
<!–
<lst name=”slave”>
<str name=”masterUrl”>http://localhost:8983/solr/replication</str>
<str name=”pollInterval”>00:00:60</str>
</lst>
–>
</requestHandler>
各參數的具體含義參見:http://wiki.apache.org/solr/SolrReplication 這里就不再熬述。
這里稍作擴展,討論一下solr Replication Handler 中snapshot的原理。為什么我們不能在solr運行過程中直接復制lucene index文件,而必須通過Replication Handler呢?原因是,假如你直接復制,那么在復制過程中,lucene有可能進行了commit的操作,而commit操作會涉及到對segment文件的merge,如此就很容易造成數據的不一致性的問題。那么Replication Handler是怎么處理的呢?其原理就是在於SnapshotDeletionPolicy。SnapshotDeletionPolicy能使用最近一次commit作為參照,把所有對應該次commit的index數據做一個快照,一直保留着直到系統創建完成所有的備份數據。以下代碼就說明了這個原理:
IndexDeletionPolicy policy = new KeepOnlyLastCommitDeletionPolicy(); SnapshotDeletionPolicy snapshotter = new SnapshotDeletionPolicy(policy); IndexWriter writer = new IndexWriter(dir, analyzer, snapshotter, IndexWriter.MaxFieldLength.UNLIMITED); try { IndexCommit commit = snapshotter.snapshot(); Collection fileNames = commit.getFileNames(); /*<iterate over & copy files from fileNames>*/ } finally { snapshotter.release(); }
- 第二行代碼創建一個snapshot,
- 你仍舊可以使用第三行創建的IndexWrite去更新數據,但它不會影響這個已創建的snapshot。
- try block里面就是將snapshot對應的index數據創建出來。
大家有興趣的話可以看一下solr的源碼(org.apache.solr.handler. ReplicationHandler中的private void doSnapShoot(SolrParams params, SolrQueryResponse rsp, SolrQueryRequest req)),原理和上面的代碼差不多。
恢復
恢復操作很簡單,就是把之前備份出來的index數據復制回去。例如,將備份數據復制到SOLR_HOME/data/index下,然后重啟solr就搞定了。
對於alfresco中的solr而言,就是將index備份復制回/alf_data/solr/workspace/SpacesStore/index中。
重建索引
假如你沒有任何備份,而index數據又崩潰了,最后萬不得已,你就只能重建索引了。不過還好,這項工作很簡單,你需要做的就是先把solr停止,然后刪除SOLR_HOME/data下面的index文件夾以及其他文件夾,再重啟solr,根據你應用的情況,solr會自動重建index(例如,alfresco中的solr),或是你手動發起重建index的請求(例如,通過DIH)。