3

我正在尝试为标题中描述的问题找到一个水平扩展的解决方案。

对问题的更详细解释是:从消息队列 Web 服务中,读取包含上传到某处文件的 URL 的消息,下载文件,对其进行解析,并将其内容附加到位置取决于内容的文件中.

由于队列中的消息量很大(假设每秒连续 100 条消息),如果由多个工作人员执行并发处理,如果没有对文件的受控访问,则可能会丢失数据。

一个相关的特定信息是,在一批消息中,两条消息不太可能针对同一个目标文件(假设 1% 的消息会发生这种情况,分布均匀),以及处理一个消息的速度消息及其文件的速度略高于从队列中读取消息的速度,从而大大降低了发生冲突的可能性。

如果概率非常低,丢失一些数据可能是可以接受的,但我没有确切的数字。

有哪些可用的算法或设计模式?

一些细节:

  • 1000 万个不同的输出文件
  • 每天 500 万条消息
  • 文件存储由第三方网络服务提供,具有无限并发读/写
  • 消息顺序不重要
  • 消息仅包含文件的 URL(以 GUID 作为其名称)
4

2 回答 2

1

由于您可以在任意数量的工作人员之间任意扩展下载和附加的基本工作,因此这里的关键问题似乎是如何保证一次只发生一个文件更新。实现这一目标的一些方法:-

选项 1:从附件中拆分下载。 多个“下载”工作人员:获取内容、计算位置、计算位置的哈希值、根据哈希值将内容放入写入队列。多个“编写器”工作人员,每个使用一个队列,按顺序处理队列,保证没有其他编写器会尝试更新同一位置。您可能需要实现某种形式的一致散列,以使系统能够优雅地承受任意故障。

选项2:创建一个单独的系统来锁定 多个worker,每个worker下载内容,计算位置,在辅助系统(数据库,文件系统,内存分布式缓存)中获取位置锁,执行附加操作,释放锁。本质上,这变成了一个分布式锁问题。

于 2014-07-10T05:42:35.517 回答
1

我不明白有什么问题。你可能忘了提到它。对于您描述的问题,有非常简单的解决方案。只需以循环或平衡方式在工作节点池中分发消息。每个工作人员将加载文件,解析并存储在第三方存储中。就这样。

寻找一些(分布式)消息队列解决方案,例如RabitMQ

编辑:所以事实证明这是愚蠢的存储问题。在愚蠢的第三方存储之前必须有一些真正的存储层,它提供“原子”附加和透明压缩/解压缩。有用于构建可扩展存储的技术。看看著名的Dynamo 纸。因为您的功能要求非常狭窄,您可以轻松地围绕一些开源环实现编写自己的解决方案,如来自Riak的Riak Core ,并使用第三方存储作为后端。

我将简要描述基本原理。您通过(一致的)散列将目标空间划分为存储桶。然后,您为每个 bucked 保留序列化程序,为您提供原子操作。在您的情况下,它是append透明的(去)压缩。序列化器保持状态并且也用作缓存。所以它看起来像从外面没有锁。

于 2014-07-10T06:32:53.627 回答