<?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
相应类型参数没有给出, 处理器将选择一个响应格式以匹配输入的内容。