我没有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,所以这可能是另一个约束。
答案 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