【问题标题】:Hadoop DistributedCacheHadoop分布式缓存
【发布时间】:2012-04-25 14:57:33
【问题描述】:

我已经阅读了来自 Apache 和 Yahoo 的关于 DistributedCache 的教程。我仍然对一件事感到困惑。假设我有一个想要复制到所有数据节点的文件。所以,我用 DistributedCache.addCacheFile(new URI(hdfsPath),job) 在工作驱动程序中使文件可用。然后,我在 Mapper 中调用 DistributedCache.getLocalCacheFiles(job)

现在,我想根据这个文件的内容在数据节点上创建一个数组,这样每次 map() 运行时,它就可以访问数组的元素。我可以这样做吗?我很困惑,因为如果我读取缓存文件并在 Mapper 类中创建数组,它似乎会为 Mapper 的每个新输入创建数组,而不是每个 Mapper 一次。这部分实际上是如何工作的(即,我应该在哪里/何时创建数组)?

【问题讨论】:

  • 我想我可能已经找到了自己问题的答案。看起来好像在实例化 Mapper 时会自动调用 configure() 方法。因此,应该使用 configure() 创建数组。这在 map() 方法之外,所以它只发生一次。我希望这是对的!

标签: hadoop mapreduce distributed-cache


【解决方案1】:

这里混杂了几个概念。 Datanode 与 DistributedCache 没有直接关系。它是 MapReduce 层的概念。
希望在映射器之间重用缓存文件中的相同派生与 MR 范例的功能性质有些矛盾。映射器在逻辑上应该是独立的。
您想要的是一种优化,如果映射器的缓存文件预处理相对昂贵
您可以通过将预处理数据保存在某个静态变量中,惰性评估它并设置 hadoop 以在任务之间重用虚拟机来在某种程度上做到这一点。这不是“MR”精神解决方案,但应该有效。
更好的解决方案是将缓存文件预处理到表单中,这样映射器的消耗会很便宜。
让我们假设所有想法都是一种优化 - 否则为每个映射读取和处理文件就可以了。
可以说,如果为每个映射器准备文件比映射处理本身便宜得多,或者比映射器运行开销便宜得多 - 我们很好。
我所说的形式是指文件的格式,它可以非常有效地转换为我们需要的内存结构。例如 - 如果我们需要在数据中进行一些搜索 - 我们可以存储已经排序的数据。它可以节省我们每次排序的时间,这通常比从磁盘顺序读取要贵得多
如果在您的情况下它是一些适度数量的属性(比如说数千),我可以假设它们的读取和初始化与单个映射器相比并不重要

【讨论】:

  • 我确实希望映射器是独立的。我只希望他们每个人都拥有相同数据的副本(例如,输入中的用户 ID 作为键传递,并且我将用户的一些属性存储在我希望访问的文件中)。与其每次都将属性作为输入的一部分传递,我认为最好在每个节点上的单个文件中列出一次(对于所有用户)。我不确定我是否理解“将缓存文件预处理为表单”的意思。你能解释一下这里的表格是什么意思吗?
  • 我已经为答案添加了一些解释。
  • 感谢您的补充说明!