文章目錄
- 4.1.1 資料庫產品表分析:
- 4.1.2 Lucene索引程式:
- 4.1.3 Lucene索引庫:
- 4.3.1 權重計算
- 4.3.2 索引自動化更新
說是電子商務搜尋結構描述方案,其實就是lucene.net的應用,公司廟小,人少,也就自己平時看看,以前做過一點例子,這樣就被拉上去寫架構方案了。我這個懶惰的傢伙,在網上瘋狂的搜集搜尋結構描述方面的東西,因為做做架構,暫時沒寫代碼,每天就看人家部落格,結果兩個星期了才弄了個大概的草圖,這不清明節過後就要詳細方案了,現在只能把我的草圖分享一下,希望大家板磚伺候,悶在家裡鼓搗比較鬱悶啊,效率太低。
基於lucene的搜尋方案
一、 Lucene 簡介
Lucene是apache的一個頂級開源項目,由java實現的全文檢索索引引擎,能基於各種文檔格式的全文索引和檢索,包括word、pdf,不包括圖形類。
Lucene.net 是C#版的lucene 是由java的lucene翻譯過來的,也被apache列為開源項目對外發布,功能和java的基本一樣,但是由於缺乏良好的支援人員和社區活躍度,目前已被apache放入孵化器
Lucene寫入:源檔案經過analyzer處理,包括分詞,權重處理、產生document記錄,寫入儲存空間(硬碟或者記憶體)。
Lucene 讀出:對搜尋關鍵詞進行analyzer處理,包括分詞、權重、範圍匹配處理.源碼結構圖如下:
具體流程如:
資料流圖如下:
二、常用Recommendation Engine演算法問題
採用基於資料採礦的演算法來實現Recommendation Engine是各大電子商務網站、SNS社區最為常用的方法,Recommendation Engine常用Content-Based 推薦演算法及協同過濾演算法(Item-Based 、User-based)。但從實際應用來看,對於大部分中小型企業來說,要在電子商務系統完整採用以上演算法還有很大的難度。
1)、相對成熟、完整、現成的開源解決方案較少
粗略分來,目前與資料採礦及Recommendation Engine相關的開源項目主要有如下幾類:
資料採礦相關:主要包括Weka、R-Project、Knime、RapidMiner、Orange 等
文本挖掘相關:主要包括OpenNLP、LingPipe、FreeLing、GATE 、Carrot2 等,具體可以參考LingPipe’s Competition
Recommendation Engine相關:主要包括Apache Mahout、Duine framework、Singular Value Decomposition (SVD) ,其他包可以參考Open Source Collaborative Filtering Written in Java
搜尋引擎相關:Lucene、Solr、Sphinx、Hibernate Search等
2)、常用Recommendation Engine演算法相對複雜,入門門檻較高
3)、常用Recommendation Engine演算法效能較低,並不適合海量資料採礦
以上這些包或演算法,除了Lucene/Sor相對成熟外,大部分都還處於學術研究使用,並不能直接應用於互連網規模的資料採礦及Recommendation Engine引擎使用。
(以上都是基於java的,需要自己去研究實現,有很大難度)
備忘:除了分類尋找和主動搜尋,推薦系統也是使用者瀏覽商品的重要途徑,能協助使用者發現類似並感興趣的產品,增加商品的訪問量,將訪問者轉化為購買者,引導使用者購買。最終產生的價值是提升使用者購物體驗和使用者粘度,提高訂單量,如Amazon30%的訂單來自推薦系統。
採用Lucene實現Recommendation Engine的優勢
對很多眾多的中小型網站而言,由於開發能力有限,如果有能夠整合了搜尋、推薦一體化的解決方案,這樣的方案肯定大受歡迎。採用Lucene來實現Recommendation Engine具有如下優勢:
1)、Lucene 入門門檻較低,大部分網站的站內搜尋都採用了Lucene
2)、相對於協同過濾演算法,Lucene效能較高
3)、Lucene對Text Mining、相似性計算等相關演算法有很多現成方案
在開源的項目中,Mahout或者Duine Framework用於Recommendation Engine是相對完整的方案,尤其是Mahout 核心利用了Lucene,因此其架構很值得借鑒。只不過Mahout目前功能還不是很完整,直接用其實現電子商務網站的Recommendation Engine尚不是很成熟。只不過從Mahout實現可以看出採用Lucene實現Recommendation Engine是一種可行方案。
3、採用Lucene實現Recommendation Engine需要解決的核心問題
Lucene對於Text Mining較為擅長,在contrib包中提供了MoreLikeThis功能,可以較為容易實現Content-Based的推薦,但對於涉及使用者協同過濾行為的結果(所謂的Relevance Feedback),Lucene目前並沒有好的解決方案。需要在Lucene中內容相似演算法中加入使用者協同過濾行為對因素,將使用者協同過濾行為結果轉化為Lucene所支援的模型。
Recommendation Engine的資料來源
電子商務網站與Recommendation Engine相關典型的行為:
購買本商品的顧客還買過
瀏覽本商品的顧客還看過
瀏覽更多類似商品
喜歡此商品的人還喜歡
使用者對此商品的平均打分
因此基於Lucene實現Recommendation Engine主要要處理如下兩大類的資料
1)、內容相似性
例如:商品名稱、作者/譯者/製造商、商品類別、簡介、評論、使用者標籤、系統標籤
2)、使用者協同行為相似性
例如:打標籤、購買商品、點擊流、搜尋、推薦、收藏、打分、寫評論、問答、頁面停留時間、所在群組等等
5、實現方案
5.1、內容相似性 基於Lucene MoreLikeThis實現即可。
5.2、對使用者協同行為的處理
1)、使用者每一次協同行為都使用lucene來進行索引,每次行為一條記錄
2)、索引記錄中包含如下重要訊息:
商品名、商品id、商品類別、商品簡介、標籤等重要特徵值、使用者關聯線為的其他商品的特徵元素、商品縮圖地址、協同行為類型(購買、點擊、收藏、評分等)、Boost值(各協同行為在setBoost時候的權重值)
3)、對評分、收藏、點擊等協同行為以商品特徵值(標籤、標題、概要資訊)來表徵
4)、不同的協同行為類型(例如購買、評分、點擊)設定不同的值setBoost
5)、搜尋時候採用Lucene MoreLikeThis演算法,將使用者協同轉化為內容相似性
以上方案只是基於Lucene來實現Recommendation Engine最為簡單的實現方案,方案的準確度及細化方案以後再細說。
更為精細的實現,可以參考Mahout的演算法實現來最佳化。
其他搜尋引擎開源工具推薦:Sphinx,目前是基於出自俄羅斯的開源全文檢索搜尋引擎軟體Sphinx,單一索引最大可包含1億條記錄,在1千萬條記錄情況下的查詢速度為0.x秒(毫秒級)。Sphinx建立索引的速度為:建立100萬條記錄的索引只需3~4分鐘,建立1000萬條記錄的索引可以在50分鐘內完成,而只包含最新10萬條記錄的增量索引,重建一次只需幾十秒。
Sphinx 是一個基於 GPL 2 協議頒發的免費開源的全文檢索搜尋引擎.它是專門為更好的整合指令碼語言和SQL資料庫而設計的.當前內建的資料來源支援直接從串連到的 MySQL 或 PostgreSQL擷取資料, 或者你可以使用 XML 通道結構(XML pipe mechanism , 一種基於 Sphinx 可識別的特殊xml格式的索引通道)
基於LAMP架構的應用很廣泛,目前瞭解的商業應用有康盛的Discuz企業版。
、
三、手機之家的搜尋方案(參考用)
手機之家目前的Lucene應用,採用的是Lucene 2.4.1 + JDK 1.6(64 bit)的組合,運行在8 CPU, 32G記憶體的機器上,資料量超過3300萬條,未經處理資料檔案超過14G,每天需要支援超過35萬次的查詢,高峰時期QPS超過20。單看這些資料可能並沒有大的亮點,但它的重建和更新都是自動化完成,而且兩項任務可以同時運行,另一方面,在不影響服務可靠性的前提下,儘可能快地更新資料(如果兩者發生衝突,則優先保證可用性,延遲更新),其中的工作量還是非常大的。
PPT串連 http://www.slideshare.net/tangfl/lucene-1752150
在大規模的應用中,Lucene更適合用於狹義的“搜尋”,而不應當負責資料的儲存。我們看看Lucene的原始碼也可以知道,Document和Field的儲存效率是不夠好看的。手機之家的團隊也發現了這一點,他們的辦法是,用Lucene存放索引,用Memcache + Berkeley DB(Java Edition)負責儲存。這樣有兩個好處,一是減輕了Lucene的資料規模,提高了程式的效率;另一方面,這套系統也可以提供某些類似SQL的查詢功能。實際上,Lucene本身似乎也注意到了這個問題,在Store中新增了一個db的選項,其實也是利用的Berkeley DB。
在大規模應用中,Cache是非常重要的。PPT中也提到,可以在程式提供服務之前,進行幾次”預熱“搜尋,填充Searcher的Cache。據我們(銀杏搜尋)的經驗,也可以在應用程式中,再提供針對Document的Cache,這樣對效能有較大的改善。Lucene自己似乎也注意到了這個問題,在2.4版本中提供了Cache,並提供了一個LRU Cache實現。不過據我們測試,在極端情況下,這個Cache可能會突破大小限制,一路膨脹最後吃光記憶體,甚至從網路上找的許多LRU Cache實現在極端條件下都有可能出現這樣的問題,最終自己寫了一個LRU Cache,並修改多次,目前來看是穩定的。
在編寫Java服務程式的時候,記得設定退出的鉤子函數(RunTime.getRunTime.addShutdownHook)是一個非常好的習慣。許多Java程式員都沒有這種意識,或者有,也只是寫一個finalize函數,結果程式非正常退出時,可能造成某些外部資源的狀態不穩定。拿Lucene來說,之前的IndexWriter是預設autoCommit的,這樣每添加一條記錄,就提交一次,好處是如果中斷,則之前添加的記錄都是可用的,壞處則是,索引的速度非常低。在新版本中autoCommit預設為False,速度提升明顯(我們測試的結果是,提高了大約8倍),但如果中途異常退出,則前功盡棄。如果我們添加了退出的鉤子函數,捕獲到退出訊號則自動調用writer.close()方法,就可以避免這個問題。
目前的Lucene是相容JDK 1.4的,它的binary版本也是JDK1.4編譯的,如果對效能要求比較高,可以自行下載Lucene Source Code,用更新版本的JDK編譯出.jar檔案,據我測試,速度大約有30%的提升。
四、 XX網搜尋方案4.1 初步解決方案:
實現站內產品的分詞搜尋、推薦關鍵詞和簡單排序,定時自動更新,索引讀寫分離。
基於伺服器的搜尋壓力大,使用者的搜尋體驗不夠有好,初步解決方案目標是解決伺服器的搜尋壓力,實現初步的分詞搜尋,索引的自動定時維護。
4.1.1 資料庫產品表分析:
l 大類基表
l 產品分類擴充基表
l 品牌基表,品牌系列表基表
l 產品基表(主表)
l 顏色基表
產品基表的資料大概在8萬條左右,佔用空間40m左右,單表資料量相對來書還是比較小的。
4.1.2 Lucene索引程式:
通過lucene的索引程式將庫裡的資料讀入流,然後寫入lucene自訂的索引檔案,這個索引檔案不進行搜尋操作,需要完成後替換到搜尋索引。在建立索引的過程中進行分詞處理,分片語件採用eaglet開發的Apsara Distributed File System分片語件(已基於apache開源協議開源,進一步功能需要自己二次開發)。
4.1.3 Lucene索引庫:
基表的索引檔案大概在100m左右,分為寫入時的庫和搜尋時用的庫,寫入庫完成後併入搜尋庫,考慮到新索引合覆蓋就索引的瞬間可能產生的索引程式錯誤或者索引檔案損壞,在覆蓋的同時通過程式控制讓搜尋程式讀取寫索引裡的檔案。
l 搜尋處理services:基於產品庫的的搜尋,如品牌,分類,價格區間。搜尋程式依賴於介面,基於資料庫的搜尋和基於檔案的搜尋要按需要隨時切換。搜尋的同時需要利用分片語件分詞處理,對分詞後的結果進行檢索,資料庫檢索的暫時不做分詞處理。
l 查詢處理:查詢前景程式使用mvc,實現產品的分詞高亮顯示,按照類別分類查詢,品牌分類查詢,價格區間查詢。
4.2 第二步關鍵詞統計:
搜尋關鍵詞的搜集和搜尋的聯合處理,實現簡單的搜尋推薦功能。主要是對前台的搜尋索引鍵進行統計分析,並與搜尋的排序進行關聯,關鍵詞的處理和與主表的關聯索引方案等初步處理完成後再做完整解決方案。
4.3 第三步最佳化完善:
實現索引檔案的基於訊息的增量自動更新,權重計算,推薦產品計算研究,即時搜尋的研究。權重計算,需要重新開發自己的向量演算法引擎,考慮當中。
即時搜尋目前在學習當中。
4.3.1 權重計算
權重計算方法會將前台使用者的統計資料和產品庫進行關聯開發一套天天網產品的權重排序計算方法,以下演算法流程圖只是一個構思。
4.3.2 索引自動化更新
建立基於訊息機制的一個索引更新與維護機制。