提交與交易日誌
在 Solr 中,文件在「提交」更新 Lucene 索引檔之前無法用於搜尋。您的提交策略將決定文件新增、刪除或變更何時可供搜尋。交易日誌會記錄自上次「硬」提交點以來收到的文件更新。
solrconfig.xml 中的 <updateHandler>
本節中的設定是在 solrconfig.xml
中的 <updateHandler>
元素中設定,可能會影響索引更新的效能。這些設定會影響內部執行更新的方式。
<updateHandler>
元素會採用 class 參數,該參數必須是 solr.DirectUpdateHandler2
。Solr 隨附的 _default
configset 已定義此區段,但下面討論的許多參數值可能需要為您的應用程式自訂。
<config>
<updateHandler class="solr.DirectUpdateHandler2">
...
</updateHandler>
</config>
請注意,<updateHandler>
設定不會影響處理用戶端更新請求的請求處理常式的較高層級設定。
提交
傳送到 Solr 的資料在提交到索引之前是無法搜尋的。原因是,在某些情況下,提交可能會很慢,而且應該與其他可能的提交請求隔離進行,以避免覆寫資料。
硬提交與軟提交
Solr 支援兩種提交類型:硬提交和軟提交。
硬提交 會對索引檔呼叫 fsync
,以確保已將它們刷新到穩定儲存空間。目前的交易日誌會關閉,並開啟新的交易日誌。請參閱下方的交易日誌一節,了解在沒有硬提交的情況下如何復原資料。選擇性地,硬提交也可以讓文件可供搜尋,但在某些使用案例中,這可能不是理想的,因為它比軟提交更昂貴。依預設,提交動作會導致所有 Lucene 索引檔硬提交到穩定儲存空間 (磁碟)。
軟提交 速度更快,因為它只會讓索引變更可見,而不會 fsync
索引檔、啟動新的區段,也不會啟動新的交易日誌。具有 NRT 需求的搜尋集合會希望經常軟提交,以滿足應用程式的可見性需求。軟提交可能比硬提交 (openSearcher=true
)「成本較低」,但並非沒有成本。建議將此設定為應用程式需求允許的合理時間長度。
硬提交表示,如果伺服器當機,Solr 會確切知道您的資料儲存在哪裡;軟提交表示資料已儲存,但位置資訊尚未儲存。權衡之處在於,軟提交可讓您更快地看到資料,因為它不必等待背景合併完成。
明確提交
當用戶端在更新請求中包含 commit=true
參數時,這可確保更新中新增和刪除所影響的所有索引區段,會在完成索引更新後立即寫入磁碟。
如果指定了額外的參數 softCommit=true
,則 Solr 會執行軟提交。這是近乎即時儲存的實作,這項功能可提升文件的可見性,因為您不必等待背景合併和儲存 (如果使用 SolrCloud,則儲存到 ZooKeeper) 完成,就可以繼續進行其他作業。
關於在索引期間使用明確提交請求的詳細資訊,請參閱使用更新處理常式建立索引一節。
若要瞭解近即時操作的更多資訊,請參閱近即時使用案例。
自動提交
為了避免在索引期間傳送明確的提交命令,並提供對提交發生時間的控制,可以在solrconfig.xml
中設定 autoCommit
參數。
這比從索引客戶端傳送明確提交更好,因為它能讓您對提交策略有更多的控制。請注意,solrconfig.xml
中提供了預設值,但這些值很可能未根據您的需求進行調整,若未有效調整,可能會導致效能問題。
這些設定控制著待處理的更新將自動推送到索引的頻率。
maxDocs
-
選填
預設值:無
自上次提交以來發生的更新次數。
maxTime
-
選填
預設值:無
自最早未提交的更新以來經過的毫秒數。當發送大量文件時,此參數比
maxDocs
更佳。 maxSize
-
選填
預設值:無
磁碟上交易日誌 (tlog) 的最大大小,超過此大小會觸發硬提交。當文件的大小未知,且目的是將交易日誌的大小限制在合理範圍時,此設定非常有用。
有效值可以是位元組 (預設值,沒有後綴),千位元組 (若定義為帶有
k
後綴,如25k
),百萬位元組 (m
) 或十億位元組 (g
)。 openSearcher
-
選填
預設值:
true
是否在執行提交時開啟新的搜尋器。如果此值為
false
,則提交會將最近的索引變更刷新到穩定儲存,但不會開啟新的搜尋器來使這些變更可見。
如果達到 maxDocs
、maxTime
或 maxSize
限制中的任何一個,Solr 會自動執行提交操作。首先達到這些閾值的任何一個都會觸發提交。
如果 solrconfig.xml
中缺少 autoCommit
標籤,則只有明確的提交才會更新索引。是否使用 autoCommit 的決定取決於您的應用程式需求。
<autoCommit>
<maxDocs>10000</maxDocs>
<maxTime>30000</maxTime>
<maxSize>512m</maxSize>
<openSearcher>false</openSearcher>
</autoCommit>
您也可以使用 autoSoftCommit
標籤指定「軟」自動提交。
<autoSoftCommit>
<maxTime>5000</maxTime>
</autoSoftCommit>
自動提交最佳實務
確定最佳的 autoCommit
設定是在效能和準確性之間進行權衡。導致頻繁更新的設定將提高搜尋的準確性,因為新的內容將更快地可被搜尋,但由於頻繁更新,效能可能會受到影響。較不頻繁的更新可能會提高效能,但更新在查詢中顯示的時間會較長。
以下是兩種提交方式的 NRT 組態範例,硬提交每 60 秒一次,軟提交每 10 秒一次。請注意,這些不是 Solr 附帶範例中的值!
<autoCommit>
<maxTime>${solr.autoCommit.maxTime:60000}</maxTime>
<openSearcher>false</openSearcher>
</autoCommit>
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:10000}</maxTime>
</autoSoftCommit>
這些參數可以在執行時通過定義 Java「系統變數」來覆寫,例如指定 `-Dsolr.autoCommit.maxTime=15000 將會覆寫硬提交間隔,值為 15 秒。 |
autoCommit
(使用 openSearcher=false
)和 autoSoftCommit
的選擇有不同的後果。在非正常關機的情況下,Solr 可能需要花費 autoCommit
中指定的時間,才能從交易日誌中重播未提交的文件。
為 autoSoftCommit
選擇的時間決定了文件傳送到 Solr 後到可被搜尋的最大時間,並且不會影響交易日誌。
為此值選擇您的應用程式可以容忍的最長時間間隔,通常 15-60 秒是合理的,或者甚至更長,具體取決於需求。在時間設定為非常短的間隔(例如 1 秒)的情況下,請考慮停用您的快取(尤其是 queryResultCache 和 filterCache),因為它們將沒有什麼作用。
對於極大量的大宗索引,特別是如果沒有搜尋的初始載入,請考慮透過為 maxTime 參數指定值 -1 來關閉 autoSoftCommit 。 |
在時間段內提交
autoCommit
的替代方案是使用 commitWithin
,它可以在向 Solr 發出更新請求時(即在推送文件時)或在更新請求處理常式中定義。
commitWithin
設定允許強制文件提交在定義的時間段內發生。這最常用於近即時使用案例,因此預設為執行軟提交。但是,這不會將新文件複製到使用者管理的叢集中的追隨者伺服器。如果這是您實作的要求,您可以使用參數強制執行硬提交,如下例所示
<commitWithin>
<softCommit>false</softCommit>
</commitWithin>
使用此組態,當您呼叫 commitWithin
作為更新訊息的一部分時,它將自動執行硬提交。
交易日誌
交易日誌 (tlog) 是自上次硬提交以來更新的「滾動視窗」。每次發生任何類型的硬提交時,都會關閉目前的交易日誌並開啟新的日誌。軟提交對交易日誌沒有影響。
啟用 tlog 後,添加到索引的文件會在索引呼叫返回到用戶端之前寫入 tlog。在非正常關機的情況下(斷電、JVM 崩潰、kill -9
等),在 Solr 停止時寫入 tlog 但尚未通過硬提交提交的任何文件都會在啟動時重播。因此,資料不會遺失。
當 Solr 正常關機時(使用 bin/solr stop
命令),Solr 將關閉 tlog 檔案和索引段,因此啟動時不需要重播。
一個令人困惑的點是交易日誌中包含多少資料。tlog 不包含所有文件,只包含自上次硬提交以來的那些文件。不再需要的較舊交易日誌檔案會被刪除。
以上隱含著如果禁用硬提交,交易日誌將永遠增長。因此,在索引時啟用硬提交非常重要。 |
交易日誌組態
所有 SolrCloud 叢集以及即時獲取功能都需要交易日誌。它在 solrconfig.xml
的 updateHandler
區段中配置。
交易日誌在 solrconfig.xml
中配置,在如下區段中
<updateLog>
<str name="dir">${solr.ulog.dir:}</str>
</updateLog>
唯一需要的參數是
dir
-
必填
預設值:無
交易日誌的位置。在 Solr 的預設
solrconfig.xml
檔案中,這定義為${solr.ulog.dir:}
。如預設值所示,交易日誌的位置可以位於任何位置,只要它在
solrconfig.xml
中定義,並且 Solr 可寫入和讀取。
還有三個額外的專家級組態設定,它們會影響索引效能以及副本在必須進入完全復原之前在更新上可以落後多少。這些設定主要會影響 SolrCloud 叢集組態
numRecordsToKeep
-
選填
預設值:
100
在所有交易日誌檔案中保留的最小更新記錄數。
maxNumLogsToKeep
-
選填
預設值:
10
要保留的最大交易日誌檔案數。
numVersionBuckets
-
選填
預設值:
65336
用於追蹤最大版本值(在檢查重新排序的更新時)的儲存區數量。增加此值以降低在高容量索引期間同步存取版本儲存區的成本。這每個 Solr 核心需要
(8 位元組 (long) * numVersionBuckets)
的堆積空間。 syncLevel
-
選填
預設值:
FLUSH
交易日誌檔案的同步層級。可以是 NONE、FLUSH 或 FSYNC,如果未設定任何值,則預設為 FLUSH。
這些組態選項以以下方式工作
-
FSYNC:Solr 內部緩衝區會明確刷新到下層特定於檔案系統的緩衝區,該緩衝區也會刷新到交易日誌檔案。這是一個成本較高的操作,但更安全,因為內容會寫入交易日誌檔案。
-
FLUSH:我們只會明確將 Solr 內部緩衝區刷新到下層特定於檔案系統的緩衝區,但此緩衝區不會明確刷新到交易日誌檔案。這成本較低,但也較不安全,因為如果我們在檔案系統特定緩衝區也刷新之前發生崩潰,則會遺失其中的資料。
-
NONE:沒有明確的緩衝區刷新。此組態選項成本最低,但安全性也最低。
一個範例,要包含在 solrconfig.xml
的 <updateHandler>
下,採用上述進階設定
<updateLog>
<str name="dir">${solr.ulog.dir:}</str>
<int name="numRecordsToKeep">500</int>
<int name="maxNumLogsToKeep">20</int>
<int name="numVersionBuckets">65536</int>
<str name="syncLevel">FSYNC</str>
</updateLog>
事件監聽器
UpdateHandler 區段也是可以配置與更新相關的事件監聽器的地方。這些事件可以觸發在任何提交之後 (event="postCommit"
) 或僅在最佳化命令之後 (event="postOptimize"
) 發生。
用戶可以在 Solr 外掛程式中編寫自訂更新事件監聽器類別。從 Solr 7.1 開始,出於安全原因,移除了 RunExecutableListener
。
其他 <updateHandler> 選項
在某些情況下,複雜的更新(例如空間/形狀)可能需要很長時間才能完成。在預設組態中,屬於同一個內部版本儲存區的其他更新將無限期地等待。最終,這些未完成的請求可能會堆積起來,並導致執行緒耗盡,甚至可能導致記憶體不足錯誤。
參數 versionBucketLockTimeoutMs
通過為長時間執行的更新請求指定逾時來幫助防止這種情況。如果達到此限制,則更新將會失敗,但不會永遠阻止所有其他更新。
這個設定會產生記憶體成本。大於預設值 0
(無限制逾時) 的值會導致 Solr 使用版本儲存桶的不同內部實作,這會使每個 Solr 核心的記憶體消耗從約 1.5MB 增加到約 6.8MB。
以下是在 solrconfig.xml
的 <config>
區段下指定此選項的範例:
<updateHandler class="solr.DirectUpdateHandler2">
...
<int name="versionBucketLockTimeoutMs">10000</int>
</updateHandler>