我有一个包含 5 亿行和 58 个变量的大型数据集。我需要使用第 59 个变量之一对数据集进行排序,该变量是使用其他 58 个变量计算的。该变量恰好是一个浮点数,小数点后有四位。
有两种可能的方法:
- 普通归并排序
- 在计算第 59 个变量时,我开始将特定范围内的变量发送到特定节点。对这些节点中的范围进行排序,然后在我对数据进行完美排序后将它们合并到减速器中,现在我也知道在哪里合并哪组数据;它基本上变成了附加的。
哪种方法更好,为什么?
我有一个包含 5 亿行和 58 个变量的大型数据集。我需要使用第 59 个变量之一对数据集进行排序,该变量是使用其他 58 个变量计算的。该变量恰好是一个浮点数,小数点后有四位。
有两种可能的方法:
哪种方法更好,为什么?
我假设您正在为所有行寻找没有二次排序的总排序顺序。我还应该提到,“更好”从来都不是一个好问题,因为时间和空间之间通常需要权衡取舍,在 Hadoop 中,我们倾向于考虑空间而不是时间,除非您使用针对时间优化的产品(TeraData具有将数据库放入内存以供 Hadoop 使用的能力)
在您提到的两种可能的方法中,我认为只有一种可以在 Hadoop 基础架构中工作。数字 2,由于 Hadoop 利用许多节点来完成一项工作,排序变得有点难以实现,我们通常希望 MR 的“随机排序”阶段来处理排序,因为分布式排序是编程模型的核心.
在生成第 59 个变量时,您需要对该变量的分布进行采样,以便您可以通过框架发送它,然后像您提到的那样合并。考虑 x 的变量分布包含 80% 的值的情况。这可能会将 80% 的数据发送给一个可以完成大部分工作的 reducer。这当然假设某些键将在排序和随机播放阶段进行分组,除非您将它们编程为唯一的,否则会出现这种情况。由程序员设置分区器以通过对密钥分布进行采样来均匀分布负载。
另一方面,如果我们要在内存中排序,那么我们可以在 reduce 期间完成同样的事情,但存在固有的可伸缩性问题,因为排序仅与当前运行排序的节点中可用的内存量一样好,并且很快就会消失当它开始使用 HDFS 来查找其余不适合内存的数据时。如果您忽略了采样问题,您可能会耗尽内存,除非您的所有键值对均匀分布并且您了解数据中的内存容量。
查看HadoopStreaming Wiki 页面的 Hadoop 比较器类部分
您可以将数据集移动到 HDFS,使用 Python 编写映射器并仅执行 hadoop 流式映射器工作。Hadoop Streaming 将自动帮助您对它们进行排序。
然后,您可以根据需要使用 hdfs dfs -getmerge 和 -copyToLocal 将已排序的记录移回本地。