我们从供应商那里获得对我们的 Web 应用程序的并发回调,我们怀疑它导致我们丢失更新,因为它们是在不同的机器上同时处理的。
我们需要序列化这些调用的处理 当且仅当它们影响相同的用户记录。
我的一位同事提出了一个 AWS Kinesis 流,我们使用用户 ID 作为分区键。这个想法是相同的分区键将记录放在同一个分片中。每个分片只由一个 worker 处理,不会有并发问题。通过设计,将保证不并行处理属于同一用户的记录。这个解决方案可以扩展并解决问题,但它至少会让我们倒退一个冲刺。
我们正在努力寻找一种可以更快部署的解决方案。
到目前为止我们讨论过的其他解决方案:
我们在使用 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/