簡體   English   中英

配置 AWS SQS/Lambda 觸發器以支持 1:1 策略以及最大並發實例數

[英]Configuring AWS SQS/Lambda trigger to honor both 1:1 policy as well as max concurrent instances

這里的 Java 8 使用 AWS Java SDK 編寫了一個 Java lambda,它應該響應發送到 SQS 隊列的消息而執行。

理想情況下,將為發送到 SQS 隊列的每條記錄調用/執行一個且只有一個 lambda 實例。 因此,如果將 5 條消息發送到隊列,將觸發 5 條 lambdas(或者 - 根據我的 lambda 配置 - 我可能會設置並發 lambdas 的最大數量,在這種情況下,我的期望是待處理/未使用的 SQS 消息將等待下一個可用的拉姆達)。

這不是硬性要求,只是理想。

我注意到在com.amazonaws.services.lambda.runtime.events.SqsEvent類中,有一個getRecords() : List<SQSMessage>方法讓我有點擔心。 對我來說,這意味着單個 lambda 實例每次執行可能會收到1 個以上的 SQS 消息,這又與我想要的行為背道而馳。

所以我想知道如果有配置LAMBDA觸發的方式,使得它永遠只能觸發一次每SQS隊列的消息,同時還表彰設置“LAMBDA並發實例的最大#”,使得信息在SQS等到了lambda准備好。 再舉一個例子,假設我將並發 Lambda 的最大數量設置為三 (3),並且 5 條消息同時發送到隊列中。 在這種情況下,我希望觸發 3 個 Lambda,每個處理 5 個排隊消息中的一個,5 個消息中的 2 個將等待這 3 個 Lambda 中的一個完成,以便另一個可以觸發並接收它們。

這是可能的嗎? 還是 Lambda 只是“決定”(?)以某種方式自行決定向給定的 Lambda 執行提交多少條消息? 如果是這樣,有人知道這是如何決定的嗎?

TL; 博士

正如@joseph 已經正確指出的那樣,您可以使用BatchSize設置為 1 的事件源映射。這將使getRecords()最多返回 1 SQSMessage 為了一次最多處理 1 條消息,您必須將 Lambda 函數的保留並發設置為 1。但是,正如也正確指出的,這對於標准SQS 隊列來說並不是最佳選擇。 事件源映射將遇到一些記錄到 CloudWatch Logs 的TooManyRequestsException: Rate Exceeded錯誤。

要在不依賴於 Lambda 函數節流的情況下使用適當的一次一條消息的順序處理模式,請使用 AWS 博客文章 [1] 中所述的 SQS FIFO 隊列。 它說:“總並發數等於或小於 SQS FIFO 隊列中唯一 MessageGroupId 的數量”。 也就是說,您可以為您的 SQS FIFO 隊列配置一個MessageGroupId ,以便:

  • 每個 SQS 隊列消息只觸發一次 Lambda(因為 batchSize = 1)
  • 同時還遵守恰好為 1 的“最大並發 Lambda 實例數”(因為並發計數 = #unique 消息組 ID = 1)

因此,唯一消息組 ID 的數量是最大值。 SQS FIFO 隊列的事件源映射的並發 Lambda 調用數。

更多信息

用於 Lambda 的 Java 庫

據我所知,AWS 提供了一組 POJO(例如庫aws-lambda-java-events 中的SQSEvent )[2],以便處理傳入的 SQS 事件 [3]。 SQS 事件由 Lambda 事件源映射傳遞並反序列化為給定的 POJO。 POJO SQSEvent的文檔也可從 JavaDoc.io [4] 獲得,源代碼可在 GitHub [5] 獲得。 getRecords()方法返回一個SQSMessage對象列表,因為 AWS Lambda 事件源映射確實可以提供 1 到 10 條 SQS 消息。

Lambda 事件源映射

事件源映射是使用特定於源類型的屬性創建和配置的。 當我們查看 SQS 集成時,我們必須只考慮 SQS 特定的屬性。 這些主要是: BatchSizeEventSourceArn 有關完整列表,請參閱 [6]。 如果屬性不適用於 SQS 源類型,則其描述以關鍵字(Streams)開頭。

如果要限制使用getRecords()檢索的 SQS 消息的數量,則必須設置BatchSize 默認值為 10。

Lambda 縮放

如文檔 [7] 中所述,Lambda 並發限制可用於限制由 Lambda 函數並發處理的 SQS 消息批次的數量。 但是,這不會阻止事件源映射調用 Lambda 函數。 至少,我找不到任何相反的官方消息來源 - 如果我錯了,請糾正我。

也就是說,如果大量使用 SQS 隊列,則會拋出大量限制錯誤(代碼 429)。 可以通過指示事件源按順序處理消息來克服這個問題。 這是通過使用 Amazon SQS FIFO 事件源實現的。 這是一個相當新的功能。 [8]

概括

總而言之,我建議:

  • 使用具有 FIFO 類型而不是標准類型的 SQS 隊列
  • 使用 BatchSize 設置為 1 的事件源映射
  • 在所有 SQS SendMessage API 調用中對MessageGroupId屬性使用相同的值 [9]
  • 熟悉 SQS FIFO 隊列和標准隊列之間的差異 [10][11] - 包括價格差異 [12]
  • 不必設置保留並發,因為它由 FIFO 隊列的事件源映射處理

參考

[1] https://aws.amazon.com/blogs/compute/new-for-aws-lambda-sqs-fifo-as-an-event-source/
[2] https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-create-package.html#with-sqs-example-deployment-pkg-java
[3] https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html
[4] https://javadoc.io/static/com.amazonaws/aws-lambda-java-events/2.2.2/com/amazonaws/services/lambda/runtime/events/SQSEvent.html
[5] https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events /SQSEvent.java
[6] https://docs.aws.amazon.com/lambda/latest/dg/API_CreateEventSourceMapping.html#API_CreateEventSourceMapping_RequestBody
[7] https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html
[8] https://aws.amazon.com/about-aws/whats-new/2019/11/aws-lambda-supports-amazon-sqs-fifo-event-source/?nc1=h_ls
[9] https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
[10] https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html
[11] https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html#FIFO-queues-moving
[12] https://aws.amazon.com/sqs/pricing/?nc1=h_ls

Getrecords 是獲取源記錄從 1 到最大可能的函數。 批量大小由lambda 事件源映射控制 如果您將其設置為 1,您的 lambda 將始終收到一個只有一個元素的記錄數組。

處理消息的 lambda 數取決於您為 lambda 設置的並發限制。 請記住,如果您允許的並發 lambda 數小於您在任何時候擁有的 sqs 消息數,您可能會在 Cloudwatch 指標中看到許多限制異常。 如果這是所需的行為,您可以忽略它們。

此外,您還可以增加 sqs 配置的可見性超時,以確保同一消息在已被一個 lambda 處理時不會傳送到另一個 lambda。

暫無
暫無

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

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