我正在尝试理解与Hadoop的Map / Reduce框架相关的数据位置。特别是我试图了解哪个组件处理数据局部性(即它是输入格式?)
Yahoo's Developer Network Page声明“然后,Hadoop框架使用来自分布式文件系统的知识,在数据/记录的位置附近安排这些进程。”这似乎意味着HDFS输入格式可能会查询名称节点以确定哪些节点包含所需数据,并且如果可能,将在这些节点上启动映射任务。可以想象,通过查询确定哪些区域正在为某些记录提供服务,可以采用类似的方法。
如果开发人员编写自己的输入格式,他们是否负责实现数据本地化?
答案 0 :(得分:7)
FileInputFormat
类和getSplits()
方法。它搜索Blocklocations:
BlockLocation[] blkLocations = fs.getFileBlockLocations(file, 0, length);
这意味着FileSystem查询。这发生在JobClient
内部,结果写入SequenceFile(实际上它只是原始字节代码)。
因此,Jobtracker稍后在初始化作业时读取此文件,并且几乎只是将任务分配给inputsplit。
但数据的分布是NameNodes作业。
现在提问你:
通常你是从FileInputFormat
延伸出来的。因此,您将被迫返回InputSplit
的列表,并且在初始化步骤中需要这样的事情来设置拆分的位置。例如FileSplit
:
public FileSplit(Path file, long start, long length, String[] hosts)
所以实际上你没有实现数据局部性,你只是告诉哪个主机可以找到分割。使用FileSystem
界面可以轻松查询。
答案 1 :(得分:0)
Mu理解是数据局部性由HDFS和InputFormat共同决定。前者确定(通过机架感知)并存储跨越数据节点的HDFS块的位置,而后者将确定哪些块与哪个分区相关联。 jobtracker将尝试通过确保与每个拆分关联的块(1拆分为1个映射任务映射)对tasktracker是本地的来优化将哪些拆分传递到哪个映射任务。
不幸的是,这种保证局部性的方法在同构集群中得以保留,但在非均匀集群中会崩溃,即每个数据节点存在不同大小的硬盘。如果你想深入研究这个问题,你应该阅读本文(Improving MapReduce performance through data placement in heterogeneous hadoop clusters),该文章还涉及与你的问题相关的几个主题。