5

這可能看起來像一個非常基本的問題,但如果我從S3下載文件而另一個進程正在更新文件,是否需要擔心要獲取不完整的文件?從文件更新時從AWS S3下載

示例:一個200MB的CSV文件。用戶A開始用1Mbps的200MB新內容更新文件。 16秒後,用戶B開始以200Mbps下載文件。用戶B是否獲得了原始文件的全部200MB,或者用戶B是否獲得了〜2MB的用戶A的更改而沒有其他內容?

回答

9

用戶B獲取全部200MB的原始文件。

原因是:在S3

PUT操作都是原子。技術上沒有「修改」一個對象的東西。當一個對象被覆蓋時實際發生的事情是該對象被替換爲,而另一個對象具有相同的密鑰。但是,直到新的(覆蓋)對象完整地上傳並且成功地,原始對象纔會被實際替換......即使這樣,被覆蓋的對象在技術上也沒有「消失」 - 它只被替換爲存儲桶的索引,以便將來的請求將服務於新對象。 (新服務對象實際上被記錄爲不能保證總是立即發生,與上傳新對象(立即可供下載)相反,覆蓋現有對象最終是一致的,這意味着它是可能的 - 但是不太可能 - 在您上傳一個對象後很短的時間內,舊副本仍然可以用於後續請求)。

但是,當您覆蓋一個對象,並且桶上未啓用版本控制時,儘管密鑰相同,但舊對象和新對象實際上是獨立存儲在S3中的。舊對象現在不再被存儲桶的索引引用,因此您不再爲存儲它而收取費用,它很快就會從S3的後備存儲中清除。它實際上沒有記錄多久後發生這種情況......但是(tl; dr)覆蓋當前正在下載的對象應該不會引起任何意想不到的副作用。

更新到單個鍵是原子的。例如,如果您將PUT添加到現有密鑰,則後續讀取可能會返回舊數據或更新數據,但不會寫入損壞或部分數據。

http://docs.aws.amazon.com/AmazonS3/latest/dev/Introduction.html#ConsistencyModel

+0

你能引用源? – PhilT

+2

@PhilT完成。如果「後續」讀取可能會返回新舊對象,則可以推斷正在進行的下載將繼續返回舊對象。當您「覆蓋」一個對象時,只有允許S3的前端從存儲中獲取對象的索引記錄被覆蓋。新對象分開編寫,索引更新,然後清除舊對象(除非啓用桶版本控制,在這種情況下,它也會保留)。因此,覆蓋是邏輯的,而不是物理的,索引中的短暫複製延遲是最終一致性的原因。 –

+0

完美!謝謝。 – PhilT