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