在具有1GB RAM的机器上对1TB文件进行排序

Sort 1TB file on machine with 1GB RAM

本文关键字:1TB 文件 排序 机器 1GB RAM      更新时间:2023-10-16

这个问题看起来很简单,但是我不能理解它背后的真正工作。我知道人们会说,把它们分解成512兆的块,然后像使用Map reduce一样使用归并排序。

这是我实际的问题:

假设我将文件分解成512mb的块,然后发送到不同的主机进行排序。假设这些机器使用归并排序。现在假设,我有2000台机器,每台机器有2000个512兆的数据块。当我把它们合并回来的时候,它是怎么工作的?尺寸不会继续增大吗?例如,合并两个512兆将得到1024兆,这是我的RAM的大小,所以这将如何工作?任何机器都不能将一个大于512mb的块与另一个块合并,因为它的大小大于1gb。

在合并结束时,我如何能够将两个0.5 TB的块与另一个0.5 TB的块合并…虚拟内存的概念在这里起作用了吗?

我在这里澄清我的基本知识,我希望我问的这个非常重要的问题(正确)正确。此外,谁应该做这个合并(排序后)?我的机器还是那2000台机器中的几台?

这个问题可以简化为一个更简单的问题。这个问题的设计是为了迫使您选择一种方法。

  • 拾取块=~ 1GB,排序&
  • 你最终在文件系统上有1000个1GB的排序文件。
  • 现在,它只是一个将k排序数组合并成一个新数组的问题。

    合并k排序的数组需要你维护一个最小堆(优先队列),每次有k个元素。

k = 1000(文件)。(1GB内存可存储1000个数字)

因此,保持从优先级队列中弹出元素并保存到磁盘。

您将有一个新文件,大小排序为1TB。

参考:http://www.geeksforgeeks.org/merge-k-sorted-arrays/

PS:可以在一台1gb RAM的机器上使用更好的数据结构

合并可以在小于O(N)空间中完成,优先队列即O(K)空间,即问题的核心。

这是一个理论上的方法。假设你已经有了2000个512mb的文件,准备创建一个1TB的文件。

如果您只是循环遍历每个文件,找到FIRST值最低的文件,然后将其移动到目标文件中,然后重复,那么您将按顺序结束所有内容。RAM使用应该很小,因为您永远不需要一次打开多行。

显然,您应该能够优化这一点-在运行时将每个文件的第一行保留在RAM中,这样应该会更快一些。

如何合并的简短版本是这样的:

1)为合并的每台机器创建一个槽。

2)你问每台机器它们还没有给你的最低的条目。

3)你从你的表中删除值最低的表项,输出它,并要求机器用它还没有给你的最低的表项重新填充慢速表,如果机器没有表项,则将槽空。

4)重复步骤3,直到表为空。

这允许您从N台机器中合并一次只存储N个条目。当然,您可以简单地将其优化为保存来自每台机器的M个条目。在这种情况下,您需要存储N*M个条目,当插槽为空时,向该机器请求M个条目来填充它。

现在,假设我有2000台机器,每台机器排序2000,512 mb的块。现在当我把它们合并回来的时候,它是怎么工作的?尺寸不能再大了吗再增加吗?例如,合并两个512兆将得到1024兆这是我的RAM的大小,所以这是如何工作的?任何机器都不能将一个大于512兆的块与另一个块合并,因为然后size> 1gb

这不是一个实际的合并排序实现的工作方式。归并排序(以及相关的排序算法)很酷的一点是,您不需要将整个数据集放在内存中即可使其工作。合并时,每次只需要将文件的一小部分读入内存,然后很快就会将其写出来。

换句话说,合并排序不需要随机访问。如果没有这个好的特性,用当时的技术是不可能对磁带驱动器上的数据进行排序的。磁带驱动器当然不是随机访问介质,当时的RAM以千字节为单位。

归并排序的好处是你不需要随机访问;顺序访问就可以了。这就是为什么当数据集不适合内存时,它是一个完美的解决方案。

单个合并过程需要2个(或更多)输入并产生一个输出。您只需将输入组合成输出,直到只剩下一个文件。