Lucene Hack之通過縮小搜尋結果集來提升效能載,作者佚名)

來源:互聯網
上載者:User
一、緣起
    Lucene在索引檔案上G之後的搜尋效能下降很嚴重,隨便跑個搜尋就要上0.x秒。如果是單線程搜尋那麼效能尚可,總可以在0.x秒返回結果,如果是Web式的多線程訪問,由於Lucene的內部機制導致資料被大量載入記憶體,用完後立即丟棄,隨之引起JVM頻繁GC,效能極其低下,1-10秒的長串連比比皆是。這也是世人為之詬病的Lucene應用瓶頸問題,那麼是否有解決方案呢?

二、思路
    我們來觀察Google, Baidu的搜尋,有一個總體的感覺就是搜尋結果多的關鍵詞耗時比較少,結果少的關鍵詞耗時反而多,且結果多的時候會說“約******個結果”。隱士猜測Google, Baidu的演算法是找到前n個結果後停止掃描索引,根據前n個結果來推斷總共有多少個結果,此猜想可由Google, Baidu翻頁限制而得到部分驗證。
再看Lucene,其Hits.length()返回的總是精確的結果,如果可以讓Lucene也返回模糊的結果,那麼索引檔案就算是10G也可以輕鬆應對了。

三、探索
    隱士帶著這個問題訪名山、覓高人,可惜沒有找到前人的成果,可能是隱士走的路不夠勤,如有類似的解決方案,隱士不吝賜教。
無奈之下,隱士詳細研究了Lucene 2.1.0源碼,準備重新發明輪子。
一般來說大多數搜尋應用中的Query都會落在BooleanQuery上,隱士就拿它開刀。一路看來,BooleanScorer2裡的一個method吸引了隱士,代碼如下:

 

代碼
  1. public void score(HitCollector hc) throws IOException {   
  2.   if (countingSumScorer == null) {   
  3.     initCountingSumScorer();   
  4.   }   
  5.   while (countingSumScorer.next()) {   
  6.     hc.collect(countingSumScorer.doc(), score());   
  7.   }   
  8. }   

    在while迴圈裡嵌入寫日誌代碼可證結果集有多大,此處就迴圈了多少次。countingSumScorer.next()的意思是找到下一個符合boolean規則的document,找到後放入HitCollector,這HitCollector後面會換個馬甲放在大家熟悉的Hits裡面。

    如果可以在這個while迴圈裡嵌一個break,到一定數量就break出來,效能提升將相當明顯。這個代碼相當簡單,果然大幅提高了效能,帶來的副作用是結果不太准,這個可以通過調整業務模型、邏輯來修正。畢竟這是一條提升Lucene效能的有效方法。

    細細想來,正是由於這個break會導致結果集大的關鍵詞提前出來,搜尋時間少,結果集小的關鍵詞不可避免會走完整個索引,相應的搜尋時間會長一點。

四、效果
    由於具體內嵌程式碼的過程極其繁瑣,隱士將在第二回詳細講解。這第一回先來個Big picture。
曆盡千辛萬苦,隱士終於搞定了這套程式,效果可以從隱士做的視頻搜尋http://so.mdbchina.com/video/%E7%BE%8E%E5%A5%B3看出。

    這個關鍵詞“美女”可以找到18萬個視頻,平均0.5秒返回結果,現在用上了新演算法,只要0.06x秒返回結果,而且返回結果足夠好了,估算的8.5萬個結果雖然離18萬有很大差距,不過由於是估算的,差2-3倍應屬可以接受的。
由演算法的特性可知,while裡面的hc.collect總可以在常量時間內完成,迴圈次數又是<=常量,該演算法的時間複雜度只和BooleanQuery的複雜程度相關,和索引檔案大小以及命中的Document在索引檔案內的分布密度沒有關係,因為BooleanQuery的複雜程度決定了countingSumScorer.next()需要經過多少次判斷、多少次讀取索引檔案,countingSumScorer.next()正是整個演算法中耗時不定的部分。

    現在這個視頻搜尋的索引檔案接近3G,熱門關鍵詞可以在0.0x秒返回結果,隱士相信即使以後索引檔案上到10G,依然可以在0.0x秒返回結果。

(註:這個視頻搜尋實際使用效果會打折扣,因為後台索引也在這台機器上,以後會分伺服器,現在暫時在一起。)

=======佐證=======

Q: 如何看到前 1000 個結果以外的其他結果?

A: 針對某一個查詢,即使匹配項超過 1000 個,Google 也只提供 1000 個最相關的搜尋結果。(由於結果估算方面的差異,我們顯示的結果偶爾可能會稍低於 1000。)我們努力為您提供高效的搜尋體驗,讓您無需滾動到前十個列表之後。我們也理解,某些使用者想要查看的結果可能不止 1000 個,但這並非普遍情況,而且為每個使用者都提供這些結果會極大地增加我們的系統負擔。

//這裡看出,越少的返回結果對伺服器壓力越小,而且足夠滿足99.99%的使用者需求,而使用者如果沒有找到有用的資訊,唯一的方法是增加相關的關鍵字形成查詢組合。所以上文的出發是正確的。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.