solrconfig.xml
文件位於SolrCore的conf目錄下, 通過solrconfig.xml
可以配置SolrCore實例的相關信息, 可不作修改.
這里以4.10.4版本為例, 文件位置:example/solr/collection1/conf/solrconfig.xml
;
1 luceneMatchVersion - 指定Lucene版本
<luceneMatchVersion>4.10.4</luceneMatchVersion>
表示Solr底層使用的Lucene的版本, 官方推薦使用新版本的Lucene.
使用注意事項: 如果更改了這個設置, 必須對所有已經創建的索引數據重新索引(re-index), 否則可能出現無法查詢的情況.
2 lib - 配置擴展jar包
solrconfig.xml
中可以加載一些擴展的jar包, 擴展步驟如下:
(1) 把要擴展的jar包復制到指定目錄;
這里將其復制到SolrHome同級目錄, 防止項目移動時遺忘了這些jar包, 導致項目出錯;
如果有多個SolrHome, 建議把這些jar包放置在SolrHome的上級目錄, 這樣就不必在每個SolrHome中添加這些jar包, 從而下述路徑也就無需修改了;
(2) 復制solr解壓文件中的contrib和dist目錄到work目錄下(與SolrHome同級, 為了后期搭建集群時共用這些jar包, 而不用每次都添加);
(3) 修改solrconfig.xml
文件, 加載擴展的jar包:
solr.install.dir
表示${SolrCore}的目錄位置, 這里是collection1內的路徑;

./
表示當前目錄; ../
表示上一級目錄.
這里要將jar包放置在${SolrCore}
上一級目錄的lib
目錄下, 需要把 ../../..
修改為 ../..
:

3 dataDir - 索引數據路徑
配置SolrCore的data目錄.
data目錄用來存放當前SolrCore的index索引文件和tlog事務日志文件.
solr.data.dir
表示${SolrCore}/data
的目錄位置.

