Amazon web services Amazon SQS唯一消息

Amazon web services Amazon SQS唯一消息,amazon-web-services,amazon-sqs,Amazon Web Services,Amazon Sqs,我使用SQS作为视频编码的队列,希望确保每个视频只执行一个编码 SQS工作得很好,因为当消息排队时,它将仅由单个线程接收。但是,对于相同的视频/编码,可能会向队列发送多条消息,这意味着对于特定的“编码”队列,消息内容是相同的 是否仍然需要消除重复以确保对于特定队列,队列中的消息或从队列接收的消息是唯一的 我认为的一个选项是在消息发送时为每种编码类型创建一个新队列。因此,队列可以命名为类似于编码视频id,它只包含一条消息,我可以检查以确保队列不存在。唯一的“问题”是,可能会创建1000到10个这样

我使用SQS作为视频编码的队列,希望确保每个视频只执行一个编码

SQS工作得很好,因为当消息排队时,它将仅由单个线程接收。但是,对于相同的视频/编码,可能会向队列发送多条消息,这意味着对于特定的“编码”队列,消息内容是相同的

是否仍然需要消除重复以确保对于特定队列,队列中的消息或从队列接收的消息是唯一的


我认为的一个选项是在消息发送时为每种编码类型创建一个新队列。因此,队列可以命名为类似于
编码视频id
,它只包含一条消息,我可以检查以确保队列不存在。唯一的“问题”是,可能会创建1000到10个这样的队列

IMO,创建无限数量的队列,每个队列中只包含一条消息,这是一个非常糟糕的设计,即使从理论上讲是可行的

如果是我,我会尝试确保每个视频都有某种唯一的标识符,即使用户“双击”了流程按钮,这也是相同的

我想看一个系统,在这个系统中,具有唯一名称(如guid)的视频被上传到S3,消息被放入队列,线程从队列中拾取消息并进行编码,然后将视频写回不同的S3存储桶,但基本名称相同

在处理任何视频之前,我会首先检查“输出桶”,看看那里是否已经有编码的视频,以及匹配的名称,如果是-我会跳过重新处理并删除消息

如果所有操作都在EC2本地磁盘上运行(并且您没有使用S3),那么可以使用硬盘上的输入和输出目录执行相同的操作(但这将假定多台计算机没有执行处理)


重要的是要记住,即使用户只提交了一次,同样的消息也有可能通过SQS发送。这种情况虽然很少发生,但无论您设置什么系统,都需要确保如果/当您收到偶然的重复消息时,它不会破坏任何内容。

无法确保消息在一个特定的环境中的唯一性n SQS队列,或者就此进行排序。另外,队列太多也不是一个好主意

在我看来,您需要向系统中添加另一个组件。某种元数据服务就足够了。它可以像这样工作:

  • 创建编码任务时(在将其添加到SQS之前),可以将其写入元数据服务
  • 当工作程序收到编码任务时,它将查询元数据服务以查看任务是否已经完成
  • 当工作者完成编码任务时,它会在元数据服务中将该任务标记为已完成
如果将这些编码作业的输出上载到S3,则可以有效地将S3本身用作元数据服务。如果每个视频都有唯一的名称/id,则可以使用此唯一id的键将输出保存在S3中。或者将其设置为S3元数据键值(这将使文件更难找到,因为您不能只查询S3元数据服务)。然后,当工作人员收到编码任务时,它将检查文件是否已经存在于S3上,在这种情况下,它将从SQS中删除消息并跳过任务

如果不将输出保存到S3,可能需要使用某种数据库。Dynamo DB可能在速度和成本方面有所帮助


希望这有帮助!:)

您建议的解决方案是一个糟糕的设计,即使可能或不可能。以下是我解决问题的方法


我将使用一个数据库(可能是DynamoDB)根据视频的编码类型存储一个唯一的id,我将添加一个名为status的列。一旦用户单击convert按钮,首先,我将检查数据库。如果项目不可用,将向数据库推送一条状态为“Converting”的新记录。然后将工作推入SQS。处理工作负载后,将数据库的状态更改为“已完成”。如果用户再次单击转换按钮,则会根据数据库中的状态变量显示结果。

有一种方法,可以在从队列中获取数据后仅检查唯一消息。我将在下面进行解释

假设您经常向单个SQS队列添加随机消息(不考虑任何id或任何内容)。逻辑是在从队列接收消息时使用的

在创建ReceiveMessageRequest对象时,您可以指定AttributeName。因此,向请求对象添加“ApproxiateReceiveCount”属性。这将获取“ApproxiateReceiveCount”值以及从SQS队列获取的每条消息

现在,对于第一次读取的消息,“ExtErraseCeVeCuNT”是1,否则这个值将大于1。因此,每次读取Sqs时只能考虑那些中介。只需通过设置“Max NoMeNoof消息”限制每次读取的最大消息数。属性,以确保每次读取时不会获得巨大的有效负载(有效负载的每个64 KB块被记为1个请求)

我知道,FIFO队列在某些情况下会做得更好。但是,它几乎没有限制-

  • 它的吞吐量有限(每秒只有300个事务(TPS))
  • 目前它只支持两个地区(美国西部(俄勒冈州)和美国东部(俄亥俄州)地区)
请找到下面解释逻辑的C代码-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Amazon.SQS;
using Amazon.SQS.Model;

namespace DriverDataPooler1
{
    class Program
    {
        AmazonSQSClient objClient = new AmazonSQSClient
                ("<AWSAccessKeyId>", "<AWSSecretAccessKey>", Amazon.RegionEndpoint.APSouth1);
        //Create New SQS Queue
        CreateQueueResponse queueResponse = new CreateQueueResponse();
        ListQueuesResponse objqueuesResponseList = new ListQueuesResponse();

        // Declare the request and response objects
        ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
        ReceiveMessageResponse receiveMessageResponse = new ReceiveMessageResponse();

        static void Main(string[] args)
        {
            Program p1 = new Program();
            p1.getQueueData();
        }

        public void getQueueData(){

            objqueuesResponseList = objClient.ListQueues(new ListQueuesRequest());
            List<String> QueueList = objqueuesResponseList.QueueUrls;



            // Receive Message from SQS Queue
            if (QueueList.Any())
            {
                // I am only considering the first queue here as I have only one SQS queue
                receiveMessageRequest.QueueUrl = QueueList[0];
                receiveMessageRequest.WaitTimeSeconds = 20;

                //You can limit t6he number of messages to decrease the mayload amount (depends on the size of each message) 
                receiveMessageRequest.MaxNumberOfMessages = 10;
                receiveMessageRequest.AttributeNames = new List<string>() { "ApproximateReceiveCount" };
                receiveMessageResponse = objClient.ReceiveMessage(receiveMessageRequest);
                List<Message> result = receiveMessageResponse.Messages;
                if (result.Any())
                {
                    foreach (Message res in result)
                    {
                        // Checking for the messages that are read for the first time
                        if (Int16.Parse(res.Attributes["ApproximateReceiveCount"]) == 1)

                            // Process you messages here 
                            Console.WriteLine(res.Body);
                    }
                }
                else
                {
                    Console.WriteLine("You have no new messages in your SQS");
                }
            }
            else
            {
                Console.WriteLine("You have no available SQS");
            }
            Console.ReadKey();

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用Amazon.SQS;
使用Amazon.SQS.Model;
命名空间驱动程序DataPooler1
{
班级计划
{