2013-10-07 42 views
1

我有一個分佈式應用程序;也就是說,我在多臺計算機上運行同步進程,與中央數據庫進行交談並訪問網絡文件共享。在分佈式系統中鎖定文件

此過程從網絡文件共享(通過CIFS)中選取一個集合文件,對這些文件運行轉換算法並將輸出複製回網絡文件共享。

我需要鎖定輸入文件,以便其他服務器(運行相同的進程)不會在相同的文件上工作。爲了爭辯,假設我的描述過於簡單化,並且鎖定是絕對必要的。

這裏是我提出的解決方案和一些想法。

1)使用機會鎖(oplocks)。此解決方案僅使用文件系統來鎖定文件。這裏的問題是,我們必須嘗試獲取鎖以確定鎖是否存在。這似乎是網絡重定向器協商鎖定可能會很昂貴。關於這一點的好處是可以創建oplock,以便在發生錯誤時自行刪除。

2)使用數據庫應用鎖(通過sp_getapplock)。這似乎會更快,但現在我們正在使用數據庫來鎖定文件系統。此外,數據庫應用程序鎖定可以通過事務或會話來確定範圍,這意味着如果我想堅持以後再發布應用程序鎖定,則必須堅持連接。目前,我們正在使用連接池,這將不得不改變,這可能是一個更大的談話本身。這種方法的好處是,如果我們失去與服務器的連接,鎖將被清理乾淨。當然,這意味着如果我們失去了與數據庫的連接,而不是網絡文件共享,那麼當我們仍在處理輸入文件時,鎖會消失。

3)創建一個數據庫表和存儲過程來表示我想要鎖定的項目。這個過程非常簡單。這當然是潛在的網絡錯誤。如果由於某種原因,數據庫變得無法訪問,鎖將保持有效。然後,我們需要推導出一些算法來在以後清理這個問題。

什麼是最好的解決方案,爲什麼?答案不限於上面提到的那些。

回答

1

對於您的情況,您應該使用共享模式鎖定。這正是他們所做的。

Oplocks不會達到你想要的 - 一個oplock不是一個鎖,並且不會阻止任何人做任何事情。它是讓客戶端機器知道是否有人訪問文件的通知機制。這是通過「打破」你的oplock傳遞給機器的,但這不是通向應用層(即代碼)的方式 - 它只是向客戶機操作系統生成一條消息,告訴它使其緩存失效從服務器複製並重新獲取。

請參閱MSDN這裏:

的另一進程打開對您持有的機會鎖定一個文件會發生什麼情況的解釋是在這裏:

但重要的一點是,oplocks不會阻止其他進程打開文件,它們只是允許客戶端計算機之間的協調。因此,oplock不會在應用程序級別鎖定文件 - 它們是網絡文件系統堆棧用於實現緩存的網絡協議的一項功能。它們並不真正用於應用程序。


既然你是在windows編程合適的解決方案似乎是共享模式鎖,即與SHARE_DENY_READ|SHARE_DENY_WRITE|SHARE_DENY_DELETE打開該文件。

如果CIFS服務器不支持共享模式鎖定,您可能會考慮使用flock()類型鎖定。 (以傳統的Unix技術命名)。

如果您正在處理xyz.xml請創建一個名爲xyz.xml.lock的文件(使用CREATE_NEW模式,這樣您就不會破壞現有的文件)。完成後,將其刪除。如果由於文件已經存在而無法創建文件,那意味着另一個進程正在處理它。將信息寫入鎖定文件對於調試非常有用,例如服務器名稱和PID,這可能很有用。您還必須有一些清理廢棄鎖定文件的方法,因爲這些文件不會自動發生。

如果CIFS是例如複製系統,那麼數據庫鎖定可能是合適的,因此鎖定不會在整個系統中以原子方式發生。否則,我會堅持使用文件系統,因爲只有一件事會出錯。

+0

本,謝謝你的回覆。你在這裏告訴我的關於oplocks似乎不同意MSDN中「網絡I/O」部分的內容。此外,聽起來你的意思是說SHARE _...標誌與oplocks相反,而MSDN則討論了這些標誌如何指導網絡重定向器如何處理oplocks。謝謝你指示我去羊羣。我沒有考慮到這一點,並會考慮它。 –

+0

@PhillipScottGivens,擴展答案。從應用程序的角度來看,Oplock不是鎖 - 它們是允許客戶機網絡堆棧實現緩存的實現細節。對於您的情況,如果服務器支持,則應使用共享模式鎖定。這*完全是他們所做的。 – Ben

+0

謝謝你的跟進。再次,您講述了與微軟不同的故事。從他們寫的內容來看,我的印象是從應用程序中看不到oplock。它們是由遠程機器上的內核級文件系統驅動程序爲您創建的。無論它們是否獨佔,是否處理緩存,或者其他因素由文件共享標誌,文件訪問標誌和文件選項標誌決定。如果你不同意,請給我一個支持你的職位的鏈接? –