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