2013-08-27 22 views
4

我使用的Lucene.net 3.0.3和AzureDirectory 2.0.4937.26631我從NuGet(在NuGet中稱爲Lucene.Net.Store.Azure)安裝。如何使AzureDirectory和Lucene.net具有並行IndexWriters?

azuredirectory.codeplex.com狀態的項目描述「更具體的:你可以有1..1工作者角色添加文檔到索引,和1..1搜索webroles想要搜索的目錄以近乎實時的。」 (強調增加)暗示可能有多個工作者角色並行寫入索引。但是,當我嘗試這樣做時,我得到了許多「鎖定超時:[email protected]」。例外。

我的代碼遵循AzureDirectory文檔(azuredirectory.codeplex.com/documentation)中給出的示例。我的代碼大致(簡化的問題)。

var dbEntities = // Load database entities here 
var docFactory = // Create class that builds lucene documents from dbEntities 
var account = // get the CloudStorageAccount 
var directory = new AzureDirectory(account, "<my container name>"); 
using(var writer = new IndexWriter(directory, new StandardAnalyzer(Version.LUCENE_30), createEvenIfExists, IndexWriter.MaxFieldLength.UNLIMITED)) 
{ 
    foreach(var entity in entities) 
    { 
     writer.AddDocument(docFactory.CreateDocument(entity)); 
    } 
} 

當按順序運行時,此代碼正常工作。但是,如果我在多個線程/工作者上並行運行相同的代碼。我得到很多「鎖定超時:[email protected]。」例外:

[Lucene.Net.Store.LockObtainFailedException: Lock obtain timed out: [email protected]] 
    at Lucene.Net.Store.Lock.Obtain(Int64 lockWaitTimeout) in d:\Lucene.Net\FullRepo\trunk\src\core\Store\Lock.cs:line 83 
    at Lucene.Net.Index.IndexWriter.Init(Directory d, Analyzer a, Boolean create, IndexDeletionPolicy deletionPolicy, Int32 maxFieldLength, IndexingChain indexingChain, IndexCommit commit) in d:\Lucene.Net\FullRepo\trunk\src\core\Index\IndexWriter.cs:line 1228 
    at Lucene.Net.Index.IndexWriter..ctor(Directory d, Analyzer a, Boolean create, MaxFieldLength mfl) in d:\Lucene.Net\FullRepo\trunk\src\core\Index\IndexWriter.cs:line 1018 

據我所知,「write.lock」文件是在Blob存儲中創建文件時,文件包含文本「wrote.lock」持有鎖。我從我的搜索中看到,用戶遇到了write.lock問題沒有得到清理。這似乎不是我的問題,因爲我可以在順序運行時獲得相同的代碼以正確工作,並在此情況下清除鎖定文件。

我在AzureDirectory文檔(azuredirectory.codeplex.com/documentation)中看到「索引一次只能由一個進程更新,因此通過索引角色推送所有添加/更新/刪除操作是有意義的。」但是,這沒有任何意義,因爲您創建的任何角色都應該有多個實例,因此會有多個實例並行寫入索引。此外,項目描述直接指出:「您可以有1..N個工作人員將文檔添加到索引。」注意它表示「一個」索引,而不是索引碎片。

問:

所以,是該項目的描述只是?或者實際上有一種方法可以讓多個IndexWriters並行地添加到索引中?我無法在API中看到任何內容來實現這一點。如果可能,請提供一個代碼片段,說明如何使用AzureDirectory「並有1..N個角色將文檔添加到索引」。

+0

我不明白用snide評論的倒票,然後刪除評論而不添加更具建設性的評論。這是一個有效的問題,因爲幾乎沒有關於AzureDirectory的在線信息,而且我沒有看到任何直接解決此問題的信息。從來沒有,我會試圖增加這個問題,更清楚地說明爲什麼這是一個有效的問題。 –

+1

+1我認爲這也是一個有效的問題。 –

回答

1

最高效的方式做到這一點是...

1)使用生產者/消費者設計模式

  • 有了這個,你可以有線程/任務x量與每個獨立作家寫作該指數
  • 你可以從數據庫中

2)對於大的索引生產者/消費者PATT閱讀消費者的X量(即線程/任務)恩應該產生單獨的索引。例如,如果我有4個編寫者構建4個索引,那麼我使用Lucene API將它們合併起來。

3)之後,在硬盤上有一個很好的索引。使用AzureDirectory的最後一步是使用Lucene目錄。複製命令,將索引從FSDirectory(硬盤驅動器)複製到Azure目錄。

  • 這是重要的,因爲AzureDirectory內部在Azure Blob存儲使用元數據屬性,以確定「最後更新指紋」索引
  • AzureDirectory還會壓縮索引,上傳之前...這是我喜歡它的原因因爲我可以使用並行線程將其壓縮到硬盤驅動器上,然後將其發送到Azure Blob存儲器之前的硬盤驅動器步驟。我改變AzureDirectory的實現,因爲它在內存中的一切,這樣做,對於一個20G的指標並不好:)

我已經使用這個兩個IaaS的/ PaaS產品在Azure和這個偉大工程。請記住,(我之前在帖子中提到過)AzureDirectory在我看來不是「企業」或「嚴肅的生產」準備...有些事情如:網絡重試,上傳大型索引,壓縮大型索引需要先解決我可以稱它爲「生產準備」。如果可以,請使用IaaS Azure產品,然後您不需要Azure Directory,並使用vanilla FSDirectory構建/顯示索引。

+0

關於2,那麼Lucene.net/AzureDirectory不直接支持多個作者?老實說,我的項目沒有時間花在這些問題上。我正在尋找更多開箱即用的解決方案。關於3,我真的需要能夠在未來重建Azure中的索引,我不能要求我的客戶端能夠在本地執行此操作,尤其是當所有數據都在SqlAzure中時。 –

+0

@JeffWalkerCodeRanger我建議使用Azure IaaS VM產品,然後設置它多一點,但你可以本地使用Lucene.NET。 AzureDirectory不支持多個編寫器:http://azuredirectory.codeplex.com/documentation(「索引一次只能由一個進程更新,因此通過索引角色推送所有添加/更新/刪除操作是有意義的。顯而易見的方法是創建一個Azure隊列,將一組對象流提供給一個工作者角色索引,並維護索引更新。「) –

+0

@JeffWalkerCodeRanger#3你可以絕對重建索引,只需要一個工作人員角色執行此操作並將其推送到Azure Blob帳戶。我上面概述的方法在多個索引編寫器(即大型/超大型Worker Role VM)中可以在本地驅動器上使用多個線程..build索引,並將其推送到Azure Blob存儲。不知道爲什麼這會阻止您重建索引...您可以按照設定的時間表重建索引,使其可以配置(即工作人員角色ping一個數據庫並檢查設置),隊列等。 –