Amazon web services Amazon SQS唯一消息
我使用SQS作为视频编码的队列,希望确保每个视频只执行一个编码 SQS工作得很好,因为当消息排队时,它将仅由单个线程接收。但是,对于相同的视频/编码,可能会向队列发送多条消息,这意味着对于特定的“编码”队列,消息内容是相同的 是否仍然需要消除重复以确保对于特定队列,队列中的消息或从队列接收的消息是唯一的Amazon web services Amazon SQS唯一消息,amazon-web-services,amazon-sqs,Amazon Web Services,Amazon Sqs,我使用SQS作为视频编码的队列,希望确保每个视频只执行一个编码 SQS工作得很好,因为当消息排队时,它将仅由单个线程接收。但是,对于相同的视频/编码,可能会向队列发送多条消息,这意味着对于特定的“编码”队列,消息内容是相同的 是否仍然需要消除重复以确保对于特定队列,队列中的消息或从队列接收的消息是唯一的 我认为的一个选项是在消息发送时为每种编码类型创建一个新队列。因此,队列可以命名为类似于编码视频id,它只包含一条消息,我可以检查以确保队列不存在。唯一的“问题”是,可能会创建1000到10个这样
我认为的一个选项是在消息发送时为每种编码类型创建一个新队列。因此,队列可以命名为类似于
编码视频id
,它只包含一条消息,我可以检查以确保队列不存在。唯一的“问题”是,可能会创建1000到10个这样的队列 IMO,创建无限数量的队列,每个队列中只包含一条消息,这是一个非常糟糕的设计,即使从理论上讲是可行的
如果是我,我会尝试确保每个视频都有某种唯一的标识符,即使用户“双击”了流程按钮,这也是相同的
我想看一个系统,在这个系统中,具有唯一名称(如guid)的视频被上传到S3,消息被放入队列,线程从队列中拾取消息并进行编码,然后将视频写回不同的S3存储桶,但基本名称相同
在处理任何视频之前,我会首先检查“输出桶”,看看那里是否已经有编码的视频,以及匹配的名称,如果是-我会跳过重新处理并删除消息
如果所有操作都在EC2本地磁盘上运行(并且您没有使用S3),那么可以使用硬盘上的输入和输出目录执行相同的操作(但这将假定多台计算机没有执行处理)
重要的是要记住,即使用户只提交了一次,同样的消息也有可能通过SQS发送。这种情况虽然很少发生,但无论您设置什么系统,都需要确保如果/当您收到偶然的重复消息时,它不会破坏任何内容。无法确保消息在一个特定的环境中的唯一性n SQS队列,或者就此进行排序。另外,队列太多也不是一个好主意 在我看来,您需要向系统中添加另一个组件。某种元数据服务就足够了。它可以像这样工作:
- 创建编码任务时(在将其添加到SQS之前),可以将其写入元数据服务
- 当工作程序收到编码任务时,它将查询元数据服务以查看任务是否已经完成
- 当工作者完成编码任务时,它会在元数据服务中将该任务标记为已完成
希望这有帮助!:)您建议的解决方案是一个糟糕的设计,即使可能或不可能。以下是我解决问题的方法
我将使用一个数据库(可能是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))
- 目前它只支持两个地区(美国西部(俄勒冈州)和美国东部(俄亥俄州)地区)
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
{
班级计划
{