标准SQS AWS队列,检查是否有重复交付

时间:2018-09-12 23:55:18

标签: amazon-web-services aws-lambda amazon-sqs

AWS上的Standard SQS队列的文档说,它有时可能会发送两次消息。

什么是理想的检查方法?我基本上有一个lambda设置,该设置由进入队列的项目激活。对项目进行一些计算,然后将数据写回到数据库中。

在消息已经事先传递的情况下再次检查之前是否足以检查该数据是否已写入数据库?

还是有一种更好的方法?

反正有没有让FIFO队列输入到lambda中?

3 个答案:

答案 0 :(得分:0)

我遇到了类似的问题,并且能够通过验证dynamoDB中是否已经存在唯一消息标识符来解决此问题。如果已经存在,则不会处理数据。如果密钥尚不存在,则将其存储在发电机中。至此,您可以使用AWS dynamo数据库流执行通过AWS lambda用新密钥保存dynamo之后需要执行的任何处理。

答案 1 :(得分:0)

有以下几种选择

  1. 最明显的是关于在消息中具有一些唯一标识符,然后将其存储在某种持久性机制(最好是DynamoDB)中,以便在处理每条消息之前进行检查。使您知道此消息是否已被处理。如果这是您决定的路线,则可以将该标识符作为消息属性的一部分而不是消息正文的一部分,这样您就不必解析整个正文以查看它是否重复。
    • 优点:消息处理是实时的
    • 缺点:最终需要保留ID和重复数据删除的开销
  2. 第二个选择是使用FIFO队列,然后让调度的Lambda(使用AWS Cloudwatch Alarms)按指定的时间表轮询FIFO队列,如果存在消息,则对其进行处理
    • 优点:节省了持久保留ID和重复数据删除的开销
    • 缺点:不是实时的
  3. 第三种奇特的选择(只是因为您要求提供更高级的选择)是拥有2个SQS队列(1个标准队列和其他FIFO),并让消息生产者将消息放入两个SQS队列中。现在,您有基于标准队列的Lambda触发器,但是当调用Lambda时,请从FIFO队列中读取消息。这样,如果Lambda被重复消息触发,则对于该Lambda调用,FIFO队列中将没有任何内容,您无需进行任何处理
    • 优点:消息处理是实时的,您无需担心维护唯一ID的麻烦
    • 缺点:2个队列

答案 2 :(得分:0)

对于这样的问题,您可以尝试服务中的许多变通办法,例如检查重复的message_id或为此目的维护两个队列。所有这些似乎都是合法的,但会消耗更多的处理能力。一个好的解决方案是使用AWS SQS本身的内部功能。但是,仍然不足以满足我们的要求。下面提供了一些可用于此目的的方法。

  1. SQS标准队列+ Lambda +数据库

这是您建议的方法,我们将在数据库中检查已处理的message_id,并确保不要两次处理同一条消息。确保为message_id列添加索引,以加快检查速度。

  1. Message Publisher + SQS标准队列+ Lambda +数据库

在这里,您可以要求消息发布者确保不会将重复的消息发送到SQS。仅当您维护自己的发布服务时,才有可能。如果可以访问,这可能是理想的解决方案。

  1. SQS标准队列+ EC2 +数据库

您可以使用EC2实例而不是lambda,以便可以将已处理的message_id保存在EC2中。每当收到消息时,这将节省数据库I / O操作。缺点是您必须使用轮询和EC2成本,而不是使用Lambda。

  1. SQS FIFO队列+ Lambda(或EC2)+数据库+轮询

您可以使用FIFO队列并严格执行一次处理,以确保不会将重复的消息发送到SQS。这涉及Lambda(使用CloudWatch)或EC2实例轮询消息。这可能需要大量的性能,但是我们可以执行我们的要求。

到目前为止,lambda触发仅在SQS标准队列中受支持。因此,选择FIFO将不是一种选择。如果从实际角度来看,第二种选择将是理想的解决方案。这比将整个体系结构变成意大利面条要容易和干净得多。希望这会有所帮助。