2016-03-10 39 views
1

我需要移動重命名AWS S3存儲中的對象。Amazon Web Services S3中的線程安全文件重命名

我發現的所有解決方案都需要複製後再刪除。然而,這兩個文件都存在很短的時間,我不認爲這是線程安全的。

有沒有辦法以線程安全的方式做到這一點?

代碼使用Java AWS SDK在Scala中。

編輯: 羅布,感謝您的答覆,我相信我明白,代碼正在做,但讓我覺得我問了錯誤的問題。

而不是特定的AWS功能,讓我用我正在嘗試完成的內容來描述它。

我有一個定期從外部接收文件的S3目錄。我有多個進程需要「處理」這些文件,並且每個文件只能處理一次。

在過去,作爲一種便宜的處理方式,我使用重命名來移動文件或將其標記爲處理。如果重命名成功,則該進程知道它擁有該文件並將繼續處理。如果因爲源文件不存在而失敗,那麼它會嘗試目錄中的下一個文件。

我所需要的是一種方式,最好是僅限於S3,這將允許多個進程在文件上工作,同時確保每個文件只處理一次。

在下面您的解決方案,因爲「發現」和「刪除」是分開的方法,並且刪除該文件不存在,並沒有失敗,我不知道我怎麼看這兩個過程不能簡單地(以最壞的情況)都與另一個完全一致。

文件移動可能是錯誤的解決方案,而我對AWS的經驗不足使我無法看到完成此任務的更好方法。

回答

0

不,這不是由S3 API

1

過去那樣處理這種廉價的方式支持的,我已經使用了重命名,以 無論是移動的文件或將其標記爲處理。如果重命名 成功,則該進程知道它'擁有'該文件,並且將繼續處理 。如果因爲源文件不存在而導致源文件不存在,則它會嘗試目錄中的下一個文件。

讓我首先指出,使用原子重命名爲線程獲取獨佔訪問來處理文件的方法起作用,但它確實存在使文件未處理的風險。想象一下,如果線程(或整個服務器)在重命名後死亡,會發生什麼情況。如果沒有一個可靠的方式來跟蹤哪些文件尚未完成並重試它們,您的系統將不會很有彈性。

正如您注意,S3沒有一個原子重命名操作,所以,你的願望你平時的技術不起作用。

S3有一個很好的「通知」功能,可以配置。就你而言,你可能希望在創建文件時得到通知。通知可以交付給SNS,SQS或Lambda。您可能需要SQS或Lambda。通過SQS,消息被添加到隊列中,您可以獲取線程並處理該文件。 SQS模型保證「至少一次」交付,並將重試交付,直到消息被刪除(或超出隊列年限)。如果不刪除時間是可重新配置的。請注意,SQS可能會多次發送相同的消息 - 它們在過度交付方面犯錯,而不是在傳遞消息。如果可以在很少的情況下對文件進行雙重處理,那麼這可能對您很有幫助。我們廣泛使用SQS隊列並很高興。

我不熟悉Lambda消息處理的詳細語義。

我建議你谷歌「S3事件通知」瞭解更多詳情。

原來的答覆原來的問題:

我不知道這個問題是「線程安全」 - 或許更多的「事務完整性」?

無論如何,你是正確的做一個S3「原子」重命名是不明顯的。我認爲你必須「挑選你的毒藥」 - 要麼你必須處理這樣一個事實,1)你同時擁有新舊版本,或者2)你有一段時間既沒有舊的也沒有新的副本。

在這兩種情況下,您需要處理的關鍵問題是堅持您正在執行重命名(直到重命名被確認爲完整)。如果在表示文件的某個數據庫中有一行,那麼您可以在那裏保存該狀態。以下假定您不想使用除S3之外的其他任何內容來保持狀態。

您將實際複製文件兩次,使用中間副本的臨時文件夾。你可以有單獨的線程來完成每一步(尋找要處理的文件),也可以有一個單獨的線程檢查各種條件並完成剩下的步驟。換句話說,您需要查找部分已完成的重命名(但該線程未能完成)並從中斷的地方找到。

對於這個例子,我們將從A重命名爲B並使用一個名爲tmp的臨時文件夾。

如果你更喜歡簡單有兩個副本:

1. Copy A to tmp/A-B (the file name has before and after names in it). 
2. Finding tmp/A-B: copy it to B. 
3. Finding tmp/A-B, A and B: delete A. 
4. Finding tmp/A-B, A is missing and B exists: delete tmp/A-B. 

如果你更喜歡簡單既無副本:

1. Copy A to tmp/A-B. 
2. Finding tmp/A-B and A: delete A. 
3. Finding tmp/A-B and A is missing and B is missing: copy tmp/A-B to B. 
4. Finding tmp/A-B and A is missing and B exists: delete tmp/A-B. 
+0

謝謝,我可能會問錯了問題。請參閱我上面的編輯。 –

+0

再次感謝。我會研究事件。我們有一個監視工作目錄中的文件的過程,所以如果它們太老了(一個線程死亡沒有完成或清理),我們會收到這個問題的通知。由於這應該是非常罕見的,手動將文件移回到目錄對我們來說是一個好的解決方案。 –