2015-12-20 33 views
1

我正在尋求什麼是設計最好的辦法建議 -AWS - 希望將多個文件上傳到S3,只有當所有上傳觸發lambda函數

使用案例

我想將多個文件放入S3中​​。一旦所有文件都成功保存,我想觸發一個lambda函數來做其他工作。

幼稚的做法

我快到這一問題的方法是通過保存在迪納摩的記錄,其中包含一個唯一的標識符和記錄,我會爲要在S3中存在的鍵被上傳沿總數。

一個基本的實現將採取我現有的lambda函數,該函數在我的S3存儲桶被寫入時隨時調用,並手動檢查是否所有其他文件都已保存。

Lambda函數會知道(查看Dynamo以確定我們正在查找的內容)並查詢S3以查看其他文件是否在其中。如果是這樣,請使用SNS觸發其他將執行其他工作的lambda 。

編輯:另一種方法是讓我的客戶端程序將文件放到S3中負責直接調用其他lambda函數,因爲它在技術上知道所有文件何時上傳。這種方法的問題是我不希望這是客戶端程序的責任......我希望客戶端程序不關心。一旦它上傳了文件,它應該能夠退出。

思考

我不認爲這是一個好主意。主要是因爲Lambda函數應該是輕量級的,並且在Lambda函數內輪詢數據庫以獲取所有上傳文件的S3密鑰,然後在S3中檢查它們是否存在 - 每次這樣做似乎是貧民區和非常重複的。

什麼是更好的方法?我在想像使用SWF的東西,但我不確定這是否對我的解決方案過度殺傷,或者如果它甚至會讓我做我想做的事情。該文檔也沒有顯示真實的「示例」。這只是一個沒有太多步驟指導的討論(也許我正在尋找錯誤的位置)。

編輯針對mbaird的建議如下─

選項1(SNS)這是我會去。這很簡單,並沒有真正違反單一責任原則。也就是說,客戶端上傳文件併發送通知(通過SNS)其工作已完成。因此這基本上是選項1的另一個「實現」。客戶端進行服務調用,在這種情況下,導致表格更新與SNS通知(選項1)相比, 。此更新將觸發Lambda函數,而不是通知。這不是一個糟糕的解決方案,但我更喜歡使用SNS進行通信,而不是依賴數據庫的能力(在這種情況下是Dynamo流)來調用Lambda函數。在任何情況下,我都在使用AWS技術,並與他們的產品(Lambda函數,SNS等)耦合,但是我覺得依靠像Dynamo流這樣的東西使它更緊密的耦合。對於我的使用案例來說,並不是真正的巨大擔憂,但仍然感到骯髒; D

選項3與S3觸發器我的關注點是競爭條件的可能性。例如,如果客戶端正在同時上傳多個文件(想到幾個異步上傳會隨着文件大小的變化而立即啓動),那麼如果兩個文件幾乎同時完成上傳,以及兩個或多個Lambda函數(或者我們使用的任何實現)查詢Dynamo並獲取N作爲完成的上傳(而不是N和N + 1)?現在,即使最後的結果應該是N + 2,每一個都會給N加1!Nooooooooooo!

所以選項1獲勝。

+0

選項1絕對是最優雅的解決方案。我很高興你會這樣做。如果您使用DynamoDB Atomic Counters,則選項3中不應存在競爭條件,並檢查更新的返回結果而不是執行單獨的查詢。我試圖通過鏈接到原子計數器文檔來解答我的答案。 –

回答

2

如果您不希望客戶端程序直接負責調用Lambda函數,那麼它會好嗎如果它做了一些更通用的東西?

選項1:(SNS)如果只是通知SNS主題已完成一批S3上傳,該怎麼辦?您可以將您的Lambda功能訂閱到該SNS主題。

選項2 :(DynamoDB Streams)如果只是使用屬性record.allFilesUploaded = true更新DynamoDB記錄會怎麼樣?您可以使用您的Lambda功能trigger off the DynamoDB stream。由於您已經通過客戶端創建了DynamoDB記錄,因此這似乎是一種非常簡單的方法,可以將批量上傳標記爲完整,而無需編寫關於接下來需要進行的操作的知識代碼。然後,Lambda函數可以檢查「allFilesUploaded」屬性,而不必在每次調用文件時都去S3。

或者,請勿在所有文件上傳完成之前插入DynamoDB記錄,然後您的Lambda函數才能觸發正在創建的新記錄。

方案三:(繼續使用S3觸發)如果客戶端程序無法從它目前的工作方式,然後,而不是列出所有S3文件,並將它們在DynamoDB比較列表每次的改變出現新文件,只需通過atomic counter更新DynamoDB記錄即可。然後將結果值與文件列表的大小進行比較。一旦這些值相同,您就知道所有文件都已上傳。不利的一面是,您需要在DynamoDB表上配置足夠的容量來處理所有更新,這將增加您的成本。

另外,我同意你的觀點,SWF對於這項任務來說是過度的。

+0

添加評論到我原來的帖子關於你的建議。標記爲答案。我很感謝你寫這篇文章 - 這非常有幫助。 – Beebunny