<?xml version="1.0" encoding="UTF-8" ?>
<config>
<luceneMatchVersion>4.10.4</luceneMatchVersion>
<dataDir>${solr.data.dir:}</dataDir>
<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}" />
<codecFactory class="solr.SchemaCodecFactory" />
<schemaFactory class="ClassicIndexSchemaFactory" />
<indexConfig>
<writeLockTimeout>10000</writeLockTimeout>
<ramBufferSizeMB>100</ramBufferSizeMB>
<mergePolicy class="org.apache.lucene.index.TieredMergePolicy">
<int name="maxMergeAtOnce">10</int>
<int name="segmentsPerTier">10</int>
</mergePolicy>
<mergeFactor>10</mergeFactor>
<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler" />
<lockType>${solr.lock.type:native}</lockType>
<unlockOnStartup>false</unlockOnStartup>
<termIndexInterval>128</termIndexInterval>
<reopenReaders>true</reopenReaders>
<deletionPolicy class="solr.SolrDeletionPolicy">
<str name="maxCommitsToKeep">1</str>
<str name="maxOptimizedCommitsToKeep">0</str>
<str name="maxCommitAge">30MINUTES</str><!-- 1DAY -->
</deletionPolicy>
<infoStream>true</infoStream><!-- attr: file="INFOSTREAM.txt" -->
<checkIntegrityAtMerge>false</checkIntegrityAtMerge>
</indexConfig>
<updateHandler class="solr.DirectUpdateHandler2">
<updateLog>
<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>
</updateHandler>
<query>
<maxBooleanClauses>1024</maxBooleanClauses>
<filterCache class="solr.FastLRUCache" size="100000" initialSize="5000" autowarmCount="1024" />
<queryResultCache class="solr.FastLRUCache" size="100000" initialSize="5000" autowarmCount="1024" />
<documentCache class="solr.LRUCache" size="100000" initialSize="8000" autowarmCount="1024" />
<fieldValueCache class="solr.FastLRUCache" size="200" autowarmCount="128" showItems="100" />
<enableLazyFieldLoading>true</enableLazyFieldLoading>
<useFilterForSortedQuery>true</useFilterForSortedQuery>
<queryResultWindowSize>30</queryResultWindowSize>
<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
<useColdSearcher>false</useColdSearcher>
<maxWarmingSearchers>2</maxWarmingSearchers>
</query>
<requestDispatcher handleSelect="false">
<requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="204800" formdataUploadLimitInKB="2048" addHttpRequestToContext="false" />
<httpCaching never304="true" />
</requestDispatcher>
<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these will be overridden by parameters in the request -->
<lst name="defaults">
<str name="echoParams">explicit</str>
<str name="defType">edismax</str>
<int name="rows">10</int>
<!--<str name="fl">*,score</str>-->
<str name="facet.mincount">1</str>
<!-- 不限制Facet字段返回的結果條數. -->
<str name="facet.limit">-1</str>
<str name="facet.sort">count</str>
</lst>
<lst name="appends">
</lst>
</requestHandler>
<!-- A request handler that returns indented JSON by default -->
<requestHandler name="/query" class="solr.SearchHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<str name="indent">true</str>
<str name="q.alt">*:*</str>
<str name="fl">*</str>
<int name="rows">10</int>
<str name="facet.mincount">1</str>
<!-- 不限制Facet字段返回的結果條數. -->
<str name="facet.limit">-1</str>
<str name="wt">xml</str>
</lst>
<lst name="appends">
</lst>
</requestHandler>
<!-- Solr MoreLikeThis Query -->
<!-- 類似查詢 MoreLikeThis -->
<!-- 在solr中有兩種方式實現MoreLikeThis -->
<!-- 第一種:SearchHandler中的MoreLikeThisComponent,MoreLikeThis以組件的身份出現,適於簡單應用。 -->
<!-- 第二種:MoreLikeThisHandler,MoreLikeThis做爲一個單獨的Handler來處理,能夠應用過濾等較複雜操做 -->
<!-- 類似查詢 -->
<requestHandler name="/mlt" class="solr.MoreLikeThisHandler">
<lst name="defaults">
<str name="q.alt">*:*</str>
<str name="fl">*</str>
<!-- 開啓類似查詢 -->
<str name="mlt">true</str>
<!-- 最小分詞頻率,源文檔中小於該頻率的分詞將被忽略掉。tf:分詞後的詞在該文檔中的頻率 -->
<int name="mlt.mintf">1</int>
<!-- 最小文檔頻率,該詞所在文檔的個數小於這個值時將不用於類似判斷。df:該詞所在文檔的個數。 -->
<int name="mlt.mindf">1</int>
<!-- 設置類似查詢字段,最好採用TermVectors存儲。 -->
<str name="mlt.fl">GoodsId</str>
<!-- 控制返回結果的最大數量 -->
<int name="rows">5</int>
<str name="wt">xml</str>
</lst>
<lst name="appends">
</lst>
</requestHandler>
<!-- realtime get handler, guaranteed to return the latest stored fields of any document, without the need to commit or open a new searcher. The current implementation relies on the updateLog feature being enabled. -->
<requestHandler name="/get" class="solr.RealTimeGetHandler">
<lst name="defaults">
<str name="omitHeader">true</str>
</lst>
</lst>
</requestHandler>
<!-- The export request handler is used to export full sorted result sets. Do not change these defaults. -->
<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>
<!-- Update Request Handler. http://wiki.apache.org/solr/UpdateXmlMessages The canonical Request Handler for Modifying the Index through commands specified using XML, JSON, CSV, or JAVABIN Note: Since solr1.1 requestHandlers requires a valid content type header if posted in the body. For example, curl now requires: -H 'Content-type:text/xml; charset=utf-8' To override the request content type and force a specific Content-type, use the request parameter: ?update.contentType=text/csv This handler will pick a response format to match the input if the 'wt' parameter is not explicit -->
<requestHandler name="/update" class="solr.UpdateRequestHandler">
<!-- <lst name="defaults"> <str name="update.chain">dedupe</str> </lst> -->
</requestHandler>
<!-- Solr Cell Update Request Handler http://wiki.apache.org/solr/ExtractingRequestHandler -->
<requestHandler name="/update/extract" startup="lazy" class="solr.extraction.ExtractingRequestHandler">
<lst name="defaults">
<!-- All the main content goes into "text"... if you need to return the extracted text or do highlighting, use a stored field. -->
<str name="fmap.content">text</str>
<str name="lowernames">true</str>
<str name="uprefix">ignored_</str>
<!-- capture link hrefs but ignore div attributes -->
<str name="captureAttr">true</str>
<str name="fmap.a">links</str>
<str name="fmap.div">ignored_</str>
</lst>
</requestHandler>
<!-- Field Analysis Request Handler RequestHandler that provides much the same functionality as analysis.jsp. -->
<requestHandler name="/analysis/field" startup="lazy" class="solr.FieldAnalysisRequestHandler" />
<!-- Document Analysis Handler http://wiki.apache.org/solr/AnalysisRequestHandler -->
<requestHandler name="/analysis/document" class="solr.DocumentAnalysisRequestHandler" startup="lazy" />
<!-- Admin Handlers Admin Handlers - This will register all the standard admin RequestHandlers. -->
<requestHandler name="/admin/" class="solr.admin.AdminHandlers" />
<!-- This single handler is equivalent to the following... -->
<!-- <requestHandler name="/admin/luke" class="solr.admin.LukeRequestHandler"/> <requestHandler name="/admin/system" class="solr.admin.SystemInfoHandler"/> <requestHandler name="/admin/plugins" class="solr.admin.PluginInfoHandler"/> <requestHandler name="/admin/threads" class="solr.admin.ThreadDumpHandler"/> <requestHandler name="/admin/properties" class="solr.admin.PropertiesRequestHandler"/> <requestHandler name="/admin/file" class="solr.admin.ShowFileRequestHandler"/> -->
<!-- If you wish to hide files under ${solr.home}/conf, explicitly register the ShowFileRequestHandler using: -->
<!-- <requestHandler name="/admin/file" class="solr.admin.ShowFileRequestHandler"> <lst name="invariants"> <str name="hidden">synonyms.txt</str> <str name="hidden">anotherfile.txt</str> </lst> </requestHandler> -->
<!-- ping/healthcheck -->
<requestHandler name="/admin/ping" class="solr.PingRequestHandler">
<lst name="invariants">
<str name="q">solrpingquery</str>
</lst>
<lst name="defaults">
<str name="echoParams">all</str>
</lst>
<!-- <str name="healthcheckFile">server-enabled.txt</str> -->
</requestHandler>
<!-- Echo the request contents back to the client -->
<requestHandler name="/debug/dump" class="solr.DumpRequestHandler">
<lst name="defaults">
<str name="echoParams">explicit</str>
<str name="echoHandler">true</str>
</lst>
</requestHandler>
<queryResponseWriter name="json" class="solr.JSONResponseWriter">
<!-- For the purposes of the tutorial, JSON responses are written as plain text so that they are easy to read in *any* browser. If you expect a MIME type of "application/json" just remove this override. -->
<str name="content-type">text/plain; charset=UTF-8</str>
</queryResponseWriter>
<!-- Custom response writers can be declared as needed... -->
<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" startup="lazy" />
<!-- XSLT response writer transforms the XML output by any xslt file found in Solr's conf/xslt directory. Changes to xslt files are checked for every xsltCacheLifetimeSeconds. -->
<queryResponseWriter name="xslt" class="solr.XSLTResponseWriter">
<int name="xsltCacheLifetimeSeconds">5</int>
</queryResponseWriter>
<!-- Legacy config for the admin interface -->
<admin>
<defaultQuery>*:*</defaultQuery>
</admin>
</config>
複製代碼
<luceneMatchVersion>4.10.4</luceneMatchVersion>
複製代碼
表示Solr底層使用的Lucene的版本,官方推薦使用新版本的Lucene。php
使用注意事項:若是更改了這個設置,必須對全部已經建立的索引數據從新索引(re-index),不然可能出現沒法查詢的狀況。html
<dataDir>${solr.data.dir:}</dataDir>
複製代碼
配置SolrCore的data目錄。java
data目錄用來存放當前SolrCore的index索引文件和tlog事務日誌文件。apache
solr.data.dir
表示 ${SolrCore}/data
的目錄位置。json
建議不做修改,不然配置多個SolrCore時容易出錯。數組
<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>
複製代碼
有如下存儲方案:瀏覽器
solr.StandardDirectoryFactory
:這是基於文件系統存儲目錄的工廠 它會基於當前的操做系統和JVM版本選擇最好的實現。solr.NRTCachingDirectoryFactory
:默認方案:此工廠的設計目的是在內存中存儲部分索引, 從而加快近實時搜索(Near-Real-Time)的速度。solr.MMapDirectoryFactory
:這是Solr 3.1 - 4.0 版本在Linux64位系統下的默認實現, 它經過使用虛擬內存和內核特性調用 mmap去訪問存儲在磁盤中的索引文件, 容許Lucene或Solr直接訪問I/O緩存. 若是不須要近實時搜索功能, 使用此工廠是個不錯的方案。solr.NIOFSDirectoryFactory
:適用於多線程, 但據報道, Solr 4.x以前的版本不適用在Windows系統上(慢), 由於JVM還存在bug。solr.SimpleFSDirectoryFactory
:適用於小型應用程序, 不支持大數據和多線程。solr.RAMDirectoryFactory
:這是內存存儲方案, 不能持久化存儲, 在系統重啓或服務器crash時數據會丟失. 並且不支持索引複製(不能使用副本)。<codecFactory class="solr.SchemaCodecFactory"/>
<schemaFactory class="ClassicIndexSchemaFactory"/>
複製代碼
Solr中,編碼可使用自定義的編解碼器,好比:想啓動per-field DocValues
格式,能夠在solrconfig.xml
文件中設置Schemafactory
的內容:緩存
docValuesFormat="Lucene42"
:默認設置, 全部數據會被加載到堆內存中;docValuesFormat="Disk"
:這是另外一個實現,將部分數據存儲在磁盤上;docValuesFormat="SimpleText"
:文本格式, 很是慢, 僅僅用於學習測試。<indexConfig>
<!-- maxFieldLength was removed in 4.0. To get similar behavior, include a LimitTokenCountFilterFactory in your fieldType definition. E.g. <filter class="solr.LimitTokenCountFilterFactory" maxTokenCount="10000"/> -->
<writeLockTimeout>10000</writeLockTimeout>
<useCompoundFile>false</useCompoundFile>
<ramBufferSizeMB>100</ramBufferSizeMB>
<mergePolicy class="org.apache.lucene.index.TieredMergePolicy">
<int name="maxMergeAtOnce">10</int>
<int name="segmentsPerTier">10</int>
</mergePolicy>
<mergeFactor>10</mergeFactor>
<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler" />
<lockType>${solr.lock.type:native}</lockType>
<unlockOnStartup>false</unlockOnStartup>
<termIndexInterval>128</termIndexInterval>
<reopenReaders>true</reopenReaders>
<deletionPolicy class="solr.SolrDeletionPolicy">
<str name="maxCommitsToKeep">1</str>
<str name="maxOptimizedCommitsToKeep">0</str>
<str name="maxCommitAge">30MINUTES</str>
</deletionPolicy>
<infoStream>true</infoStream>
<checkIntegrityAtMerge>false</checkIntegrityAtMerge>
</indexConfig>
複製代碼
indexConfig
標籤用於設置索引的屬性。安全
maxFieldLength
:對文檔創建索引時,文檔字段的最大長度,超過這個長度的值將被截斷。若是文檔很大,就須要增長這個數值。這個值設置的太高會致使內存不足異常。 該配置在Solr 4.0版本開始已經移除了,相似的設置須要在fieldType中定義。如:<!-- 限制token最大長度 -->
<filter class="solr.LimitTokenCountFilterFactory" maxTokenCount="10000"/>
複製代碼
writeLockTimeout
:IndexWriter等待寫鎖的最長時間(毫秒)。默認是1000毫秒。性能優化
maxIndexingThreads
:生成索引時一個IndexWriter可使用的最大線程數。默認是8,當不少線程到達時,多出的線程就只能等待運行中的線程結束,以空出資源。
useCompoundFile
:開啓整合文件。 開啓此選項,Lucene會將多個內部文件整合爲若干個大文件,來減小使用Lucene內部文件的數量。即便用更少的用於索引的文件,這有助於減小Solr用到的文件句柄的數目,代價是下降了性能——用於索引的文件數更少了。除非應用程序用完了文件句柄,不然使用默認值false就能夠。 Lucene中默認是true,Solr3.6開始默認爲false。
ramBufferSizeMB
:Lucene建立或刪除index後,合併內存中的文檔數據、建立新的segment、將內存中數據刷新到磁盤以前可用的RAM大小。默認是100MB,較大的值能夠提升建立索引的時間,但會犧牲更多內存。
maxBufferedDocs
:在將內存中的索引數據刷到磁盤以前,可使用的buffer大小。 默認是1000個文檔,較大的值能夠提升建立索引的時間,但會犧牲更多的內存。 說明:ramBufferSizeMB和maxBufferedDocs同時設置時,優先知足閾值小的選項。
mergePolicyFactory
:合併策略。
<mergePolicyFactory class="solr.TieredMergePolicyFactory">
<!-- 一次最多合併的段的個數 -->
<int name="maxMergeAtOnece">10</int>
<int name="segmentsPerTier">10</int>
</mergePolicyFactory>
複製代碼
配置Lucene中segment(段,索引信息的呈現方式)的合併策略:
從Solr/Lucene3.3開始,使用TieredMergePolicyFactory。
從Lucene2.3開始,默認使用LogByteSizeMergePolicy;
更早的版本使用LogDocMergePolicy。
mergeFactor
:合併因子,每次合併多少個segment。默認是10,每次合併多少個segment。<mergeFactor>10</mergeFactor>
複製代碼
越小的值(最小爲2)使用的內存越少,但建立索引的時間也更慢;
值越大,可讓索引時間變快,但會用掉更多的內存——典型的時間與空間的平衡。
mergeScheduler
:合併段的調度器,控制Lucene如何實現段的合併。<mergeScheduler class="org.apache.lucene.index.ConcurrentMergeScheduler"/>
複製代碼
從Lucene 2.3開始默認使用ConcurrentMergeScheduler調度器, 可使用單獨的線程在後臺並行執行合併;
Lucene 2.2以前默認使用SerialMergeScheduler調度器, 並不能並行執行合併。
lockType
:指定Lucene使用哪一個LockFactory的實現, 即Lock策略。<lockType>${solr.lock.type:native}</lockType>
複製代碼
共有三種策略:
single
- SingleInstanceLockFactory, 建議用於只讀索引(read-only)或不存在其餘進程會修改索引的場景;native
- NativeFSLockFactory,使用操做系統本地文件鎖機制, 當同一個JVM中的多個Solr Web應用試圖共享同一個索引時,不能使用;simple
- SimpleFSLockFactory,普通文件的行鎖定方式。
Solr3.6以後默認是native
策略,以前的版本使用的是simple
策略。
unlockOnStartUp
:啓動Solr服務時釋放鎖。<unlockOnStartup>false</unlockOnStartup>
複製代碼
某些狀況下,索引可能會因爲不正確的關機或其餘錯誤而一直處於鎖定狀態,致使不能田間和更新索引。將其設置爲true能夠禁用啓動鎖定,從而容許添加和更新操做。
默認爲false。
若是設置爲true,在Solr啓動時將釋放全部的寫鎖或提交鎖——忽略多線程環境中保護索引的鎖定機制,將致使進程能夠繞過Lucene索引的鎖機制直接訪問索引,請慎用。
若是鎖類型爲```single````,該配置將不起做用。
termIndexInterval
:Lucene將term加載到內存中的頻率。<termIndexInterval>128</termIndexInterval>
複製代碼
最佳實踐:使用默認值128,大多數狀況下都頗有用。
nrtMode
:近實時模式。<nrtMode>true</nrtMode>
複製代碼
默認爲true,設置爲true,將從IndexWriter打開/從新打開IndexReaders,而不是從文件目錄打開。
在主/從模式的主機中, 將其設置爲false;
在SolrCloud集羣中, 將其設置爲true.
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默認的實現類支持刪除索引提交點的提交數量,索引提交點和優化狀態的年齡(即內部掃描的次數)。不管如何,都應該一直保留最新的提交點。
infoStream
:Lucene的信息流,控制索引時的日誌信息。<infoStream file="INFOSTREAM.txt">false</infoStream>
複製代碼
爲了方便調試,Lucene提供了InfoStream
用於顯示索引時的詳細信息。
默認爲false。設置爲true時,Lucene底層的IndexWriter將會把本身的信息流寫入Solr的日誌,具體日誌信息還要經過log4j.properties
文件控制。
checkIntegrityAtMerge
:合併段時的安全檢查。<checkIntegrityAtMerge>false</checkIntegrityAtMerge>
複製代碼
設置爲true,將啓用此安全檢查——有助於在合併segment時 下降舊segments中損壞的索引轉移到新段的風險,代價是合併的速度將變慢。
Solr默認使用的高可用的updateHandler
是:
<updateHandler class="solr.DirectUpdateHandler2">
複製代碼
<updateLog>
<!-- dir: 事務日誌的存儲目錄 -->
<str name="dir">${solr.ulog.dir:}</str>
</updateLog>
複製代碼
默認路徑:${SOLR_HOME}/data/tlog
啓用事務日誌用於實時查詢、持久化索引數據、Solr Cloud中副本的恢復……
隨着索引庫的頻繁更新,tlog日誌文件會愈來愈大,因此建議提交索引時採用硬提交 - 即批量提交的方式。 - hard commit
。
這是默認的自動提交策略。
<autoCommit>
<!-- 多少個文檔提交一次: 要添加的文檔數達到此值時自動觸發新的提交 -->
<maxDocs>10000</maxDocs>
<!-- 多少毫秒提交一次: 添加文檔操做的時間持續到此值時自動觸發新的提交, 與maxDocs配置其一便可 -->
<!-- 二者同時配置時知足其中一個條件便可觸發自動提交 -->
<maxTime>${solr.autoCommit.maxTime:15000}</maxTime>
<!-- 若是爲false, 提交操做會將最近的更改信息刷新到磁盤, 但不會當即打開查詢器 - 也就是說客戶端查詢不到; 實時性要求高的項目, 須要設置爲true - 在6.0以後的版本中默認爲true -->
<openSearcher>true</openSearcher>
</autoCommit>
複製代碼
autoCommit
是硬提交,開啓後會進行以下操做。
- 生成一個新的tlog文件,刪除舊的tlog文件;
- 把內存中緩存的文檔fsync(OS內部的函數)到磁盤中,並建立一個index descriptor,用來記錄各個文檔的存儲位置;此時就算JVM崩潰或系統宕機,也不影響這部分數據,不利之處是:佔用資源較多。
- 若是
<openSearcher>true</openSearcher>
,就會打開查詢器,讓這次硬提交的文檔可供搜索。
在Solr6.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); 複製代碼
在頻繁添加文檔的應用中,官方建議使用
commitWithin
,而不是啓用autoCommit
。經過代碼操做時,請不要使用
commit API
手動提交,由於這會觸發硬提交,出現大量的建立、刪除tlog文件的操做,影響IO性能。若是啓用了updateLog,官方強烈建議使用某種硬提交策略來限制日誌的大小。
最佳的自動提交設置:須要在性能和可見性之間進行權衡。
// 若是要手動提交, 不要使用無參方法, 推薦指定提交策略: 是否等待刷新(建議不等待, 由於會阻塞)、等待可搜索(建議不等待, 由於會阻塞)、軟提交
// 這是Solr 4.10版本API中的用法.
solrServer.commit(false, false, true);
複製代碼
<autoSoftCommit>
<maxTime>${solr.autoSoftCommit.maxTime:-1}</maxTime>
</autoSoftCommit>
複製代碼
autoSoftCommit
是軟提交,配置後會進行以下操做:
- 把內存中緩存的索引的文檔fsync(OS內部的函數)到磁盤中,但不會建立index descriptor——也就是說各個文檔的真實存儲位置並無被記錄下來。
- 打開文檔查詢器,涉及到的索引數據能夠被查詢到——近實時(NRT)更好。
- 軟提交不會等待後臺合併、整理文檔等操做,只確保了修改的可見性,沒有獲取到文檔的具體存儲位置——也就是說若是此時JVM崩潰活着系統宕機,就找不到這些數據了
軟提交比硬提交更快,更能作到近實時查詢,可是若是服務器不穩定,或JVM崩潰,會致使提交的數據沒法被檢索到。
maxBooleanClauses
:最大布爾子句,能夠組合在一塊兒造成一個查詢的布爾子句數量的上限,默認的1024已經足夠。<maxBooleanClauses>1024</maxBooleanClauses>
複製代碼
若是應用程序大量使用了通配符或範圍查詢,爲了不拋出TooManyClausesException
異常,建議增長這個值。
這個選項會修改全部SolrCores的全局Lucene屬性,若是多個solrconfig.xml文件中的配置不一致,將以最後初始化的文件爲基準。
Solr使用Searcher類來處理查詢。這個類將與索引相關的數據加載到內存中,根據索引、CPU及內存的大小,加載過程可能耗時比較久。
要改進這一設計和顯著提升性能,Solr引入一種「預熱」策略,就是把這些新的Searcher聯機以便爲用戶提供查詢服務以前,先對它們「熱身」。
- 基於LinkedHashMap的LRUCache;
- 基於ConcurrentHashMap的FastLRUCache。
區別:FastLRUCache在單線程操做中具備更快的查詢和更慢的添加操做,所以當緩存的命中率(> 75%)時一般比LRUCache更快,而且在多CPU系統的其餘場景下可能更快。
class:SolrCache的實現類;
size:cache中可保存的最大項。
initalSize:cache的初始化大小,與
java.util.HashMap
中entry的容量相關。
- 對全部緩存模式而言,設置緩存參數時,都有必要在內存、CPU和磁盤訪問之間進行均衡。Solr Web管理員界面的Statistics對分析緩存的hit-to-miss比例以及微調緩存大小等統計數據都很是有用。
- 並不是全部應用程序都會從緩存收益,實際上一些應用程序反而會因爲「將某個永遠用不到的條目存儲在緩存中」這一額外步驟而受到影響。
filterCache
:過濾器緩存。<filterCache class="solr.FastLRUCache" size="512" initialSize="512" autowarmCount="0"/>
複製代碼
是SolrIndexSearcher用於過濾(filter queries
,也就是fq
參數)的緩存:將獲得的文檔存儲爲無序的集合DocSets;
結果還能用來facet分片查詢——有效提升了Solr的查詢性能。
queryResultCache
:查詢結果緩存。<queryResultCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0"/>
複製代碼
緩存查詢結果——基於查詢、排序和請求的有序的文檔範圍,也就是文檔id列表。
documentCache
:文檔緩存。<documentCache class="solr.LRUCache" size="512" initialSize="512" autowarmCount="0"/>
複製代碼
緩存Lucene的Document對象,也就是每一個文檔的stored fields
- 在schema.xml
文件中配置。
因爲Lucene內部文檔ID是瞬態的(會被更改),所以該緩存不會自熱。
cache
:塊鏈接使用的自定義緩存。<cache name="perSegFilter" class="solr.search.LRUCache" size="10" initialSize="0" autowarmCount="10" regenerator="solr.NoOpRegenerator" />
複製代碼
fieldValueCache
:字段值緩存。<fieldValueCache class="solr.FastLRUCache" size="512" autowarmCount="128" showItems="32" />
複製代碼
該緩存用來按照文檔的id保存可以快速訪問的字段的值,就算這裏不配置,Solr也會默認建立fieldValueCache。
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的緩存。
enableLazyFieldLoading
:開啓懶加載Field。<enableLazyFieldLoading>true</enableLazyFieldLoading>
複製代碼
性能優化建議:若是應用程序只會檢索文檔中的少數幾個Field,能夠把這個屬性設置爲true——沒有請求的存儲字段(stored fields)將延遲加載。
懶加載大多發生在應用程序返回部分檢索結果時,用戶經常會單擊其中一個來查看存儲在此索引中的原始文檔,初始每每只須要顯示很短的一段信息。
查詢很大的Document,尤爲是含有很大的text類型的字段時,應該避免加載整個文檔。
useFilterForSortedQuery
:爲存儲字段使用過濾器。<useFilterForSortedQuery>true</useFilterForSortedQuery>
複製代碼
經過使用過濾器進行搜索的優化,若是請求的排序條件不包括文檔的得分(score),Solr將檢查filterCache
以查找和查詢匹配的過濾器。若是找到,相關過濾器將做爲文檔ID的來源,而後對其ID進行排序返回。
大多數狀況下,除非 常用不一樣的排序規則 並 重複進行相同的查詢,不然這個配置沒有多大用處,能夠不用配置。
queryResultWindowSize
:查詢結果窗口大小。<queryResultWindowSize>20</queryResultWindowSize>
複製代碼
用於queryResultCache
的優化。發起查詢請求時,將手機所請求數文檔ID的數量集合。
例如:搜索特定查詢請求並匹配文檔10-19,而且queryWindowSize = 50
,Solr將收集並緩存文檔0-49。
能夠經過緩存實現該範圍內的任意其餘查詢請求。
queryResultMaxDocsCached
:查詢結果的最大文檔緩存數。<queryResultMaxDocsCached>200</queryResultMaxDocsCached>
複製代碼
設置查詢結果中能夠緩存的最大文檔數。
負責查詢操做的各種搜索器(IndexSearcher
),均可以觸發相關監聽器,進而採起下一步操做:
- newSearcher - 每當建立新的搜索器時觸發,而且當前的搜索器正在處理請求(也成爲被註冊了)。它能夠用來啓動某些緩存,以防止某些請求的請求時間過長。
- firstSearcher - 建立第一個搜索器時觸發,但這時是沒有可用的搜索器來處理請求或加載緩存中的數據的。
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>
複製代碼
useColdSearcher
:使用冷搜索器。<useColdSearcher>false</useColdSearcher>
複製代碼
若是搜索請求到來,而且目前尚未被註冊的搜索器,就當即註冊仍在加載緩存(自熱)的搜索器並使用它。
默認爲false - 全部請求都將阻塞,直到第一個搜索器完成緩存數據的加載。
maxWarmingSearchers
:最大的搜索器個數,默認是2。<maxWarmingSearchers>2</maxWarmingSearchers>
複製代碼
在後臺同時預熱(加載緩存)的搜索器的最大數量,這些搜索器事先預熱好,能夠隨時使用,若是申請的搜索器個數超出範圍將會報錯。
對只讀的索引庫,建議設置爲1-2
,對於可讀寫的索引庫,根據設備內存和CPU的大小,能夠設置更高的值。
若是頻繁讀寫的索引庫中,此參數較小,可能會拋出Error opening new searcher. exceeded limit of maxWarmingSearchers=2, try again later.
的錯誤,嘗試將其調高便可解決此問題。
<requestDispatcher handleSelect="false" >
複製代碼
Request Dispatcher用來指示SolrCore裏的
SolrDispatchFilter
處理請求的行爲。handleSelect是一個之前版本中遺留下來的屬性,會影響請求的行爲(好比
/select?qt=XXX
)。若是
/select
沒有註冊,當handleSelect="true"
時,SolrDispatchFilter
就會把請求轉發給qt參數指定的處理器;除非使用/select
顯示註冊了處理器,不然當handleSelect="false"
時,SolrDispatchFilter
會忽略/select
請求,並致使404錯誤——使用上更安全。對於新用戶不建議使用
handleSelect="true"
,但這是默認向後兼容的配置。
<requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="2048000" formdataUploadLimitInKB="20480" addHttpRequestToContext="false"/>
複製代碼
這裏配置Solr請求的解析行爲,以及對請求的ContentStreams的限制。
enableRemoteStreaming
:是否容許使用stream.file和stream.url參數來指定遠程streams。這裏介紹的Solr4.10版本中默認開始了此選項,受權Solr獲取遠程文件——不安全,官方建議咱們要確保系統具備身份驗證功能。multipartUploadLimitInKB
:指定Solr容許一個多文件上傳的請求中文件的最大大小值,以KB爲單位。formdataUploadLimitInKB
:指定經過POST請求發送的表單數據(application/x-www-form-urlencoded
)的最大值,以KB爲單位。addHttpRequestToContext
:設置爲true,它將聲明原始的HttpServletRequest對象應該被包括在SolrQueryRequest的上下文集合(context map)中,這裏的SolrQueryRequest
是基於httpRequest
的請求。這個HttpServletRequest
不會被任何現有的Solr組件使用,但在開發自定義插件時可能頗有用。
httpCaching
:控制HTTP緩存控制頭(HTTP cache control headers),是W3C HTTP規格定義的HTTP響應的緩存過程,與Solr內部的緩存徹底不一樣,請勿混淆。
<httpCaching>
:元素的屬性決定了是否容許對一個GET請求進行304響應:當一個客戶端發起一個GET請求,若是資源從上一次被獲取後尚未被修改,那麼它能夠在響應頭中指定304響應。
304狀態碼的相關信息可參考:HTTP 304狀態碼的詳細講解
xml <httpCaching never304="true" />
複製代碼
never304
:若是設置爲true,那麼即便請求的資源沒有被修改,客戶端的GET請求也不會獲得304響應。將這個屬性設置爲true對開發來講是方便的,由於當經過支持緩存頭的Web瀏覽器或其餘用戶修補Solr的響應時,這裏的304響應可能會讓人混淆。
<httpCaching never304="false" lastModFrom="openTime" etagSeed="Solr">
<cacheControl>max-age=30, public</cacheControl>
</httpCaching>
複製代碼
若是包含<caccheControl>
指令,將會生成Cache-Control頭信息,若是值包含max-age=
,還會生成Expires頭信息——默認狀況下不會生成任何Cache-Control頭部信息。
即便設置了never304="true"
,也可使用<cacheControl>
選項。
若是要讓Solr可以使用自動生成的HTTP緩存頭進行響應,並正確響應緩存驗證請求,就要把never304的值設置爲"false" => Solr將根據索引的屬性生成相關的Last-Modified和ETag頭信息。
還能夠指定如下選項來限制響應頭的信息:
lastModFrom
:默認值爲"openTime"(記錄了最後的更改時間),這意味着Last-Modified(以及對If-Modified-Since請求的驗證)將所有與當前Searcher的openTime相關聯。若是但願lastModFrom
與上次修改物理索引的時間精確同步,能夠將其更改成lastModFrom="dirLastMod"
。etagSeed="..."
:是一個能夠更改的選項,即便索引沒有更改,改變這個值將強制更改ETag頭信息,從而強制讓用戶從新獲取內通,好比對配置文件作了重大修改時。
若是使用了never304="true"
,Solr將忽略lastModifiedFrom
和etagSeed
的配置。
Solr經過RequestHandler(請求處理器),提供相似WebService的功能——經過HTTP請求對索引進行訪問。
Solr經過下述步驟選擇Request Handler去處理請求:
qt
參數指定的路徑,按名稱分配給特定的Request Handler。/select
,但卻沒有任何一個Request Handler具備select
這個名稱,而requestDispatcher
,就會根據qt
參數調度Request Handler。/
的請求,是這樣被執行的:http://host/app/[core/]select?qt=name
,若是沒有給出qt
參數,那麼將使用配置爲default="true"
的requestHandler或者名稱爲"standard"(標準處理器)的處理器處理。startup="lazy"
的處理器,則在第一個使用這個請求處理器的請求到來以前不會初始化它。<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>
複製代碼
default
- 默認值:能夠指定查詢參數的默認值,這些都會被請求中的參數覆蓋,也就是說請求中的優先。appends
- 追加值:除了默認值以外,還能夠指定appends
(追加)參數來標識 從查詢參數(或現有的「default」的值)中獲取參數值,而後追加到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
是不會打開的,但若是客戶端在請求中指定了faccet=true
,那麼無論它們指定的facet.feild
或facet.query
參數是什麼,這裏配置的都將是客戶端惟一能獲得的facet
的內容。
注意:絕對客戶端沒法阻止使用這些「不變量」值,所以除非您肯定老是須要它,不然不要使用此機制。
components
- 組件:在request handler的最後, 是組件components
的定義: 定義能夠用在一個request Handler的搜索組件的列表, 它們僅在 Request Handler 中註冊.<!-- <arr name="components"> <str>nameOfCustomComponent1</str> <str>nameOfCustomComponent2</str> </arr> -->
複製代碼
搜索組件元素只能被用於SearchHandler, 若是不須要默認的SearchComponents列表, 能夠徹底覆蓋該列表, 也能夠將組件添加到默認列表中或將其附加到默認列表中。
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>
複製代碼
RealTimeGetHandler
- 實時獲取處理器, 保證返回的每一個文檔的最新存儲字段, 而不須要提交或打開新的Searcher。
<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>
複製代碼
Solr當前版本的RealTimeGetHandler
的實現, 須要開啓updateLog
功能。
若是使用SolrCloud,就不要在
/get
處禁用RealTimeGetHandler
, 不然每次觸發的Leader選舉都將致使選舉涉及到的Shard中的全部Replicas被徹底同步。一樣, Replica的恢復也將始終從Leader中獲取完整的索引,由於若是沒有
RealTimeGetHandler
的狀況下, Replicas將沒法進行部分同步。
導出請求處理器用於導出完整排序的結果集, 請不要更改這些默認的配置值。
<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>
複製代碼
經過 /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
相應類型參數沒有給出, 處理器將選擇一個響應格式以匹配輸入的內容。