在 Hadoop Mappers 和 Reducers 之间拆分任务

Splitting tasks between Hadoop Mappers and Reducers

我已经在伪分布式模式下配置了一个 Hadoop 设置。简而言之,问题是: 如何决定哪些子任务分配给映射器,哪些分配给缩减器?

详情: 关于这个 Udacity 课程:Intro to Hadoop and MapReduce 问题是:

Data comes from several branches around the world the belong to the same store company. Each data record stores a sale (receipt) in any store. The data is in form of: (date, time, store_name, cost). E.g. (2012-01-01, 12:01, New York Store, 12.99$). The task was to get sales per store.

Udacity 的解决方案 是:

  1. Mappers(仅)逐行读取文件并将其传递到reducer(几乎是读取和传递文件行)
  2. Reducers 收集 已排序的键(即商店名称)并添加 它们!

这种在映射器和缩减器之间拆分任务的选择让我感到困惑。似乎 reducer 仍在完成读取和添加的全部工作,而实际上,默认情况下它只有 1 个 reducer,这个解决方案听起来会在 reducer 中造成瓶颈。

我预期的解决方案是:

  1. 映射器读取文件,每个映射器读取一组销售额,将同一家商店的销售额相加,并传递哈希列表(键:商店,值:销售额总和) 到减速器。
  2. Reducers(默认情况下是 1 个 reducer)得到了简化版本,他们的任务现在更简单了。

我的问题是:

  1. 他们为什么这样实施?正确吗?我对 MapReduce 的理解有误吗?如果是的话,你能给我一些可以解决这个冲突的书籍、视频或教程的链接吗?
  2. 在任务数量较多的项目中,我如何才能决定哪些交给映射器,哪些交给缩减器?有没有参考或指标?

MapReduce 编程范式的核心思想是数据被描述为许多 key-value 对,其中 key 表示用于标识的特定类型(例如用户 ID,以防万一)我们想制作一个程序来为每个用户或一个单词计算一些东西,以防我们想要计算每个单词的每次出现次数,如 Hadoop 项目本身所示 here

为了从输入数据的形式得到我们想要的输出结果,必须进行某种类型的操作,以便:

  1. 将输入数据转换成一对或多对key-value组(因此我们映射数据)和
  2. 实际以我们想要的方式处理这些数据集,以获得我们的输出(因此我们 Reduce key-value 对基于我们程序的目的)

根据您在问题中提出的 Udacity 示例,我们知道输入数据的形式

(date, time, store_name, cost)

我们需要找到每家商店的销售额。所以首先我们 map 将输入数据 key-value 对形式,其中每个输入记录的 store_name 将被放入 [= key-value 对中的 14=]。该函数的输出将实际读取每一行并构建一个 key-value 对,其中所需的信息存储在其中(其中 store_namekeycostvalue):

(store_name, cost)

对输入的每一行执行此操作可能会导致 key-value 对具有与 key 相同的 store_name,基于此我们可以 reduce 通过按键分组并收集它们来减少这些对,以便将它们全部加起来并获得每家商店的总销售额。该函数的输出将是这样的(其中 store_namekeytotal_sales 是用户在函数内部编程计算的 value

(store_name, total_sales)

至于映射器和缩减器之间的任务分配,这几乎完全取决于您,因为您必须记住 映射器是针对所有输入数据执行的(例如在您的示例中逐行读取所有记录)并且正在为从映射器创建的 key-value 对中的每个 key 执行缩减器。这里的好消息是,像 Hadoop 这样的项目确实可以为您完成半部分操作,因此您需要配置的只是如何映射 Map 函数中的数据以及如何处理Reduce 函数。

至于默认的单个减速器,你可能知道你确实可以将减速器的数量设置为你想要的数量,但它们只是实例 Reduce 函数针对不同的数据在不同的 threads/CPUs/Machines 上执行(这就是 Hadoop 在大数据应用程序中使用的原因,因为这些大量的输入数据可以通过计算机集群的并行处理得到更好的处理) .

到目前为止,您对 MapReduce 机制的困惑是可以理解的,因为实际上这里使用的 MapReduce 函数源自计算的函数式编程分支,很多人不是 习惯了。考虑研究更多简单的 MapReduce 应用程序示例以更好地了解它们的机制,例如 WordCount 示例或 我们计算每个运动员的奥运金牌总数)。

至于是否有更多任务的可能性,真正由您决定在哪里剪切输入数据并将其共享给映射器(您可以从 [=42= 中的答案中找到更多信息) ] 问题)或者要初始化多少个 reducer 来并行处理你的数据(当然,对于超过默认的 1 个 reducer)。