在Solr中有兩種方式索引數據:硬提交和軟提交。html
軟提交是在Solr4.0開始,增長的一個新功能。java
那麼爲何須要軟提交呢?咱們先在這裏簡單介紹一下,後續有詳細介紹軟提交和硬提交的區別。SolrJ方法apache
沒有軟提交以前咱們提交索引是這麼實現的:緩存
client = new HttpSolrClient("http://localhost:8080/solr/"); //簡寫
SolrinputDocurnent doc= new SolrinputDocurnent() ;
doc.addF工eld(fieldName , fieldValue) ;
client .add(doc) ;
client.commit();
複製代碼
經過上述代碼咱們能夠看到,咱們每次添加一下索引,都要commit()一下,這個操做極其耗費資源,平均耗時600毫秒。服務器
因此咱們改用另外一種方式來進行提交——軟提交。ide
硬提交是關於持久化的,軟提交是關於可見性的。函數
硬提交是將數據持久化到磁盤裏面,而且可以查詢到這條數據。post
硬提交能夠經過客戶端顯式調用實現,也能夠經過在solrconfig.xml配置文件中添加相關配置實現。性能
爲了達到靈活提交目的,Solr爲硬提交和軟提交設計了自動提交策略,自動提交主要靠maxDocs和maxTime兩個參數控制,maxTime參數表示每間隔多少毫秒就觸發一次索引提交,maxDocs表示當隊列中累計了多少個索引文檔就觸發一次索引提交。兩個條件只要知足其中之一便可。優化
硬提交使用事務日誌來獲取最新的Document ID,同時對索引文件調用fsync方法確保索引數據寫入到磁盤,而且保證即使在斷電的極端狀況下也不會形成數據丟失。
硬提交它會要求全部的段文件必須當即合併爲一個段文件,並重寫整個索引,這個操做執行開銷很大,不能執行太頻繁。段文件合併應該合理配置合併策略,並按期執行索引優化,提高查詢性能。
<!-- 自動(硬)提交策略 -->
<!-- autoCommit是硬提交, 開啓後會進行以下操做: -->
<!-- 生成一個新的tlog文件, 刪除舊的tlog文件; -->
<!-- 把內存中緩存的文檔fsync(OS內部的函數)到磁盤中, 並建立一個index descriptor, 用來記錄各個文檔的存儲位置;此時就算JVM奔潰或系統宕機, 也不影響這部分數據, 不利之處是: 佔用資源較多; -->
<!-- 若是<openSearcher>true</openSearcher>, 就會打開查詢器, 讓這次硬提交的文檔可供搜索. -->
<autoCommit>
<!-- 多少個文檔提交一次: 要添加的文檔數達到此值時自動觸發新的提交 -->
<maxDocs>${solr.autoCommit.maxDocs:1000}</maxDocs>
<!-- 多少毫秒提交一次: 添加文檔操做的時間持續到此值時自動觸發新的提交, 與maxDocs配置其一便可 -->
<maxTime>${solr.autoCommit.maxTime:1000}</maxTime>
<!-- 若是爲false, 提交操做會將最近的更改信息刷新到磁盤, 但不會當即打開查詢器 - 也就是說客戶端查詢不到; 實時性要求高的項目, 須要設置爲true - 在6.0以後的版本中默認爲true -->
<openSearcher>true</openSearcher>
</autoCommit>
複製代碼
軟提交併無將數據持久化到硬盤上,只是將更新的索引數據對查詢請求可見。
<!-- 軟提交策略,配置後會進行以下操做 -->
<!-- 把內存中緩存的文檔fsync(OS內部的函數)到磁盤中, 但不會建立index descriptor——也就是說各個文檔的真實存儲位置並無被記錄下來; -->
<!-- 打開文檔查詢器, 涉及到的索引數據能夠被查詢到——近實時(NRT)更好; -->
<!-- 軟提交不會等待後臺合併、整理文檔等操做, 只確保了修改的可見行, 沒有獲取到文檔的具體存儲位置 —— 也就是說若是此時JVM奔潰或系統宕機, 就找不到這些數據了. -->
<!-- 軟提交比硬提交更快, 更能作到近實時查詢, 可是若是服務器不穩定, 或JVM奔潰, 會致使提交的數據沒法被檢索到. -->
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
</autoSoftCommit>
複製代碼
Transaction Log:事務日誌,記錄了原始文檔,用於索引恢復功能。 此處未完待續………………
<!-- The default high-performance update handler -->
<!-- 更新處理器 -->
<!-- Solr默認使用的高可用的updateHandler是下面這個: -->
<updateHandler class="solr.DirectUpdateHandler2">
<!-- 索引庫的事務日誌 -->
<!-- 默認路徑: ${SOLR_HOME}/data/tlog. -->
<!-- 啓用事務日誌用於實時查詢、持久化索引數據、Solr Cloud中副本的恢復... -->
<!-- 隨着索引庫的頻繁更新, tlog日誌文件會愈來愈大, 因此建議提交索引時採用硬提交 - 即批量提交的方式 - hard autoCommit. -->
<updateLog>
<!-- dir: 事務日誌的存儲目錄 -->
<str name="dir">${solr.data.dir:}</str>
</updateLog>
<maxPendingDeletes>100000</maxPendingDeletes>
<autoCommit>
<maxDocs>${solr.autoCommit.maxDocs:1000}</maxDocs>
<maxTime>${solr.autoCommit.maxTime:1000}</maxTime>
<openSearcher>true</openSearcher>
</autoCommit>
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
</autoSoftCommit>
</updateHandler>
複製代碼
在Lucene中,索引提交分兩個階段提交,prepareCommit操做屬於第一個階段。第一個階段會作一些準備工做,好比將隊列中待添加和標記爲待刪除的索引文檔刷新到索引文件中,而後同步索引文件、建立並寫入段文件,當第一階段執行完以後,須要顯式調用commit結束提交操做,或者調用rollback去回滾提交操做。若是直接調用commit。那麼內部會隱式的先調用prepareCommit。