建議不作修改, 否則配置多個SolrCore時容易出錯.
4 directoryFactory - 索引存儲工廠
<directoryFactory name="DirectoryFactory"
class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}">
<!-- These will be used if you are using the solr.HdfsDirectoryFactory,
otherwise they will be ignored. If you don't plan on using hdfs,
you can safely remove this section. -->
<!-- The root directory that collection data should be written to. -->
<str name="solr.hdfs.home">${solr.hdfs.home:}</str>
<!-- The hadoop configuration files to use for the hdfs client. -->
<str name="solr.hdfs.confdir">${solr.hdfs.confdir:}</str>
<!-- Enable/Disable the hdfs cache. -->
<str name="solr.hdfs.blockcache.enabled">${solr.hdfs.blockcache.enabled:true}</str>
<!-- Enable/Disable using one global cache for all SolrCores.
The settings used will be from the first HdfsDirectoryFactory created. -->
<str name="solr.hdfs.blockcache.global">${solr.hdfs.blockcache.global:true}</str>
</directoryFactory>
有以下存儲方案:
(1) solr.StandardDirectoryFactory
: 這是基於文件系統存儲目錄的工, 它會基於當前的操作系統和JVM版本選擇最好的實現.
(2) solr.NRTCachingDirectoryFactory
- 默認方案: 此工廠的設計目的是在內存中存儲部分索引, 從而加快近實時搜索(Near-Real-Time)的速度.
(3) solr.MMapDirectoryFactory
: 這是Solr 3.1 - 4.0版本在Linux64位系統下的默認實現, 它通過使用虛擬內存和內核特性調用
mmap去訪問存儲在磁盤中的索引文件, 允許Lucene或Solr直接訪問I/O緩存. 如果不需要近實時搜索功能, 使用此工廠是個不錯的方案.
(4) solr.NIOFSDirectoryFactory
: 適用於多線程, 但據報道, Solr 4.x之前的版本不適用在Windows系統上(慢), 因為JVM還存在bug.
(5) solr.SimpleFSDirectoryFactory
: 適用於小型應用程序, 不支持大數據和多線程.
(6) solr.RAMDirectoryFactory
: 這是內存存儲方案, 不能持久化存儲, 在系統重啟或服務器crash時數據會丟失. 而且不支持索引復制(不能使用副本).
5 codecFactory - 編解碼方式
<codecFactory class="solr.SchemaCodecFactory"/>
<schemaFactory class="ClassicIndexSchemaFactory"/>
Solr中, 編解碼可以使用自定義的編解碼器, 比如: 想啟動per-field DocValues
格式, 可以在solrconfig.xml
文件中設置SchemaCodecFactory
的內容:
docValuesFormat="Lucene42"
: 默認設置, 所有數據會被加載到堆內存中;
docValuesFormat="Disk"
: 這是另一個實現, 將部分數據存儲在磁盤上;
docValuesFormat="SimpleText"
: 文本格式, 非常慢, 僅僅用於學習測試.
6 indexConfig - 索引配置
indexConfig
標簽用於設置索引的屬性.
(1) maxFieldLength
: 對文檔建立索引時, 文檔字段的最大長度, 超過這個長度的值將被截斷. 如果文檔很大, 就需要增加這個數值.
這個值設置得過高會導致內存不足異常;
該配置在Solr 4.0版本開始已經移除了, 類似的設置需要在fieldType中定義, 如:
<!-- 限制token最大長度 -->
<filter class="solr.LimitTokenCountFilterFactory" maxTokenCount="10000"/>
(2) writeLockTimeout
: IndexWriter等待寫鎖的最長時間(毫秒).
默認是1000毫秒:
<writeLockTimeout>1000</writeLockTimeout>
(3) maxIndexingThreads
: 生成索引時一個IndexWriter可以使用的最大線程數.
<maxIndexingThreads>8</maxIndexingThreads>
默認是8, 當很多個線程到達時, 多出的線程就只能等待運行中的線程結束, 以空出資源.
(4) useCompoundFile
: 開啟整合文件.
<useCompoundFile>false</useCompoundFile>
開啟此選項, Lucene會將多個內部文件整合為若干個大文件, 來減少使用Lucene內部文件的數量. 即使用更少的用於索引的文件, 這有助於減少Solr用到的文件句柄的數目, 代價是降低了性能 ---- 用於索引的文件數變少了.
除非應用程序用完了文件句柄, 否則使用默認值false就可以.
Lucene中默認是true, Solr 3.6開始默認為false.
(5) ramBufferSizeMB
: Lucene創建或刪除index后, 合並內存中的文檔數據、創建新的segment、將內存中的數據刷新到磁盤之前可用的RAM大小.
<ramBufferSizeMB>100</ramBufferSizeMB>
默認是100MB, 較大的值可以提高創建索引的時間, 但會犧牲更多內存.
(6) maxBufferedDocs
: 在將內存中的索引數據刷新到磁盤之前, 可以使用的buffer大小.
<maxBufferedDocs>1000</maxBufferedDocs>
默認是1000個文檔, 較大的值可以提高創建索引的時間, 但會犧牲更多內存.
說明: ⑤和⑥同時設置時, 優先滿足閾值小的選項.
(7) mergePolicyFactory
: 合並策略.
<mergePolicyFactory class="solr.TieredMergePolicyFactory">
<!-- 一次最多合並的段的個數 -->
<int name="maxMergeAtOnece">10</int>
<int name="segmentsPerTier">10</int>
</mergePolicyFactory>
配置Lucene中segment (段, 索引信息的呈現方式) 的合並策略:
從Solr/Lucene 3.3開始, 使用TieredMergePolicy;
從Lucene 2.3開始, 默認使用LogByteSizeMergePolicy;
更早的版本使用LogDocMergePolicy.
(8) mergeFactor
: 合並因子, 每次合並多少個segment.
<mergeFactor>10</mergeFactor>
默認為10, 此項設置等同於同時設置MaxMergeAtOnce和SegmentsPerTier選項.
越小的值(最小為2)使用的內存越少, 但創建索引的時間也更慢;
值越大, 可以讓索引時間變快, 但會用掉更多的內存 ---- 典型的時間與空間的平衡.
(9) mergeScheduler
: 合並段的調度器, 控制Lucene如何實現段的合並.
<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler"/>
從Lucene 2.3開始默認使用ConcurrentMergeScheduler調度器, 可以可以使用單獨的線程在后台並行執行合並;
Lucene 2.2之前默認使用SerialMergeScheduler調度器, 並不能並行執行合並.
(10) lockType
: 指定Lucene使用哪個LockFactory的實現, 即Lock策略.
<lockType>${solr.lock.type:native}</lockType>
共有3種策略:
single
- SingleInstanceLockFactory, 建議用於只讀索引(read-only)或不存在其他進程會修改索引的場景;
native
- NativeFSLockFactory, 使用操作系統本地文件鎖機制, 當同一個JVM中的多個Solr Web應用試圖共享同一個索引時, 不能使用;
simple
- SimpleFSLockFactory, 普通文件的行鎖定方式.
Solr 3.6 之后默認是native
策略, 之前的版本使用的是simple
策略.
(11) unlockOnStartup
: 啟動Solr服務時釋放鎖.
<unlockOnStartup>false</unlockOnStartup>
某些情況下, 索引可能會由於不正確的關機或其他錯誤而一直處於鎖定狀態, 導致不能添加和更新索引. 將其設置為 true 可以禁用啟動鎖定, 從而允許添加和更新操作.
默認為false.
如果設置為true, 在Solr啟動時將釋放所有的寫鎖或提交鎖 —— 忽略多線程環境中保護索引的鎖定機制, 將導致進程可以繞過 Lucene索引的鎖機制 直接訪問索引, 請慎用.
如果鎖類型為signgle
, 該配置將不起作用.
(12) termIndexInterval
: Lucene將term加載到內存中的頻率.
最佳實踐: 使用默認值128, 大多數情況下都很有用.
<termIndexInterval>128</termIndexInterval>
(13) nrtMode
: 近實時模式.
<nrtMode>true</nrtMode>
默認為true. 設置為true, 將從IndexWriter打開/重新打開IndexReaders, 而不是從文件目錄中打開.
在主/從模式的主機中, 將其設置為false;
在SolrCloud集群中, 將其設置為true.
(14) deletionPolicy
: 刪除策略.
在這里指定自定義的刪除策略. 策略類必須實現org.apache.lucene.index.IndexDeletionPolicy
.
默認配置如下:
<deletionPolicy class="solr.SolrDeletionPolicy">
<!-- 最多能夠保留多少個提交點 -->
<!-- <str name="maxCommitsToKeep">1</str> -->
<!-- 最多能夠保留多少個優化提交點-->
<!-- <str name="maxOptimizedCommitsToKeep">0</str> -->
<!-- 達到指定的時間, 就刪除所有的提交點. 支持DateMathParser語法, 如: -->
<!--
<str name="maxCommitAge">30MINUTES</str>
<str name="maxCommitAge">1DAY</str>
-->
</deletionPolicy>
Solr 默認的實現類支持刪除索引提交點的提交數量, 索引提交點和優化狀態的年齡(即內部掃描的次數). 無論如何, 都應該一直保留最新的提交點.
(15) infoStream
: Lucene的信息流, 控制索引時的日志信息.
<infoStream file="INFOSTREAM.txt">false</infoStream>
為了便於調試, Lucene提供了InfoStream
用於顯示索引時的詳細信息.
默認為false. 這里設置為true, Lucene底層的IndexWriter將會把自己的信息流寫入Solr的日志, 具體日志信息還要通過log4j.properties
文件控制.
(16) checkIntegrityAtMerge
: 合並段時的安全檢查.
<checkIntegrityAtMerge>false</checkIntegrityAtMerge>
設置為true, 將啟用此安全檢查 —— 有助於在合並segment時 降低舊segments中損壞的索引轉移到新段的風險, 代價是合並的速度將變慢.
7 updateHandler - 更新處理器
Solr默認使用的高可用的updateHandler
是:
<updateHandler class="solr.DirectUpdateHandler2">
7.1 updateLog - 索引庫的事務日志
<updateLog>
<!-- dir: 事務日志的存儲目錄 -->
<str name="dir">${solr.ulog.dir:}</str>
</updateLog>
默認路徑: ${SOLR_HOME}/data/tlog.
啟用事務日志用於實時查詢、持久化索引數據、Solr Cloud中副本的恢復...
隨着索引庫的頻繁更新, tlog日志文件會越來越大, 所以建議提交索引時采用硬提交 - 即批量提交的方式 - hard autoCommit
.
7.2 autoCommit - 自動(硬)提交策略
這是默認的自動提交策略.
<autoCommit>
<!-- 多少個文檔提交一次: 要添加的文檔數達到此值時自動觸發新的提交 -->
<!-- <maxDocs>10000</maxDocs> -->
<!-- 多少毫秒提交一次: 添加文檔操作的時間持續到此值時自動觸發新的提交, 與maxDocs配置其一即可 -->
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
<!-- 如果為false, 提交操作會將最近的更改信息刷新到磁盤, 但不會立即打開查詢器 - 也就是說客戶端查詢不到;
實時性要求高的項目, 需要設置為true - 在6.0之后的版本中默認為true -->
<openSearcher>true</openSearcher>
</autoCommit>
(1) autoCommit
是硬提交, 開啟后會進行如下操作:
① 生成一個新的tlog文件, 刪除舊的tlog文件;
② 把內存中緩存的文檔fsync(OS內部的函數)到磁盤中, 並創建一個index descriptor, 用來記錄各個文檔的存儲位置;
==> 此時就算JVM奔潰或系統宕機, 也不影響這部分數據, 不利之處是: 占用資源較多;
③ 如果<openSearcher>true</openSearcher>
, 就會打開查詢器, 讓此次硬提交的文檔可供搜索.
(2) 可選項 - commitWithin - 在指定時間之后強制提交文檔:
在Solr 6.x版本中, 支持如下配置:
這個多用在近實時搜索中, 因此默認情況下執行的是軟提交 —— 修改后的文檔不會被復制到集群中的slave服務器中, 也就存在數據丟失的隱患.
當然可以通過添加參數進行強制硬提交:<commitWithin> <softCommit>false</softCommit> </commitWithin>
使用方法類似於: <add commitWithin=10000>
, Solr會在10s內提交添加的文檔. 其他用法有:
① 在add方法中設置參數, 比如
server.add(doc, 10000);
② 在SolrRequest中設置, 比如:UpdateRequest req = new UpdateRequest(); req.add(doc); req.setCommitWithin(10000); req.process(server);
(3) 最佳實踐建議:
在頻繁添加文檔的應用中, 官方建議使用
commitWithin
, 而不是啟用autoCommit
.
通過代碼操作時, 請不要使用commit API
手動提交, 因為這會觸發硬提交, 出現大量的創建、刪除tlog文件的操作, 影響IO性能.
如果不配置autoCommit
標簽, 就只有在代碼或命令中指定commit
才會更新索引.
如果啟用了updateLog, 官方強烈建議使用某種硬提交策略來限制日志的大小.
—— 最佳的自動提交設置: 需要在性能和可見行之間進行權衡.
// 如果要手動提交, 不要使用無參方法, 推薦指定提交策略: 是否等待刷新(建議不等待, 因為會阻塞)、等待可搜索(建議不等待, 因為會阻塞)、軟提交
// 這是Solr 4.10版本API中的用法.
solrServer.commit(false, false, true);
7.3 autoSoftCommit - 軟提交策略
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
</autoSoftCommit>
(1) autoSoftCommit
是軟提交, 配置后會進行如下操作:
① 把內存中緩存的文檔fsync(OS內部的函數)到磁盤中, 但不會創建index descriptor——也就是說各個文檔的真實存儲位置並沒有被記錄下來;
② 打開文檔查詢器, 涉及到的索引數據可以被查詢到——近實時(NRT)更好;
③ 軟提交不會等待后台合並、整理文檔等操作, 只確保了修改的可見行, 沒有獲取到文檔的具體存儲位置 —— 也就是說如果此時JVM奔潰或系統宕機, 就找不到這些數據了.
(2) 最佳實踐建議:
軟提交比硬提交更快, 更能做到近實時查詢, 但是如果服務器不穩定, 或JVM奔潰, 會導致提交的數據無法被檢索到.
8 query - 查詢相關配置
8.1 最大布爾子句
maxBooleanClauses
: 最大布爾子句: 可以組合在一起形成一個查詢的布爾子句數量的上限, 默認的1024已經足夠.
<maxBooleanClauses>1024</maxBooleanClauses>
如果應用程序大量使用了通配符或范圍查詢, 為了避免拋出TooManyClausesException
異常, 建議增加這個值.
這個選項會修改所有SolrCores的全局Lucene屬性, 如果多個solrconfig.xml文件中的配置不一致, 將以最后初始化的文件為基准.
8.2 查詢緩存
(1) 關於緩存:
Solr使用Searcher類來處理查詢. 這個類將與索引相關的數據加載到內存中, 根據索引、CPU及內存的大小, 加載過程可能耗時比較久.
要改進這一設計和顯著提高性能, Solr引入了一種 "預熱" 策略, 就是把這些新的Searcher聯機以便為用戶提供查詢服務之前, 先對它們 "熱身".
(2) Solr中有2種緩存實現:
a. 基於LinkedHashMap的LRUCache;
b. 基於ConcurrentHashMap的FastLRUCache.區別: FastLRUCache在單線程操作中具有更快的查詢和更慢的添加操作, 因此當緩存的命中率高 ( > 75%) 時通常比LRUCache更快, 並且在多CPU系統的其他場景下可能更快.
(3) 緩存的通用參數:
class: SolrCache的實現類;
size: cache中可保存的最大項;
initialSize: cache的初始化大小, 與java.util.HashMap
中entry的容量相關;
autowarmCount: 預熱項目數, 打開新的搜索器時, 可以使用多少項舊搜索器中的緩存數據來預填充新搜索器的緩存. 條目多意味着緩存的hit會更多, 就需要更長的預熱時間.
(4) 其他說明:
① 對所有緩存模式而言, 設置緩存參數時, 都有必要在內存、CPU和磁盤訪問之間進行均衡. Solr Web管理員界面的Statistics對分析緩存的hit-to-miss比例以及微調緩存大小等統計數據都非常有用.
② 並非所有應用程序都會從緩存受益, 實際上一些應用程序反而會由於 "將某個永遠用不到的條目存儲在緩存中" 這一額外步驟而受到影響.
(1) filterCache
: 過濾器緩存.
<filterCache class="solr.FastLRUCache" size="512"
initialSize="512" autowarmCount="0"/>
是SolrIndexSearcher用於過濾 (filter queries
, 也就是fq
參數) 的緩存: 將得到的文檔的id存儲為無序的集合DocSets;
結果還能用來facet分片查詢 —— 有效提高了Solr的查詢性能.
(2) queryResultCache
: 查詢結果緩存.
<queryResultCache class="solr.LRUCache" size="512"
initialSize="512" autowarmCount="0"/>
緩存查詢結果 —— 基於查詢、排序和請求的有序的文檔范圍, 也就是文檔id列表.
(3) documentCache
: 文檔緩存.
<documentCache class="solr.LRUCache" size="512"
initialSize="512" autowarmCount="0"/>
緩存Lucene的Document對象, 也就是每個文檔的stored fields
- 在schema.xml
文件中配置.
由於Lucene內部文檔ID是瞬態的(會被更改), 因此該緩存不會自熱.
(4) cache
: 塊連接使用的自定義緩存.
<cache name="perSegFilter" class="solr.search.LRUCache"
size="10" initialSize="0" autowarmCount="10"
regenerator="solr.NoOpRegenerator" />
關於塊連接(block join), 待學習...
(5) fieldValueCache
: 字段值緩存.
<fieldValueCache class="solr.FastLRUCache" size="512"
autowarmCount="128" showItems="32" />
該緩存用來按照文檔的id保存能夠快速訪問的字段的值, 就算這里不配置, Solr也會默認創建fieldValueCache.
(6) cache
: 自定義緩存.
<!-- 自定義緩存的示例: -->
<cache name="myUserCache" class="solr.LRUCache"
size="4096" initialSize="1024" autowarmCount="1024"
regenerator="com.mycompany.MyRegenerator"
/>
自定義緩存的目的是實現用戶/應用程序級數據的輕松緩存.
如果需要自熱, 則應將regenerator參數指定為solr.CacheRegenerator
類的實現類.
filterCache
和queryResultCache
實現了solr.CacheRegenerator
, 所以都可以自熱.可以通過
SolrIndexSearcher.getCache()
,cacheLookup()
和cacheInsert()
按名稱訪問Solr的緩存.
8.3 懶加載Field
enableLazyFieldLoading
: 開啟懶加載Field.
<enableLazyFieldLoading>true</enableLazyFieldLoading>
性能優化建議: 如果應用程序只會檢索文檔中的少數幾個Field, 可以把這個屬性設置為true ---- 沒有請求的存儲字段(stored fields)將延遲加載.
懶加載大多發生在應用程序返回部分檢索結果時, 用戶常常會單擊其中的一個來查看存儲在此索引中的原始文檔, 初始往往只需要顯示很短的一段信息.
查詢很大的Document, 尤其是含有很大的text類型的字段時, 應該避免加載整個文檔.
8.4 使用過濾器
useFilterForSortedQuery
: 為存儲字段使用過濾器.
<useFilterForSortedQuery>true</useFilterForSortedQuery>
通過使用過濾器進行搜索的優化, 如果請求的排序條件不包括文檔的得分(score), Solr將檢查filterCache
以查找與查詢匹配的過濾器. 如果找到, 相關的過濾器將作為文檔ID的來源, 然后對其ID進行排序返回.
大多數情況下, 除非 經常使用不同的排序規則 並 重復進行相同的查詢, 否則這個配置沒有多大用處, 可以不用配置.
8.5 query result - 查詢結果
(1) queryResultWindowSize
: 查詢結果窗口大小.
<queryResultWindowSize>20</queryResultWindowSize>
用於queryResultCache
的優化. 發起查詢請求時, 將手機所請求數文檔ID的數量集合.
例如: 搜索特定查詢請求並匹配文檔10-19, 並且queryWindowSize = 50
, Solr將收集並緩存文檔0-49.
可以通過緩存實現該范圍內的任何其他查詢請求.
(2) queryResultMaxDocsCached
: 查詢結果的最大文檔緩存數.
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
設置查詢結果中可以緩存的最大文檔數.
8.6 Searcher的監聽器
負責查詢操作的各類搜索器 (IndexSearcher
) 都可以觸發相關監聽器, 進而采取下一步操作:
① newSearcher - 每當創建新的搜索器時觸發, 並且當前的搜索器正在處理請求(也稱為被注冊了). 它可以用來啟動某些緩存, 以防止某些請求的請求時間過長.
② firstSearcher - 創建第一個搜索器時觸發, 但這時是沒有可用的搜索器來 處理請求 或 加載緩存中的數據的.
(1) QuerySenderListener
:
QuerySenderListener使用名為NamedList的數組, 並對序列中的每個NamedList數組執行一個本地查詢請求.
<listener event="newSearcher" class="solr.QuerySenderListener">
<arr name="queries">
<!--
<lst><str name="q">solr</str><str name="sort">price asc</str></lst>
<lst><str name="q">rocks</str><str name="sort">weight asc</str></lst>
-->
</arr>
</listener>
<!-- 開啟此搜索器, 會導致Solr服務啟動較慢 -->
<listener event="firstSearcher" class="solr.QuerySenderListener">
<arr name="queries">
<lst>
<str name="q">static firstSearcher warming in solrconfig.xml</str>
</lst>
</arr>
</listener>
(2) useColdSearcher
: 使用冷搜索器.
<useColdSearcher>false</useColdSearcher>
如果搜索請求到來, 並且目前還沒有被注冊的搜索器, 就立即注冊仍在加載緩存(自熱)的搜索器並使用它.
默認為false - 所有請求都將阻塞, 直到第一個搜索器完成緩存數據的加載.
(3) maxWarmingSearchers
: 最大的搜索器個數, 默認是2.
<maxWarmingSearchers>2</maxWarmingSearchers>
在后台同時預熱(加載緩存)的搜索器的最大數量, 這些搜索器事先預熱好, 可以隨時使用. 如果申請的搜索器個數超出范圍將會報錯.
對只讀的索引庫, 建議設置為1-2
, 對於可讀寫的索引庫, 根據設備內存和CPU的大小, 可以設置更高的值.
如果頻繁讀寫的索引庫中, 此參數較小, 可能會拋出Error opening new searcher. exceeded limit of maxWarmingSearchers=2, try again later.
的錯誤, 嘗試將其調高即可解決此問題.
9 requestDispatcher - 請求轉發器
9.1 開啟handleSelect處理器
<requestDispatcher handleSelect="false" >
Request Dispatcher用來指示SolrCore里的
SolrDispatchFilter
處理請求的行為.
handleSelect是一個以前版本中遺留下來的屬性, 會影響請求的行為(比如/select?qt=XXX
).如果
/select
沒有注冊, 當handleSelect="true"
時,SolrDispatchFilter
就會把請求轉發給qt參數指定的處理器;除非使用
/select
顯示注冊了處理器, 否則當handleSelect="false"
時,SolrDispatchFilter
會忽略/select
請求, 並導致404錯誤 ---- 使用上更安全.對於新用戶不建議使用
handleSelect="true"
, 但這是默認向后兼容的配置.
9.2 requestParsers - 請求解析器
<requestParsers enableRemoteStreaming="true"
multipartUploadLimitInKB="2048000"
formdataUploadLimitInKB="20480"
addHttpRequestToContext="false"/>
這里配置Solr請求的解析行為, 以及對請求的ContentStreams的限制.
(1)
enableRemoteStreaming
- 是否允許使用stream.file和stream.url參數來指定遠程streams. 這里介紹的Solr4.10 版本中默認開啟了此選項, 授權Solr獲取遠程文件 ---- 不安全, 官方建議我們要自己確保系統具有身份驗證功能.(2)
multipartUploadLimitInKB
- 指定Solr允許一個多文件上傳的請求中文件的最大大小值, 以KB為單位.(3)
formdataUploadLimitInKB
- 指定通過POST請求發送的表單數據(application/x-www-form-urlencoded
)的最大值,以KB為單位(4)
addHttpRequestToContext
- 設置為true, 它將聲明原始的HttpServletRequest對象應該被包括在SolrQueryRequest的上下文集合(context map)中, 這里的SolrQueryRequest
是基於httpRequest
的請求.
這個HttpServletRequest
不會被任何現有的Solr組件使用, 但在開發自定義插件時可能很有用.
9.3 httpCaching - HTTP 緩存
httpCaching
控制HTTP緩存控制頭(HTTP cache control headers), 是W3C HTTP規格定義的HTTP響應的緩存過程, 與Solr內部的緩存完全不同, 請勿混淆.
<httpCaching>
元素的屬性決定了是否允許對一個GET請求進行304響應: 當一個客戶端發起一個GET請求, 如果資源從上一次被獲取后還沒有被修改, 那么它可以在響應頭中指定304響應.
304狀態碼的相關信息可參考: HTTP 304狀態碼的詳細講解
(1) 默認配置:
<httpCaching never304="true" />
never304
: 如果設置為true, 那么即使請求的資源沒有被修改, 客戶端的GET請求也不會得到304響應.將這個屬性設置為true對開發來說是方便的, 因為當通過支持緩存頭的Web瀏覽器或其他用戶修補Solr的響應時, 這里的304響應可能會讓人混淆.
(2) 示例配置:
<httpCaching never304="false" lastModFrom="openTime" etagSeed="Solr">
<cacheControl>max-age=30, public</cacheControl>
</httpCaching>
如果包含<cacheControl>
指令, 將會生成Cache-Control頭信息, 如果值包含max-age=
, 還會生成Expires頭信息 ---- 默認情況下不會生成任何Cache-Control頭信息.
即使設置了never304 ="true"
, 也可以使用<cacheControl>
選項。
如果要讓Solr能夠使用自動生成的HTTP緩存頭進行響應, 並正確響應緩存驗證請求, 就要把never304的值設置為"false" ⇒ Solr將根據索引的屬性生成相關的Last-Modified和ETag頭信息.
還可以指定以下選項來限制響應頭的信息:
(1)
lastModFrom
- 默認值為"openTime"(記錄了最后的更改時間), 這意味着Last-Modified值(以及對If-Modified-Since請求的驗證)將全部與當前Searcher的openTime相關聯.如果希望
lastModFrom
與上次修改物理索引的時間精確同步, 可以將其更改為lastModFrom="dirLastMod"
.(2)
etagSeed="..."
- 是一個可以更改的選項, 即使索引沒有更改, 改變這個值將強制更改ETag頭信息, 從而強制讓用戶重新獲取內容, 比如對配置文件作了重大修改時.
如果使用了never304="true"
, Solr將忽略 lastModifiedFrom
和 etagSeed
的配置.
10 requestHandler - 請求處理器
Solr通過RequestHandler(請求處理器), 提供類似WebService的功能 —— 通過HTTP請求對索引進行訪問.

