作者:戰鬥民族就是幹
轉載請註明地址: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的過程中自己就可以體會到的,所以在這裡不在贅述了