ruby-on-rails - 如何并行处理大多数作业但序列化一个子集?

标签 ruby-on-rails asynchronous concurrency architecture parallel-processing

我们从供应商那里获得对我们的 Web 应用程序的并发回调,我们怀疑它导致我们丢失更新,因为它们是在不同的机器上同时处理的。

我们需要序列化这些调用的处理 当且仅当它们影响相同的用户记录。

我的一位同事提出了一个 AWS Kinesis 流,我们使用用户 ID 作为分区键。这个想法是相同的分区键将记录放在同一个分片中。每个分片只由一个 worker 处理,不会有并发问题。通过设计,将保证不并行处理属于同一用户的记录。这个解决方案可以扩展并解决问题,但它至少会让我们倒退一个冲刺。

我们正在努力寻找一种可以更快部署的解决方案。

到目前为止我们讨论过的其他解决方案:

  • 简单地延迟回调的处理,可能是随机的时间。在这种情况下,仍然有可能(尽管可能性较小)多个工作人员同时处理同一用户的作业。
  • 任何排队系统都有一个缺陷,即我们要么仅限于一名 worker ,要么面临并行处理的风险,或者与 (1) 中概述的相同。

  • 我们在使用 MySQL 的 Rails 堆栈上,并且更喜欢 AWS 作为我们的解决方案。

    这个问题有没有比切换到 Kinesis 产生更快结果的解决方案?

    最佳答案

    您基本上是在寻找命名分布式锁,以便您可以强制执行串行处理。

    如果您在 AWS 中,您可以使用每个 customerId 将记录推送到 DynamoDB。

    每次获得要处理的记录时,请进行一致读取(请参阅此处的并发部分:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/APISummary.html)。

    如果存在记录,请将您的消息添加到其中(一致写入)。让正在处理的进程在完成后进行读取,如果有消息附加到 dynamo 记录,则按顺序处理它们。最后删除记录。

    您可能会遇到竞争条件,因此您需要进行退避并重试。我不知道你的音量是多少,但 Dynamo 的速度非常快,所以超过几次的几率很小。如果失败太多次,您可能必须将内容转储到错误队列中进行清理,但这不太可能。特别是如果您的音量允许您考虑诸如消息处理中的任意延迟之类的解决方案。

    关于ruby-on-rails - 如何并行处理大多数作业但序列化一个子集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29820739/

    相关文章:

    ruby-on-rails - 我应该如何*有意*停止迁移?

    javascript - 如何在应用程序后台每 X 秒记录一次控制台日志?

    java - 多少线程安全是太多了?

    multithreading - 同步执行上下文的不确定性(又名 `parasitic`)

    sql - 为什么缺少主键/唯一键会导致更新插入时出现死锁问题?

    mysql - 如何控制 Rails 4 中连接记录的顺序

    javascript - Gmaps4Rails Gmaps.triggerOldOnload 方法未找到 JavaScript 错误

    javascript - $.when.apply($, someArray) 是做什么的?

    python - 创建 "client in server"用于向服务器发送请求

    javascript - 如何解决 Rails 应用中 Google map 自动完成功能中的此问题?