2009-06-03 186 views
12

我們正在爲企業Web應用程序設計搜索體系結構。我們將爲此使用Lucene.net。索引不會很大(大約100,000個文檔),但搜索服務必須始終保持最新狀態。將一直有新的文件添加到索引和併發搜索。 由於我們必須爲搜索系統提供高可用性,因此我們有兩臺應用程序服務器公開WCF服務以執行搜索和索引(服務的副本在每個服務器中運行)。服務器然後使用lucene.net API訪問索引。跨多個應用程序服務器同步Lucene.net索引

問題是,保持索引始終同步的最佳解決方案是什麼?我們已經考慮了幾種選擇:

  • 使用索引和一個服務器 具有第二服務器訪問通過SMB的 指標:沒有做不到的,因爲我們有 失敗 情況的單點;

  • 爲兩臺服務器建立索引,實質上每次編寫索引兩次:可能性很差,並且可能會出現異步。服務器1索引正常,服務器2耗盡磁盤空間或任何東西;

  • 使用SOLR或KATTA來包裝對索引的訪問:nope,我們不能在服務器上運行tomcat或類似服務器,我們只有IIS。我發現這可以通過Lucene(JdbcDirectory模塊)的Java版本來完成,但是我找不到Lucene.net的任何類似的東西。即使這意味着小的性能下降,我們也會選擇這個選項,因爲它可以徹底解決併發問題,並與mininum開發同步。

  • 使用Lucene.net DistributedSearch contrib模塊:我無法用文檔記錄關於此的單個鏈接。我甚至不知道通過查看代碼的代碼是什麼,但在我看來,它實際上將索引拆分到多臺機器上,這不是我們想要的。如果索引變大,可能需要一段時間,並且在這段時間內,我們將會成爲rsync和朋友,在兩臺服務器之間來回拷貝索引:返回腐敗或不一致的數據給客戶,所以我們不得不制定一些我們不想要的特別鎖定策略。

我知道這是一個複雜的問題,但我相信很多人都面對過它。歡迎任何幫助!

回答

6

看來最好的解決方案是將兩臺服務器上的文檔編入索引的索引副本。

如果您擔心索引在一臺服務器上成功並且在另一臺服務器上失敗,那麼您需要跟蹤每臺服務器的成功/失敗情況,以便一旦出現問題就可以重新嘗試失敗的文檔已解決。此跟蹤將在Lucene之外完成,無論您使用哪種系統將文檔編入索引到Lucene。根據索引完整性的重要性,您可能還必須從所使用的任何負載均衡器中刪除發生故障的服務器,直到問題得到解決並且索引已重新處理任何未完成的文檔。

+0

肖恩,這是目前我們的候選人選項。我同意你和它的看法,這似乎是最爲抉擇的選擇。我還試圖找到JdbcDirectory的源代碼,以查看.NET + SQL服務器的端口是否可行。 將問題保持開放一段時間,看看是否有新的方法出現,否則將接受此答案。 – 2009-06-03 12:44:45

+0

我查了一次同樣的事情。這似乎不值得付出努力,因爲存在一堆與DB事務相關的東西,這些東西並不是微不足道的。也有使用JDBCDirectory的東西降低速度的抱怨。源文件在Compass項目中 - http://svn.compass-project.org/svn/compass/trunk/src/main/src/org/apache/lucene/store/jdbc/ – 2009-06-03 22:39:04

1

+1對於肖恩卡彭特的回答。在兩臺服務器上建立索引似乎是最安全和最安全的選擇。

如果您索引的文檔比較複雜(Word/PDF和排序),您可以在單臺服務器上執行一些預處理,然後將其提供給索引服務器,以節省一些處理時間。

我以前使用的解決方案涉及在一臺服務器上創建索引塊,然後使用IndexWriter.AddIndexesNoOptimizersync添加到搜索服務器並將塊合併到每個索引中。您可以每5分鐘創建一個新塊或每當它達到一定的大小時創建一個新塊。如果您不必擁有絕對最新的索引,這可能是您的一個解決方案。

1

在java世界中,我們通過將MQ放在索引前面解決了這個問題。插入僅在從隊列中拉出的bean成功時完成,否則它只是回滾它所花費的任何操作,在文檔上標記爲待處理,並且稍後再次嘗試

1

我知道這是一個老問題,但我剛碰到它,想給我的2美分給其他人尋找多服務器實施建議。

爲什麼不將索引文件保存在共享的NAS文件夾上?與您在考慮的數據庫中存儲索引有什麼不同?數據庫可以複製以實現高可用性,因此可以成爲NAS!

我會配置負載均衡器後面的兩個應用程序服務器。任何索引請求都會將索引文件編入NAS中機器特定的文件夾中。也就是說,NAS上的索引將與您的應用服務器一樣多。當搜索請求進入時,您將使用Lucene進行多索引搜索。 Lucene構建了(MultiSearcher)內置的功能,並且性能仍然非常出色。

0

我們保持同步,我們的負載平衡服務器的方式,每一個都有自己的Lucene的副本,是有一些其他的服務器上的任務,運行每5分鐘指揮每個負載平衡服務器來更新他們的索引一定的時間戳。

例如,任務發送的'12 /二千○十三分之一12時間戳:35:02.423' 的所有負載平衡的服務器(任務被提交經由查詢字符串的時間戳到網頁每個負載平衡網站上),那麼每個服務器都使用該時間戳來查詢數據庫,以獲取自上次更新到該時間戳以來發生的所有更新,並更新其本地Lucene索引。

每臺服務器還將時間戳存儲在數據庫中,以便知道每臺服務器上次更新的時間。因此,如果服務器脫機,當它恢復聯機狀態時,下次收到時間戳命令時,它將抓取它在脫機時錯過的所有更新。