Solr通過下述步驟選擇Request Handler去處理請求:
(1) 傳入的查詢將根據請求中 qt
參數指定的路徑, 按名稱分派給特定的Request Handler.
(2) 如果請求路徑使用了 /select
, 但卻沒有任何一個Request Handler具有select
這個名稱, 而requestDispatcher
中指定了handleSelect="true"
, 就會根據qt
參數調度Request Handler.
(3) 沒有 /
的請求, 是這樣被執行的: http://host/app/[core/]select?qt=name
, 如果沒有給出qt
參數, 那么將使用配置為 default="true"
的 requestHandler 或者名稱為 "standard"(標准處理器)的處理器處理.
(4) 如果要使用配置為 startup="lazy"
的處理器, 則在第一個使用這個請求處理器的請求到來之前不會初始化它.
10.1 通過 /select 搜索索引
通過 /select
搜索索引:

① defaults
- 默認值:
可以指定查詢參數的默認值, 這些都會被請求中的參數覆蓋, 也就是說請求中的優先.
<requestHandler name="/select" class="solr.SearchHandler">
<!-- 設置默認的參數值, 可以在請求地址中修改這些參數 -->
<lst name="defaults">
<!-- 調試信息返回到客戶端的參數 -->
<str name="echoParams">explicit</str>
<int name="rows">10</int> <!-- 顯示的數量 -->
<str name="df">text</str> <!-- 默認的搜索字段 -->
</lst>
</requestHandler>
② appends
- 追加值:
除了默認值之外, 還可以指定appends
(追加)參數來標識 從查詢參數 (或現有的"defaults"的值) 中獲取參數值, 然后追加到 multi-val
參數列表中.
下面的例子中, 參數 fq=instock:true
將追加到用戶指定的任何查詢的fq
參數上, 這種分區索引機制獨立於所有客戶端的過濾查詢.
<!--
<lst name="appends">
<str name="fq">inStock:true</str>
</lst>
-->
⇒ 在Solr中, 客戶端無法阻止這些追加的值被使用, 所以除非你確定你總是想要它, 否則不要使用這種機制.
③ invariants
- 不變量:
這個參數用來設置不會被客戶端覆蓋的值 ⇒ 在invariants
部分定義的值總會被使用, 而不用考慮用戶或客戶端指定的defaults
或 appends
的值.
下面的例子中, 將修復 facet.field
和 facet.query
參數, 從而限制客戶端可以使用的分面(facet, 類似於一種過濾搜索).
<!--
<lst name="invariants">
<str name="facet.field">cat</str>
<str name="facet.field">manu_exact</str>
<str name="facet.query">price:[* TO 500]</str>
<str name="facet.query">price:[500 TO *]</str>
</lst>
-->
默認情況下, Solr中的 facet
是不會打開的, 但如果客戶端在請求中指定了facet=true
, 那么不管它們指定的 facet.field
或 facet.query
參數是什么, 這里配置的都將是客戶端唯一能得到的facet
的內容.
⇒ 注意:絕對客戶端無法阻止使用這些“不變量”值,因此除非您確定總是需要它,否則不要使用此機制.
④ components
- 組件:
在request handler的最后, 是組件 components
的定義: 定義可以用在一個request Handler的搜索組件的列表, 它們僅在 Request Handler 中注冊.
<!--
<arr name="components">
<str>nameOfCustomComponent1</str>
<str>nameOfCustomComponent2</str>
</arr>
-->
搜索組件元素只能被用於SearchHandler, 如果不需要默認的SearchComponents列表, 可以完全覆蓋該列表, 也可以將組件添加到默認列表中或將其附加到默認列表中.
10.2 通過 /query 搜索索引
Solr中的請求處理器, 默認返回縮進的JSON格式的內容:
<requestHandler name="/query" class="solr.SearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<str name="wt">json</str> <!-- 顯示的格式 -->
<str name="indent">true</str> <!-- 是否縮進 -->
<str name="df">text</str> <!-- 默認的搜索字段 -->
</lst>
</requestHandler>
10.3 通過 /get 獲取索引
RealTimeGetHandler
- 實時獲取處理器, 保證返回的每個文檔的最新存儲字段, 而不需要提交或打開新的Searcher.
Solr當前版本的 RealTimeGetHandler
的實現, 需要開啟 updateLog
功能.
警告:
如果使用SolrCloud, 就不要在
/get
處禁用RealTimeGetHandler
, 否則每次觸發的Leader選舉都將導致選舉涉及到的Shard中的所有Replicas被完全同步.同樣, Replica的恢復也將始終從Leader中獲取完整的索引, 因為如果沒有
RealTimeGetHandler
的情況下, Replicas將無法進行部分同步.
<requestHandler name="/get" class="solr.RealTimeGetHandler">
<lst name="defaults">
<str name="omitHeader">true</str>
<str name="wt">json</str> <!-- 顯示格式 -->
<str name="indent">true</str>
</lst>
</requestHandler>
10.4 通過 /export 導出結果
導出請求處理器用於導出完整排序的結果集, 請不要更改這些默認的配置值.
<requestHandler name="/export" class="solr.SearchHandler">
<lst name="invariants">
<str name="rq">{!xport}</str>
<str name="wt">xsort</str>
<str name="distrib">false</str>
</lst>
<arr name="components">
<str>query</str>
</arr>
</requestHandler>
10.5 通過 /update 修改索引
通過 /update 維護索引, 可以通過使用XML、JSON、CSV或JAVABIN指定的命令對索引進行添加、修改、刪除操作.
<requestHandler name="/update" class="solr.UpdateRequestHandler">
<!--
<lst name="defaults">
<str name="update.chain">dedupe</str>
</lst>
-->
</requestHandler>
注意事項:
從Solr1.1版本開始,
requestHandlers
在請求體中需要包含有效的Content-type(內容類型)頭信息, 例如: curl 中這樣使用:-H 'Content-type:text/xml;charset= UTF-8'
.要覆蓋請求體重Content-type並強制使用特定的Content-type, 就需要在請求參數中指定:
?update.contentType=text/csv
.如果
wt
相應類型參數沒有給出, 處理器將選擇一個響應格式以匹配輸入的內容.
參考資料
版權聲明
作者: 馬瘦風
出處: 博客園 馬瘦風的博客
您的支持是對博主的極大鼓勵, 感謝您的閱讀.
本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 並在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.