MapReduce 是一种编程模型,为处理大规模数据集(可达数PB级别)的并行运算提供支持。它由Google提出,并被Hadoop等大数据处理框架广泛使用。MapReduce 模型分为两个阶段:Map 阶段和 Reduce 阶段。接下来将详细解释这两个阶段:
- Map 阶段
在 Map 阶段,MapReduce 程序中的 Mapper 会对输入的数据集进行处理。输入数据通常以键值对(key-value pair)的形式存在。Mapper 对这些键值对进行处理,然后输出一组中间键值对。每个 Mapper 独立处理一个数据片段,这允许系统并行处理大量的数据片段。例如,如果你有一组文本文件,你需要统计出现的每个单词次数。在 Map 阶段,每个 Mapper 读取其分配到的文件内容,然后为文本中每个出现的单词输出(单词,1) 的键值对。
输入的数据: "hello world hello"
Mapper 输出: (hello, 1), (world, 1), (hello, 1)
- Shuffle阶段
在 Map 阶段后,系统执行一个 Shuffle 阶段,这不是由编程代码直接控制的,而是由 MapReduce 框架负责执行。在 Shuffle 阶段,所有 Mapper 的输出会被收集起来,并且根据中间键进行排序和分组,以便分配给 Reduce 阶段。
Mapper 输出的汇总: (hello, 1), (hello, 1), (world, 1)
Shuffle 后分组及排序: (hello, [1, 1]), (world, [1])
- Reduce阶段
在 Reduce 阶段,MapReduce 程序中的 Reducer 接受 Shuffle 阶段的输出,并对每一组具有相同中间键的键值对进行汇总,输出最终的结果。
Reducer 每次处理一组具有相同键的键值对。继续我们的统计单词出现次数的例子,Reducer 会将每个单词的出现次数相加,得到最终计数。
Reduce 输入: (hello, [1, 1]), (world, [1])
Reducer 输出: (hello, 2), (world, 1)
用 MapReduce 编程时,我们通常只需提供 map 函数和 reduce 函数的逻辑,并且无需关心并行处理、资源管理和容错等问题,因为这些都由 MapReduce 框架处理。这使得 MapReduce 非常适合进行数据密集型任务的分布式处理。
Eg:
为了加深对MapReduce的理解,本文给出一个数据库查询操作中,left join的MapReduce执行逻辑。
LEFT JOIN(也称为左外连接)会返回包括左表中的所有记录和右表中联结字段相等的记录。如果左表的某行在右表中没有匹配,则结果中对应右表的部分会包含NULL值。在MapReduce下,模拟这一操作涉及到以下过程。
Map阶段(Mapper处理)
1、输入的数据是两个数据集,它们共享一个可以被联结的键(例如,customer_id)。
2、Mapper读取两个数据集的数据,并基于联结键输出中间键值对。对于来自左表的记录,键是联结键,值是整个记录和一个标记(如L)。对于右表的记录也是如此,但是标记不同(如R)。
表A(左表)记录: (customer_id: 1, name: John)
表B(右表)记录: (customer_id: 1, orders: 100)
Mapper输出左表: (1, (L, (name: John)))
Mapper输出右表: (1, (R, (orders: 100)))
Shuffle和Sort阶段
1.Shuffle
操作会将所有Mapper
的输出根据中间键进行排序和分组,确保具有相同联结键的所有记录被发送到同一个Reducer
。
Reduce阶段(Reducer
处理)
1、Reducer
接收排序和分组后的键值对列表。如果一个键同时有来自左表和右表的记录,Reducer
会将它们联结起来输出。如果一个键只有左表的记录没有右表匹配,则右表的值为NULL
,并输出。
2、对于每个键,Reducer
会检查接收的值。如果至少有一个值带有左表的标记L
,那么Reducer
需要输出这个key
对应的所有组合。如果没有任何带有右表标记R
的值,那么Reducer
将会为右表列输出NULL
。
Reduce输入:
(1, [(L, (name: John)), (R, (orders: 100))])
Reducer输出:
如果左表和右表都有匹配:
1, John, 100 (联结了左表和右表的数据)
如果只有左表有匹配:
1, John, NULL (右表无匹配,所以用NULL填充右表的字段)
以上就是本期全部内容,下期介绍mapReduce过程中,经常会遇到的数据倾斜问题,及解决方案。