Mapreduce:将数据复杂地分发到节点

时间:2015-05-22 13:02:05

标签: python hadoop mapreduce cluster-computing hadoop-streaming

我没有hadoop的实践经验 - 我只学到了一些理论。我面临的任务是使用集群处理一个巨大的CSV文件(比内存大),我已经提出了以下程序。

假设csv文件包含3亿行,我称为1-100万行part1,101-200万行part2和201-300万行part3。 (这只是一个例子,因为在实践中数据必须被划分为更多的部分以便在内存中处理)

我想以下列方式将数据分发到节点上。

节点编号数据

节点1仅第1部分

节点2仅第2部分

节点3仅第3部分

节点4第1部分和第2部分

节点5第2部分和第3部分

节点6第1部分和第3部分

您会看到一些节点只占用数据的一部分而某些节点占用2.根据此情况,两个函数中的一个应用于每个节点。我了解到这可以通过reducer中的if-else语句来完成。 即我的减速机应该是这样的

如果(节点1,2,3)运行函数f1(data_block)

如果(节点4,5,6)运行函数f2(data_blockA,data_blockB)

问题是我学到的大多数hadoop示例都不允许每个节点选择他们想要读取的数据部分。数据以相当黑盒的方式分发到节点。有没有办法解决这个问题?附:我想依靠Hadoop流,因为我的主要语言是Python,而不是Java,所以这可能是另一个约束。

1 个答案:

答案 0 :(得分:1)

在HDFS架构中,存在块的概念。 HDFS使用的典型块大小为64 MB。当我们将一个大文件放入HDFS时,它会切碎为64 MB块(基于块的默认配置),假设你有一个1GB的文件并且你想将该文件放在HDFS中,那么将有1GB / 64MB = 16分割/块,这些块将分布在数据节点上。

数据拆分基于文件偏移发生。文件拆分的目标是并行处理和数据故障转移。

这些块/块将基于您的群集配置驻留在不同的DataNode上。每个块都被分配一个块ID,NameNode保留每个文件的块信息。

假设您有一个128MB的文件,并且您想在HDFS上写这个文件。

客户机首先将文件拆分为块说块A,块B然后客户机与名称节点交互并询问写入的位置 块(块A块B).NameNode给客户端提供可用数据节点列表来写入数据。

然后客户端从这些列表中选择第一个datanode并将第一个块写入datanode,一旦写入过程和复制完成,datanode就会将块复制到另一个datanode第一个datanode给出关于它收到的块的确认。然后客户端写入该 另一个块到datanode。 NameNode保留有关文件及其关联块的信息。

当客户端发出读取数据的请求时,它再次向NameNode发出请求以获取特定文件的数据位置,然后NameNode将有关数据的块信息提供给客户端。

因此您无需担心HDFS上的数据替换。

回答您的问题:

没有其他方法可以控制hadoop上的数据替换策略,但如果根据HDFS块大小划分文件(例如块大小为64MB,数据大小为63MB),那么一个文件将占用一个块,它将会继续使用特定的datanode,但NameNode将再次选择datanode。稍后,您可以检查文件所在的datanode。

但是将小文件放在hadoop上并不是处理hadoop的有效方法,因为hadoop旨在处理非常大的数据集,而小文件可能是NameNode的开销。请参阅此small file problem on Hadoop

的链接

以下链接有助于了解有关hadoop的更多信息。

http://docs.spring.io/spring-hadoop/docs/2.0.4.RELEASE/reference/html/store.html

http://www.aosabook.org/en/hdfs.html