我正在尝试找到标题中描述的问题的水平扩展解决方案。
问题的更详细解释是:从消息队列Web服务,读取包含URL的消息到上传到的文件,下载文件,解析它,并将其内容附加到位置依赖的文件关于内容。
由于队列中有大量消息(假设每秒连续100条消息),如果多个工作人员执行并发处理,如果没有对文件的受控访问,数据可能会丢失。
相关的一个特定信息是,在一批消息中,两条消息不可能用于同一目标文件(假设1%的消息会出现这种情况,均匀分布)和速度处理消息并且其文件略高于从队列中读取消息的速度,从而降低了发生碰撞的可能性。
如果概率非常低,那么丢失一些数据是可以接受的,但我没有确切的数字。
有哪些可用的算法或设计模式?
一些细节:
答案 0 :(得分:1)
由于您可以在任意数量的工作人员中扩展下载和任意追加的基本工作,因此这里的关键问题似乎是如何保证一次只发生一次文件更新。实现这一目标的一些方法: -
选项1:从附加中拆分下载。 多个下载' worker:获取内容,计算位置,计算位置的哈希值,根据哈希将内容放入编写器队列。 多个作家'每个工作者使用一个队列,按顺序处理该队列,并保证其他编写者不会尝试更新同一位置。您可能需要实现某种形式的consistent hashing以允许系统优雅地存在任意故障。
选项2:创建一个单独的锁定系统 多个工作人员,每个人下载内容,计算位置,锁定二级系统中的位置(数据库,文件系统,内存中分布式缓存),执行追加操作,释放锁定。基本上这会成为distributed lock问题。
答案 1 :(得分:1)
我不知道捕获的是什么。你可能忘了提起它。对于您描述的问题,有一个非常简单的解决方案。只需以循环或平衡的方式在工作节点池中分发消息。每个工作人员都将加载文件,解析并存储在第三方存储中。这就是全部。
查找一些(分布式)消息队列解决方案,例如RabitMQ。
修改:事实证明这是一个愚蠢的存储问题。在愚蠢的第三方存储器前面必须有一些真正的存储层,它提供了" atomic"附加和透明的压缩/解压缩。存在用于构建可扩展存储的技术。看看着名的Dynamo paper。由于您的功能要求非常狭窄,因此您可以轻松地在Riak Core中围绕某些开源环实施编写自己的解决方案Riak,并将第三方存储用作后端。
我将简要介绍基本原理。您可以通过(一致)散列将目标空间划分为存储区。然后为每个为您提供原子操作的bucked保留 serializer 。在您的情况下,它是append
和透明(de)压缩。 序列化程序保持状态,也可用作缓存。所以它看起来像是从外面锁定。