节点本地映射减少作业
Posted
技术标签:
【中文标题】节点本地映射减少作业【英文标题】:Node-Local Map reduce job 【发布时间】:2013-03-27 12:04:45 【问题描述】:我目前正在尝试编写一个 map-reduce 作业,其中输入数据不在 HDFS 中,并且基本上无法加载到 HDFS 中,因为使用该数据的程序无法使用来自 HDFS 的数据,并且复制到 HDFS 中的数据太多,每个节点至少 1TB。
所以我在集群中的 4 个节点上都有 4 个目录。理想情况下,我希望我的映射器只接收这 4 个本地目录的路径并读取它们,使用类似 file:///var/mydata/... 的东西,然后 1 个映射器可以处理每个目录。即总共 16 个映射器。
但是,为了能够做到这一点,我需要确保每个节点正好有 4 个映射器,并且正好有 4 个映射器被分配到该机器的本地路径。这些路径是静态的,因此可以硬编码到我的文件输入格式和记录读取器中,但是我如何保证给定的拆分最终出现在具有已知主机名的给定节点上。如果它在 HDFS 中,我可以使用 FileInputFormat 的变体设置 isSplittable 为 false,hadoop 会处理它,但由于所有数据都是本地的,这会导致问题。
基本上,我想要的只是能够在集群中的每个节点上抓取一次本地目录结构,处理这些目录中的 SSTable 集合并发出行(在映射器上),并减少结果(在 reduce step) 进入 HDFS 进行进一步的批量处理。
我注意到 inputSplits 提供了一个 getLocations 函数,但我相信这并不能保证执行的位置,只会优化它,如果我尝试在每个映射器中使用 file:///some_path 我需要确保准确的位置否则很明显我可能最终会反复阅读一些目录,而另一些则根本没有。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:我知道你可以通过三种方式做到这一点。
1.) 只需将数据加载到 HDFS 中,您不想这样做。但值得一试,因为它对以后的处理很有用
2.) 您可以使用 NLineInputFormat。使用每个节点中输入文件的 URL 创建四个不同的文件。
file://192.168.2.3/usr/rags/data/DFile1.xyz
.......
您将这些文件加载到 HDFS 并在这些文件上编写程序,以使用这些 URL 访问数据数据并处理您的数据。如果您将 NLineInputFormat 与 1 行一起使用。您将处理 16 个映射器,每个映射处理一个专有文件。这里唯一的问题,一个节点上的数据很有可能在另一个节点上处理,但是不会有任何重复处理
3.) 您可以通过分别加载上述四个带有 URL 的文件来进一步优化上述方法。在加载这些文件中的任何一个时,您可以删除其他三个节点,以确保文件准确地转到本地存在数据文件的节点。加载时选择复制为 1,以便不复制块。这个过程会极大地增加启动的地图处理本地文件的概率。
干杯 破布
【讨论】:
感谢您的建议,1 不好,这需要不断更新,因此数据只会在一天左右的时间内有用,并且由于我正在阅读的文件是活动数据库的一部分数据将更加陈旧。 2 很有趣, NLineInputFormat 听起来像是答案的一部分,但正如您所指出的,它不能保证局部性。 3.听起来很合理,但是删除其他3个节点是什么意思,如果这就是您的意思,我不能使部分集群脱机,集群也需要能够响应其他作业,这必须考虑到可能的运行时间,成为后台任务。 嗨费尔多,你说得对。使部分集群脱机。现在我明白这是不可能的,因为它是一个生产集群。 在使用上述方法时,确保它在本地运行的一种方法是检查地图中的文件位置,如果是远程则抛出异常以使任务失败。作业跟踪器将尝试直到任务成功,这意味着它在本地找到文件。但这是粗略的方法。要使作业继续进行,您可能需要将地图任务的最大尝试次数提高到一个较高的数值。 我已经考虑过这种方法,正如你所说的那样有点粗略,理论上仍然有可能永远不会选择某些节点,但如果我只能做到这一点,那就这样,谢谢你的建议,非常感谢您抽出宝贵的时间。以上是关于节点本地映射减少作业的主要内容,如果未能解决你的问题,请参考以下文章