結合自己的項目談談solr優化

index優化

先理解下索引段的概念

mergeFactor(索引段合併頻數,當大小相當的段數達到這個數的時候開始合併)

比如mergeFactor=3,開始來的段大小爲10M(第一層),當湊夠3個10M的時候,0.cfs, 1.cfs, 2.cfs則合併成一個新的段3.cfs,大小爲30M(第二層),然後再來4.cfs, 5.cfs, 6.cfs,合併成7.cfs,大小爲30M,然後再來8.cfs,9.cfs,a.cfs合併成b.cfs, 大小爲30M,這時候又湊夠了3個30M的,合併成90M的c.cfs(第三層),然後又來d.cfs, e.cfs, f.cfs合併成10.cfs,大小爲30M,然後11.cfs大小爲10M,這時候硬盤上的段爲:c.cfs(90M)10.cfs(30M),11.cfs(10M),可以想象,越到後合併時間會越來越多。

官方wiki:

MergeFactor (default: 10)

Determines how often segment indices aremerged by addDocument(). With smallervalues, less RAM is used while indexing, and searches are faster, but indexingspeed is slower. With larger values, more RAM is used during indexing, andwhile searches is slower, indexing is faster. Thus larger values (> 10) arebest for batch index creation, and smaller values (< 10) for indices thatare interactively maintained.

MaxMergeDocs(default: 10000)

Determines thelargest segment (measured by document count) that may be merged with othersegments. Small values (e.g., less than 10,000) are best for interactiveindexing, as this limits the length of pauses while indexing to a few seconds.Larger values are best for batched indexing and speedier searches.

簡單理解是較高的合併因子,會提高索引速度,會降低索引的搜索效率;較低的合併因子,會降低索引的速度,能提高搜索速度;所以這有一個權衡需要嘗試。

一般這兩個要合起來使用:

   LogMergePolicy mp = new LogByteSizeMergePolicy();

   mp.setMergeFactor(10 ); //滿10segment合併一次

   mp.setMaxMergeDocs(10000);//segment段最大保存document

3.5版本以後增加的新特性

TieredMergePolicy根據每一層允許的段數合併大小相似的段。這個策略和之前版本的LogByteSizeMergepolicy策略區別在於它可以合併不相鄰的段(即不在同一層),並且區分最多允許一次合併的段數setMaxMergeAtOnce和一層最多容許的段數setSegmentsPerTier。

對於一次普通的合併,首先計算一個“budget”。如果index超過了這個budget,排列所有段按照字節大小從大到小的順序。找出最小cost的段。段的cost結合skew,總段大小以及pct刪除回收計算。越小的Skew,越小的段總大小和更多的刪除空間回收的段是cost最低的,也是最適合合併的。

TieredMergePolicymp2 = new TieredMergePolicy();

mp2.setMaxMergeAtOnce(10);// 允許一次合併的段數

mp2.setMaxMergeAtOnceExplicit(30);

mp2.setSegmentsPerTier(10);// 一層最多容許的段數

mp2.setMaxMergedSegmentMB(5*1024);// default: 5G


多core的時候

多core 如果同一時間進行core 切換,會導致內存、cpu壓力過大,可以擴展Solr代碼,限制最多同時core切換的執行個數。保證不會出現高load或者高cpu 風險。

應用較高安全

最後不低於2個結點工作,並且最好2個結點是跨機器的。
offline與online切換的時候,如果數據量不是很多,可以考慮index與search合一,如果數據量較大,超過5000w的時候,建議index
offline或者search結點之外的其他結點上執行index

cache參數配置

如果更新很頻繁,導致commit和reopen頻繁,如果可以的話,關閉cache.
如果訪問中依賴cache提示性能,那麼最好關閉cache warm,no facet 需求
或者開開啓cache warm  有facet需要,對fieldvalue cache很依賴的話。
實時更新的話,通常document cache命中率比較低,完全可以不開啓這個配置

reopen 和commit

如果可以的話,主磁盤索引,不參入segment合併,新的索引段走不同的目錄。並且reopen的時候,主索引的不變動。

commit與reopen異步化

有一部分數據如果不變動,可以考慮使用memory cache 或者locale cache 平衡性能和空間開銷,同時避免FGC

中間變量壓縮、單例化

所有查詢或者建索引過程中,儘量少創建對象,而通過set改變對象值,以及單例化,提升性能。一些較大中間變量,如果可以的話,採取一些整數壓縮

對象表示重定義
例如日期、地區、url、byte等一些對象,可以考慮差值、區位碼、可別部分、壓縮等結構,使得內存開銷降低間接使得內存使用率提高,獲得更好性能。

index與store 隔離
就是index發揮它的查詢性能,store發揮它的存儲、響應性能。
也就是不要將所有的內容都放在index中,儘量使得field的屬性stored=false

單一實例

自定義的分詞,務必使用單例。在索引期間複用單一的IndexWriter實例 ,只定義一個document對象和field對象,然後通過set方式賦值。

search優化

對按指定域排序
展示的時候,對於數字的建議,展示最近1或者3個月數據。例如價格,防止作弊
dump或者建索引的時候,對數字加以上下界檢測,及早發現數字本身正確,而實際意義不合理的數據

排序可變性
默認的排序務必有自己的相關參數,並且平衡各方面需求。
排序要變,但是不至於大的波動。排序的細節不公開,但是排序的結果可以解釋的清楚。

線上線下
有些分值可以線下完成,有些分值線上完成。看需求。

多域查詢
如果默認查詢多個域,不妨將多個域合成一個域,只差一個域

高亮
高亮可以在solr裏面或者外面執行的,不一定在solr裏面執行,可以在solr之外執行
同理,分詞可以在線下執行好,dump只執行簡單的空格分詞即可

統計
facet統計可以先上與線下相結合,不一定完全依賴線上即時計數。

主動搜索
主動搜索查詢串務必嚴格處理,既要去無效查詢串,也要適當擴展查詢串。
明確查詢路徑和hit=0的對應處理。



發佈了39 篇原創文章 · 獲贊 7 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章