1. 程式人生 > >為什麼使用solr----solr與Lucene比較及solr 的結構分析

為什麼使用solr----solr與Lucene比較及solr 的結構分析

原文連結:http://www.aboutyun.com/thread-7018-1-1.html本帖最後由 nettman 於 2014-2-28 22:46 編輯


可以帶著下面問題來閱讀: 1.搜尋為什麼使用solr? 2.一個索引越來越大,solr是如何應對的? 3.Solr是什麼,一句話描述? 4.solr比Lucene有什麼優勢?
一、Lucene與solr有什麼不一樣

首先Solr是基於Lucene做的,Lucene是一套資訊檢索工具包,但並不包含搜尋引擎系統,它包含了索引結構、讀寫索引工具、相關性工具、排序等功能,因此在使用Lucene時你仍需要關注搜尋引擎系統,例如資料獲取、解析、分詞等方面的東西。

而Solr的目標是打造一款企業級的搜尋引擎系統,因此它更接近於我們認識到的搜尋引擎系統,它是一個搜尋引擎服務,通過各種API可以讓你的應用使用搜索服務,而不需要將搜尋邏輯耦合在應用中。而且Solr可以根據配置檔案定義資料解析的方式,更像是一個搜尋框架,它也支援主從、熱換庫等操作。還添加了飄紅、facet等搜尋引擎常見功能的支援。

因而,Lucene使用上更加靈活,但是你需要自己處理搜素引擎系統架構,以及其他附加附加功能的實現。而Solr幫你做了更多,但是是一個處於高層的框架,Lucene很多新特性不能及時向上透傳,所以有時候可能發現需要一個功能,Lucene是支援的,但是Solr上已經看不到相關介面。

Lucene更像是一個SDK。 有完整的API族以及對應的實現。你可以利用這些在自己的應用裡實現高階查詢(基於倒排索引技術的),Lucene對單機或者桌面應用很實用很方便。但是Lucene,需要開發者自己維護索引檔案,在多機環境中備份同步索引檔案很是麻煩。於是,就有了Solr。 

而Solr是一個有HTTP介面的基於Lucene的查詢伺服器,封裝了很多Lucene細節。

solr ,更多是和nutch 的結合使用





-----------------------------------------------------------------------------------------------------------------------------------------------
二、solr 的結構分析



solr在lucene外邊做了一層厚厚的封裝,主要是為了簡化二次開發,提供了一些成熟的解決方案。
solr和solrCore
solr可以對多個core進行綜合管理,並接受請求選擇特定的一個或者多個core執行相關任務。下面來回答什麼是solr的core。 core從檔案結構的角度來看的話,主要包括一份索引(也可能還包括拼寫檢查的索引)、一堆配置檔案。最主要的配置檔案是:solrconfig.xml和schema.xml。solrconfig.xml從整體上對core進行了配置,例如索引的存放路徑、欄位的最大長度(maxFiedlLength)、寫鎖的超時時間(writeLockTimeout)、鎖型別(lockType)、是否壓縮索引(useCompoundFile)、記憶體索引緩衝區大小(ramBufferSizeMB)、合併因子(mergeFactor)、刪除策略、自動提交策略、快取設定等,它好比是一份組裝機器人的說明書,裡面詳細描述了各個部件(handler)的引數。schema.xml主要是對索引的配置,例如分詞器、欄位名稱+索引方法+儲存方式+分詞方式、唯一標識欄位等,它好比是機器人學習的學習方法,機器人主動或被動接受特定資料,按照配置轉化成索引,然後通過其部件(handler)展示出來,例如:search、moreLikeThis、spellCheck、factedSearcher等。 core從功能方面來說的話,主要是通過各種handler進行工作,這個在上文中也提及過。solr的功能之多讓我想到瑞士軍刀,看圖:
        常見的有:morelikeThis、search、 spellCheck、dataImport等。
然而不同的部件有複雜簡易之分,我們常見的searchHandler就比較複雜,他包括多個零件(component)。 多個component進行組合就可以完成特定的工作。(以下程式碼摘自:SearchHandler.java)
  1. for( SearchComponent c : components ) {
  2.           rb.setTimer( subt.sub( c.getName() ) );
  3.           c.process(rb);
  4.           rb.getTimer().stop();
  5.         }
複製程式碼 以上文字主要簡單白話了solr的core是個什麼東西!那麼solr怎麼控制這些core進行工作呢? 這個是檢索的目的是:檢索core1下的所有內容,並返回前10條。 solr通過request獲取requestPath,解析出對應的core名稱(這裡coreName=core1),然後獲取core例項(找到相應的機器人)。 然後解析出select指令,明確告訴core是進行檢索任務,任務的具體引數通過solrRequestParser進行解析。solrRequestParser可以看出是將url轉換成core識別指令的“翻譯器”。下面core就可以呼叫相應的handler執行任務了。 從外往裡看,solr可以看成是: solr Manager -> solr core -> handler -> component
簡單說說solr的分散式(version:solr3.5)
當一個索引越來越大,一個伺服器放不下了,怎麼辦? 當一個大索引的單次請求慢得想死,怎麼辦? 選擇分散式吧!他能將索引進行切分放到不同的伺服器上(shards),還可以將處理的計算壓力進行分攤。他會將各個shard上的結果進行合併,並“完美”的呈現給您! 然而、但是......solr的分散式並不完美。最主要的就是idf的計算問題。這個問題會在單個shard進行打分運算過程中就發生了,如果每個shard在計算過程中實時去其他shards去獲取df和文件總數,請求的消耗是不能忍受的。要解決這個問題就得在每個shard中實時儲存每個單詞的df和文件總數。
簡單說說solr的服務釋出方式和客戶端solr
solr部署在伺服器上,提供各種服務。服務釋出的方式主要是基於http協議的,傳輸資料格式為xml、json,不同開發語言都可以通過socket程式設計進行訪問。官方的java客戶端就是solrJ,他利用HttpClient進行客戶端開發。 我曾經毫無理由的懷疑過這種方式——如果我要用標準的webService,然後又不想改動太多原始碼,是不是還得通過slorJ做箇中間橋樑?是不是無緣無故的多了一次http請求?雖然有embedded!感覺就是solr的這層服務介面被http侵入得有點深。深入的研究後續跟進= =。
為什麼solr沒有multiSearcher?
lucene3.5中的multiSearcher已經過時了,取而代之的是multiReader。 If you are using MultiSearcher over IndexSearchers, please use MultiReader instead; this class does not properly handle certain kinds of queries. 從lucene早起版本開始,或者說是受資料庫思想的影響,會將資料按照某一性質進行劃分,放到不同的索引裡面。理由是便於管理、防止單一索引過大。如果需要同時檢索多個索引,自然就用到了multiSearcher。到了solr發現一個core中只能一份索引,於是糾結solr為什麼沒有multiSearcher?難道solr不擔心單一索引過大嗎?難道同時檢索多個索引就得使用它並不完善的distributedSearch嗎?當時這個思想一直影響了我對solr的好感。
現在“改革開發”的思想就是:在業務需求下,不支援對多個索引同時進行檢索。當單個索引的檢索壓力出現效率問題後,再考慮分散式檢索,將資料分發到不同的shards上。如果不是單次檢索的運算量瓶頸,而是併發量帶來的壓力,考慮使用負載均衡。這裡很類似於mongodb,併發壓力大作replSet,單庫太大做sharding。