将顺序程序扩展为队列链

时间:2016-05-01 21:40:52

标签: python amazon-sqs

我正在尝试扩展按以下步骤工作的导出系统:

  • 从MySQL数据库中获取大量记录。每条记录都是一个拥有他们想要的地址和产品的人。
  • 进行外部API调用以验证每个API的地址信息。
  • 进行内部API调用,以获取每条记录上有关产品的商店和价格信息。
  • 以特定格式为每条记录分配标识符,每种导出都有所不同。
  • 将所有数据转储到文件中,压缩并通过电子邮件发送。

到目前为止,所有这些都发生在一个单片python脚本中,它开始显示它的年龄。由于一次导出的记录数量增加了大约10倍,因此脚本占用大量内存,整个导出过程很慢,因为所有步骤都是阻塞和顺序的。

为了加快流程并使其可扩展,我希望将工作分配到一系列SQS队列中。前4个步骤非常简单:

  • 选择器队列 - 接收请求,决定将导出哪些记录。使用export_idrecord_id在验证者队列中为每个人创建一个msg。
  • Verifier队列 - 获取记录的id,进行API调用以验证其地址。使用export_idrecord_id
  • 在价格队列中创建一个消息
  • 价格队列 - 获取记录的ID,进行API调用以获取价格并将其附加到记录中。使用export_idrecord_id
  • 在分配器队列中创建一个msg
  • Assigner队列 - 获取记录的id,为其分配顺序导出ID。使用export_idrecord_id
  • 在转储器队列中创建一个msg
  • Dumper queue - ???

到目前为止,这一切都很好,花花公子。工作是并行化的,我们可以添加更多的工人到最需要他们的步骤。

我对如何添加流程的最后一步感到难过?

直到现在所有的队列都已经(适当地)愚蠢。他们获得一个消息,执行一个动作并传递它。在当前脚本中,当我们到达最后一步时,程序可以确定所有记录的所有先前步骤都已完成,并且是时候转储信息了。我应该如何在分布式案例中复制这个?

以下是我能想到的选项:

  • 转储器队列只是将它的传入消息保存在数据库表中,直到它获得一个标记为“FINAL”的消息,然后它转储所有export_id的消息。这使得最终的msg成为单点故障。如果同时处理多个导出,则无法保证msgs的顺序,因此决定哪个msg是最终的很容易失败。

  • 在每个步骤中传递expected_totalcount,并且转储器队列等待,直到获得足够的消息。这将导致转储程序队列被阻塞,其他导出将不得不等待,直到收到先前启动的导出的所有消息。如果消息丢失,还必须以某种方式处理可能无限的等待时间。

上述选项似乎都不够好。我还有其他选择吗?

在高级别,一致性比此问题中的可用性更重要。因此导出的文件可能会迟到,但它们应该是正确的。

消息延迟原因

如评论中所述:

  • 内部/外部API响应时间可能会有所不同。难以量化。
  • 如果同时处理多个导出,则来自一个导出的消息可能会滞后或者在队列中以混合顺序接收。

2 个答案:

答案 0 :(得分:0)

看起来您可以执行以下操作:

  • Assigner

    • 从分配器队列中读取并分配正确的ID
    • 以批量形式打包数据并将其上传到S3。
    • 将S3的路径发送到Dumper队列
  • Dumper读取批量并以批量形式将其转储到数据库

答案 1 :(得分:0)

您可能应该使用缓存而不是队列。