将n个文件并发合并为一个文件的算法



我正试图找到一个水平缩放的解决方案,在标题中描述的问题。

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

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

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

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

有什么可用的算法或设计模式?

一些细节:

  • 1000万个不同的输出文件
  • 每天500万条消息
  • 文件存储由第三方webservice提供,具有无限并发读/写
  • 消息顺序不重要
  • 一个消息只包含一个URL到一个文件(GUID作为它的名字)

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

选项1:从附加文件中分离下载。多个"下载"工作者:获取内容,计算位置,计算位置的哈希值,根据哈希值将内容放入写入队列。多个'writer' worker,每个worker消耗一个队列,按顺序处理队列,并保证没有其他writer将尝试更新相同的位置。您可能需要实现某种形式的一致哈希,以允许系统优雅地承受任意故障。

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

我看不出有什么问题。你可能忘了提到它。对于你所描述的问题,有一个很简单的解决办法。只需在工作节点池中以轮询或均衡的方式分发消息。每个worker将加载文件,解析并存储在第三方存储中。就是这样。

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

Edit:所以这是愚蠢的存储问题。在愚蠢的第三方存储之前必须有一些真正的存储层,提供"原子"追加和透明的压缩/解压缩。有一些构建可扩展存储的技术。看看著名的Dynamo论文。因为你的功能需求很窄,你可以很容易地围绕Riak的一些开源环实现编写自己的解决方案,使用第三方存储作为后端。

我将简单地描述一下基本原理。通过(一致的)哈希将目标空间划分为桶。然后为每个buck保留序列化器,它为您提供原子操作。在您的情况下,它是append和透明(de)压缩。序列化器保存状态并充当缓存。所以从外部看它就像没有锁

相关内容

最新更新