簡體   English   中英

AWS S3 客戶端競爭條件解決方案

[英]AWS S3 client race condition solutions

我和我的團隊一直試圖解決的問題涉及多個 ec2 實例,每個實例都有自己獨立的並行訪問同一個 S3 存儲桶的權限。 當每個客戶端都嘗試在上述 s3 存儲桶中下載相同的文件時,此問題會作為競爭條件出現。 每個客戶端都試圖讀取文件,運行一些業務邏輯,然后刪除文件。 由於存在許多延遲機會,因此會出現競爭條件,並且多個實例最終會運行業務邏輯。

關於工程師如何使用他們的 s3 客戶端實現鎖定機制的一些建議將不勝感激。

我們集思廣益的方法:將 .lock 文件上傳到 s3 存儲桶,其中包含有關當前持有鎖的實例的信息。 當持有鎖的實例完成進程時,它會刪除它的鎖。 (上載鎖定文件時會出現問題 - 鎖定機制的競爭條件)。

嗯……您現在將與鎖定文件發生競爭狀況……多個節點將上傳相同的鎖定文件!

所以你需要一些更復雜的東西,因為 S3 沒有內置任何並發性,這可能很不方便。

解決這個問題的明顯方法是使用 SQS(簡單隊列服務)——這是為並發而構建的。

因此,在您的情況下,所有節點都連接到同一個隊列,等待隊列中的工作。 某些東西或其他東西會將元素添加到 s3 中需要處理的每個文件的隊列中。 其中一個節點將拾取隊列中的條目,處理文件,刪除文件並刪除隊列中的條目。

這樣你就不會得到多重處理,你會得到優雅的縮放等。

然而,突出的問題是首先掃描 s3 以將工作放入隊列中。 這可能是您遇到困難的地方。

我認為你有兩個選擇:

  1. 使用 lambda。 這是相當優雅的。 您可以將 lambda 配置為在將某些內容添加到 S3 時觸發。 然后,此 lambda 將注冊一個指向隊列中文件的指針,以供 ec2 實例處理。

    lambda 的問題是您的應用程序更加分散。 即,您不能只查看代碼的行為,還必須查看 lambda。 雖然我猜這個 lambda 並不是特別重量級的。

  2. 讓所有 ec2 實例監控 s3,但是當他們找到工作要做時,他們會將工作添加到 FIFO 隊列中。 這是來自 AWS 的一種相對較新的隊列類型,您可以在其中保證訂單並且只進行一次處理。 因此,您可以保證即使多個節點找到相同的 s3 文件,也只有一個節點會處理它。

如果您當前的設置和應用程序可行,我會考慮將事件配置到 S3 存儲桶,將消息發送到 SQS 隊列(例如,當文件上傳時),然后使用 ElasticBeanstalk Worker 環境來使用來自隊列的消息,以便根據您的應用程序處理這些文件。

工作環境文檔

如果您不想使用 AWS 特定技術(例如 SQS 或 lambdas),您有 2 個選項:

現有數據庫

如果您有一個可以利用的現有數據庫,您可以使用咨詢鎖(例如 Postgres 提供的),如下所示: 當一個進程想要處理文件時:

  1. 它首先檢查鎖是否可用。 如果沒有,它將不得不等待鎖定。
  2. 一旦它獲得鎖,它就可以做它需要的工作,包括刪除文件。
  3. 它最終釋放了鎖。

從概念上講,這與您提到的.lock文件設置非常相似。

使用外部服務

類似lockable的東西。 如果你使用 Python,你可以使用他們的Python 客戶端

$ pip install lockable-dev

from lockable import Lock

with Lock('my-lock-name'):
    #do stuff

如果你不使用 Python,你仍然可以使用他們的 HTTP 端點; 就像是

  1. curl https://api.lockable.dev/v1/acquire/my-s3-file-lock
  2. 處理文件
  3. curl https://api.lockable.dev/v1/release/my-s3-file-lock

我會嘗試將文件移動到暫存桶。 只有一個過程會成功,其他過程會失敗。 成功的拿下工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM