我在DistributedCache上阅读了Apache和Yahoo的教程。我仍然对一件事感到困惑。假设我有一个文件,我想将其复制到所有数据节点。所以,我用
作业驱动程序中的DistributedCache.addCacheFile(new URI(hdfsPath),job)
使文件可用。然后,我在Mapper中调用DistributedCache.getLocalCacheFiles(job)
。
现在,我想根据此文件的内容在数据节点上创建一个数组,以便每次map()运行时,它都可以访问数组的元素。我可以这样做吗?我很困惑,因为如果我读取缓存文件并在Mapper类中创建数组,它似乎会为Mapper的每个新输入创建数组,而不是每个Mapper只创建一次。这个部分实际上是如何工作的(即,我应该在何时何地创建数组)?
答案 0 :(得分:2)
这里混合了一些概念。
Datanode与DistributedCache无直接关系。它是MapReduce层的概念。
希望在映射器之间重用缓存文件中的相同导数,这与MR范例的功能性质相矛盾。映射器应该在逻辑上独立。
你想要的是一种优化,如果对映射器的缓存文件的预处理相对昂贵,这是有意义的
您可以在某种程度上通过将预处理数据保存在某个静态变量中,延迟评估它,并设置hadoop以在任务之间重用虚拟机来实现。这不是“MR”精神解决方案,但应该有效
更好的解决方案是将缓存的文件预处理到表单,其中mapper的使用将是便宜的。
让我们假设所有的想法都是一种优化 - 否则为每个映射读取和处理文件就好了。
可以说,如果为每个映射器准备文件比映射处理本身便宜得多,或者比映射器运行开销便宜得多 - 我们没问题。
通过表单我的意思是文件的格式,可以非常有效地转换为我们需要的内存中结构。例如 - 如果我们需要在数据中进行一些搜索 - 我们可以存储已经排序的数据。这将节省我们每次排序,通常比从磁盘顺序读取更昂贵的东西
如果在你的情况下它是一些适度数量的属性(比如数千),我可以假设它们的读取和初始化与单个映射器相比并不重要