作者:戰斗民族就是干
轉載請注明地址:http://www.cnblogs.com/prayers/p/8982141.html
本篇文章我們來了解一下solr的性能方面的調優,分為Schema優化、索引更新與提交調優、索引合並性能調優、Solr緩存、Solr查詢性能優化
Schema優化
1、index=true比index=false在索引時占用更多的內存、索引合並和優化時間更長,索引體積也響應變的更大,如果你不需要針對該域進行檢索,可以設置為index=false
2、如果不關心Term在文檔中出現的次數對最終文檔的影響可以設置omitNorms=true,即取消標准化因此對score的影響。它能減少磁盤空間的占用並加快索引速度
3、如果你不需要對該域進行高亮,你還可以設置omitPositions=true進一步減小索引體積
4、如果只需要利用倒排索引結構根據指定的Term找到對應的document,不需要計算Term在Document中的出現頻率來考慮每個索引文檔的權重,那么還可以設置omitTermFreqAndPositions=true即忽略TF計算以及Term在TermVector中的位置信息,這樣能夠進一步減小索引體積
5、對於stored屬性而言,在響應結果集中通過FL參數返回stored=true的域的執行開銷很大,因為域值需要存儲到硬盤寫IO,查詢時提取域值需要磁盤讀IO,如果不需要存儲可以設置stored=false,進一步優化索引的體積
6、如果你想要存儲的域值長度並不大, 但是為了能夠緩解提取存儲域帶來的磁盤IO,此時可以設置compressed=true即啟用域值數據壓縮。開啟compressed會降低磁盤IO但會增大CUP開銷
7、如果並不是一直都需要使用存儲域,你可以設置域延遲加載,尤其是當你開啟了域值數據壓縮。設置延遲加載開啟延遲加載之后,要返回的字段會被SetNonLazyFieldSelector立即加載,其他的域為延遲加載。啟用域延遲加載,需要在solrconfig.xml中進行如下配置
<enableLazyFieldLoading>false</enableLazyFieldLoading>
8、如果你的域值很大,可以使用ExternalFileField域(外部文件),他不支持solr查詢,只能用於顯示和function計算,還可以將域值儲存在外部系統,比如redis等,當需要域值的時候根據solr的UniqueKey去緩存中提取
9、對於Java里的日期時間類型的數據,建議你使用Solr里的date域類型,如果你需要進行日期時間范圍區間查詢,那么建議使用Solr里的date域類型,而不是使用string域類型
10、可以對facet域、排序域設置為docValue=true,它將會生成一個額外的正排表,會提升分面和排序的效率
索引更新與提交調優
1、不建議使用顯示硬提交,建議在solrConfig里面配置自動軟/硬提交方式
2、客戶端在提交索引文檔的時,建議使用批量軟提交的方式添加索引文檔
3、單機模式下,在提交索引的時候建議使用ConcurrentUpdateSolrClient類,對於solrCloud模式下建議使用CloudSolrClient類來更新或提交索引
4、默認情況下,solr會將document的每個域域值進行索引,當在對一些大文檔進行索引的時候,因為創建索引過程中solr需要將document緩存在內存中,如果域的域值很大,內存占用就很大,可能觸發更頻繁的GC,GC可能會導致暫停索引創建過程,對一些大文本域使用的域類型配置LimitTokenCountFilterFactory來限制實際索引的文本長度,從而減少索引過程中內存占用
5、在創建索引的時候,需要對文本進行分詞處理時,建議配置停止詞來剔除掉無用的噪音詞,從而減少索引體積,同時還可以避免噪音詞印象最終的檢索結果
6、禁用CompoundFile(復合)文件:開始復合文件雖然可以減少段文件個數,但是它會使得你的索引創建時間增加7%~33%,具體配置如下
<useCompoundFile>false</useCompoundFile> <mergePolicy class=”org.apache.lucene.index.TieredMergePolicy”> <float name=”noCFSRatio”>0.0</float> </mergePolicy>
7、如果索引速度經過一系列優化還是比較慢,建議可以使用MapReduce框架,利用多台機器的資源並行創建solr索引,從而加快索引速度
索引合並性能調優
1、降低索引合並頻率:索引合並之后能加快Solr查詢性能,但是索引合並是一個執行開銷很大的操作,因此你需要在保證查詢性能的前提下,盡量的降低索引合井的頻率
2、加大ramBufferSizeMB和maxBufferedDocs參數值,並且盡量降低顯式提交的頻率:索引提交除了用戶顯式的執行commit操作之外,ramBufferSizeMB或者maxBufferedDocs參數達到限定的闊值之后也會自動觸發索引提交。 因此,為了降低索引合並的頻率, 應該加大ramBufferSizeMB和maxBufferedDocs參數值,並且盡量降低顯式提交的頻率,比如采用批量commit,或者直接在solrconfig刀nl 中配置自動提交並控制自動提交的頻率,避免顯式提交
3、增大mergeFactor參數值:加大mergeFactor參數值確實可以加快索引創建速度,降低索引合並頻率但是同時它也會降低你的Solr查詢響應速度
Solr緩存
Solr中緩存都是由SolrIndexSearcher實例來管理的,一個SolrIndexSearcher實例對應一套緩存體系,如果你新建立一個SolrIndexSearcher實例,那么之前的SolrIndexSearcher全部會失效,當你數據量很大的時候,增量很頻繁的時候對緩存的依賴很大,這個之后你需要在新建SolrIndexSearcher進行緩存預加載,術語叫預熱
solr默認的4中緩存類型
1、filterCache
用於緩存Filter Query從硬盤提取出來的Document的無序ID ,下次執行相同的FieldQuery就直接會命中緩存。Solr會默認為每一個FilterQuery提供FilterCache.
應用場景:
1) 緩存所有FilterQuery返回的結果集,solr會將主Q查詢的結果集和Filter緩存的無序Document ID set集合取交集
2) 當facet.method=enum時候會命中Filter緩存
3) 如果solrconfig.xml中配置了<useFilterForSortedQuery/>true</useFilterForSortedQuery>,那么對於Solr排序操作也會使用Filter緩存。
4) Filter緩存通常還會用於其他Solr查詢,比如facet.query、 group.query
不適用場景:
價格區間、時間區間查詢:全品類價格區間太多,時間精確到秒。如果對每一個價格區間的FilterQuery都啟用FilterCache需要大量的內存支撐,另外由於區間太復雜,緩存命中率也會大大下降,所以這個時候我們可以類似這樣的FilterQuery禁用Filter緩存
2、documentCache
DocumentCache(即文檔緩存):用於儲存已經從磁盤上提取出來的Lucence中的document對象。Document緩存保存的最大項數:應該大於返回結果集中可能的最大值*查詢的最大並發量。 這樣做的目的是因為為了確保solr不在從磁盤上提取索引文檔,但是隨着doc數目越來也多,documentCache占用的內存就會越來越大
當你開啟了document緩存並且開啟了延遲加載,那么indexReader所提取的對象僅僅包含fl參數指定的Field,其他的Field會被延遲加載,這么做可以減少document緩存對內存的占用,當延遲加載的域,被后續請求到,那么indexReader會臨時從硬盤加載該域
還需要注意的是document緩存並不能進行緩存預熱,也就意味這次當打開了一個SolrIndexSearcher的時候,緩存並不會提前進行加載,因為document緩存使用的是lucence內部的document ID,當索引數據變化了之后,該ID也會發生變化
3、queryResultCache
QueryResult緩存(查詢結果集緩存):用於緩存查詢的TOP N結果集的有序的Document ID,按照排序域進行排序。查詢結果集緩存的內存占用明顯要比Filter小,因為只有q,fq,sort參數同時一致的查詢才會命中緩存
4、fieldValueCache
fieldValueCache(即域值緩存):與lucence中的fieldCache相似,但是不同的是FieldValueCache支持每個document對應多個值(多值域的多個值域,或者單值域因分詞產生多個Term)。此緩存多用於facet查詢,緩存的key為域的名稱,value為docid到多個值的映射的數據結構。如果solrconfig.xml中沒有定義<fieldValueCache>,那么Solr會自動為你生成一個size=10, max Size= 10 000,無autowarm的<fieldValueCache>
HTTP緩存:除了可以在后台服務層啟用Solr緩存之外,你還可以在前端HTTP協議層啟用HTTP緩存,對於沒有更新的資源,可以直接從HTTP緩存中直接返回,避免了同樣的查詢請求頻繁請求服務器,這能在一定程度上減輕Solr Server的負載壓力。如果想要開啟HTTP緩存,配置如下:
<httpCaching never304=”false”> <cacheControl>max-age=30, public</cacheControl> </httpCaching>
或者
<httpCaching lastModifiedFrom=”openTime” etagSeed=”Solr”> <cacheControl>max-age=30, public</cacheControl> </httpCaching>
never304參數設置為false 即表示開啟Solr中的HTTP緩存,默認never304=true即禁用HTTP緩存。 Solr中的HTTP緩存只支持GET和HEAD請求,不支持POST請求。 SolrHTTP緩存兼容HTTPI.O和HTTPl.l協議頭信息。
你還可以在solrconfig.xml 配置firstSearcher和newSearcher事件監昕器來自動觸發緩存自動預熱。
newSearcher用於當一個新的IndexSearcher實例被創建時,除了從舊IndexSearcher實例自動預熱一部分緩存之外,還可以顯式的指定一個查詢來對緩存進行預熱。 當某個查詢耗時很長時,你可以提前通過newSearcher監昕器進行預熱,這樣后續你再執行該慢查詢時會直接命中緩存。
firstSearcher表示當一個新的IndexSearcher實例正在被初始化並且當前沒有舊的Index Searcher實例用於新的IndexSearcher實例進行緩存自動預熱,此時你需要顯式的指定一個查詢來自動預熱緩存。 這個firstSearcher主要用於配置Solr剛啟動時執行什么查詢並放入緩存。 因為Solr剛啟動時,緩存肯定是空的,為了保證剛啟動的一段時間內的查詢性能高效,因此你需要配置firstSearcher來提取預熱。
當使用que可Result緩存時,你還可以額外添加<queryResultWindowSize>配置來對其進行優化。 當一個查詢被執行,返回的DocumentID會被收集,比如查詢匹配的documentID是[10, 19)之間,如果queryWindowSize= 50,那么DocumentID [0, 50] 會被收集並緩存,在此范圍內的Document將會命中緩存
Solr查詢性能優化
1、如果你的查詢需要在三個域上進行查詢,此時可以用copyField將三個域合並成為一個域,在合並之后的域上進行查詢。因為在單個域上進行查詢比在N個域上進行查詢效率要高。但是使用copyField之后,你無法為每個單獨的域進行加權
2、應該優先讓那些能夠過濾掉大部分索引文檔的FilterQuery先執行
3、在對數字域進行范圍查詢的時候,可以調整precisionStep來對rangeQuery進行優化。precisionStep默認值是4,這個值越大,分解出來的索引前綴索引就越多,數字范圍查詢越快,但是會增大索引體積
查詢方面的優化點還有很多,需要針對不同的場景不同的去分析使用。大部分是在學習solr的過程中自己就可以體會到的,所以在這里不在贅述了