我目前正在尝试编写一个map-reduce作业,其中输入数据不在HDFS中,并且无法加载到HDFS中,这主要是因为使用数据的程序无法使用HDFS中的数据,要将其复制到HDFS中,每个节点至少需要1TB。节点 - 本地地图减少工作
所以我有4个目录在我的集群中的每个节点。理想情况下,我希望我的映射器只接收这4个本地目录的路径并使用file:/// var/mydata/...之类的东西读取它们,然后1个映射器可以处理每个目录。即总共16个Mappers。
但是为了能够做到这一点,我需要确保每个节点准确地有4个映射器,并且确切地说有4个映射器被分配了该机器本地的路径。这些路径是静态的,因此可以硬编码到我的fileinputformat和recordreader中,但是如何保证给定的分割结束于具有已知主机名的给定节点。如果它是在HDFS中,我可以使用FileInputFormat中的一个变量设置isSplittable为false,并且hadoop会照顾它,但由于所有数据都是本地数据,因此会导致问题。
基本上我只需要能够在我的集群中的每个节点上抓取本地目录结构一次,在这些目录中处理SSTables集合并发出行(在映射器上),并减少结果(在减少步骤)为HDFS进一步批量处理。
我注意到inputSplits提供了一个getLocations函数,但我相信这并不能保证执行的局部性,只是优化它,而且如果我尝试在每个映射器中尝试使用file:/// some_path,我都需要确保确切的局部性否则我可能会重复读取一些目录,而其他的则根本不会。
任何帮助将不胜感激。
谢谢你的建议,1是不行的,这需要保持更新,因此数据只为一天左右有用,因为我读的文件是一个活跃的一部分数据库的数据将更加陈旧。 2很有趣,NLineInputFormat听起来像是答案的一部分,但你指出并不能保证局部性。 3。听起来似乎是合理的,但是你的意思是删除其他3个节点,如果这就是你的意思,我不能让部分集群离线,集群也需要能够响应其他工作,这必须是考虑可能的运行时间的后台任务。 – feldoh 2013-03-27 14:06:00
嗨菲尔多,你让我对。部分集群脱机。现在我明白这是不可能的,因为它是一个生产集群。 – Rags 2013-03-28 12:07:33
使用上述方法时,确保它在本地运行的一种方法是检查映射中的文件位置,如果它是远程抛出异常以使任务失败。作业追踪器将尝试,直到任务成功,这意味着它在本地找到文件。但这是粗糙的方法。为了使作业继续下去,您可能需要将地图任务的最大尝试次数增加到很高的数字。 – Rags 2013-03-28 12:15:49