我有~8000个文件,磁盘上有〜6TB数据。每个文件都包含一个键值对列表,我希望将这些值合并到一个排序的键值对列表中(例如,如果键A出现在两个文件中,则合并文件包含键A一次,该键包含两个文件中的所有值。)
我已经在Python [k-way merge中的单个主机上为单个核心实现了此gist - 请参阅this thread以获得有关该过程的直观概述]。我现在希望将这项工作分配给多个没有共享内存但可以共享网络访问权限的主机。
我需要排序的密钥空间绝对是巨大的,大约26 ^ 24,但绝大多数密钥都不存在于数据中(因此为每个工作人员提供一组密钥没有意义关心自己)。
其他人是否有任何想法如何实现分布式k-way合并算法?这让我觉得完全不平凡,但可能会有一些我看不到的低悬的果实。其他人可以提供的任何指示都将非常感激。
备注
计算设置是可参数化的。我在两个计算集群上工作,每个计算集群允许我同时使用~10-1000个节点,每个节点有12-24个核心和~120GB RAM。这些机器在他们被要求后的某个不确定的时间上线。网络通信通过TCP进行。磁盘是带有AFS文件系统的SSD,存储空间很大。
此外,我在任何给定时间使用简单的Python包big-read从8,000个文件中的每一个只读取n
行到RAM中,因此对#34进行RAM管理;外部排序"已经易于处理......
高度相关:K-way与stxxl合并。
答案 0 :(得分:1)
首先需要按键对8000个文件中的每个文件进行排序,还是按密钥对它们进行排序?如果8000首先需要按键排序,那么初始阶段将受CPU限制。这个文件排序的初始阶段可以并行完成(和多线程,如gnu排序)。在此之后,在合并步骤期间,该过程通常变为文件I / O绑定,但是如果具有SSD的文件I / O可以独立完成,则合并阶段也可以并行完成,使用SSD组。最终,生成单个排序文件的最终合并将是文件I / O绑定,并且尝试并行实现此方法没有任何优势。
答案 1 :(得分:1)
这是一个已经解决的问题。大多数mapreduce框架(例如Hadoop)都会进行分布式排序。最好的将配备逻辑来检测故障机器,取出它们并重做它们的工作。 (当您大规模使用大型分布式系统时,补偿机器故障非常重要。)只需找到一个好的框架并使用它,而不是重新发明轮子。
至于他们如何排序,我理解标准方法是合并。首先,你正在发放看起来像是“#34;排序这个块”的大块工作。"然后你开始分发看起来像的工作块,"将这些块合并在一起。"当您要合并的块不适合单台计算机时,会出现棘手的问题。然后你需要采取一组块,并找出分区的位置,然后合并碎片。我不知道他们是如何实现这一目标的。我最好的袖口想法是采取类似于每千个元素的子选择,对其进行排序,对其进行分区,并告诉每台机器保存完整的数据,将数据集切割成块,以及发送数据的人为了合并。
然而,一旦完成,你最终会得到一组有序的机器,每台机器都有一个有序的数据部分,在它们之间你有完整的数据全部排序。
重要事项:在处理大型分布式数据集时,避免在任何地方造成瓶颈非常重要。隐含或明确。您从分布式数据开始。您以分布式方式处理它。你最终得到了分布式数据。总是
答案 2 :(得分:1)
分布式排序/合并与单个主机上的排序/合并非常相似。基本思想是在不同的主机之间拆分文件。让每个主机对其各个文件进行排序,然后开始我在Divide key value pairs into equal lists without access to key value counts中描述的合并操作。因此,每个主机都有一个优先级队列,其中包含它排序的每个文件中的下一个项目。
其中一个主机维护一个优先级队列,该队列包含来自其他每个主机的下一个项目。它从该队列中选择第一个,输出它,并轮询它来自下一个项目的主机,然后将其插入优先级队列并继续。
它是优先级队列的优先级队列,分布在多个主机之间。从图形上看,它看起来像这样:
Host1 Host2 Host3 Host4
------------------------------------------------------------------
F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16
\ | | / \ | | / \ | | / \ | | /
---------- ---------- ------------ ------------
PQ1 PQ2 PQ3 PQ4
\ \ / /
\ \ / /
\ \ / /
\ \ / /
---------------\ /------------------
\ /
\ /
\ /
--
Master PQ
on primary host
现在,从单个主机一次请求单个项目是非常低效的。例如,主要主机可以从每个主机请求1,000个项目并将它们保存在单独的缓冲区中。每当主机的缓冲区用完时,主要主机就会从主机请求另一个缓冲区。这将减少网络流量。
这也减少了单个主机上的I / O:您永远不必将组合文件写入磁盘。您按照我之前的答案中的描述对单个文件进行排序并将其写入磁盘,但随后您将在各个主机上开始合并,并将项目发送到执行大合并的主要主机。
答案 3 :(得分:0)
If your compare method is not very complicated, the bottleneck is most-likely the file-IO. This will get worse when you do it over a network rather than on a local hard drive. (But you can only be sure after profiling)
I'm sure the file-IO is your bottleneck (But you can only be sure after profiling).
I would recommend: