这就是搜索引擎(7) 云计算之MapReduce
0 背景
Map/Reduce是Google针对海量信息处理提出的非常著名的云计算模型,包括Hadoop等众多开源系统都采纳了这一方法,成为了主流的云计算模型。
Map/Reduce是一个计算模型的同时,也是一个计算框架,负责将计算任务分配到众多机器上,并对机器失效等情况自动跟踪,使得应用开发者只要专注于本身的开发工作。
1. 计算模型
MapReduce的输入特征是由Key/Value数值对组成的一组记录,通过Map操作转换为新的Key/Value1键值对,其中输入数据的每条记录可能会生成多条新的记录,接着进行Reduce,将中间数据里相同的Key/Value进行累加处理,就能得到最终的结果KeyValue。这一系列计算都由框架完成,用户只需开发Map和Reduce两个操作的代码即可。
下图所示的是使用MapReduce模型统计单词在不同网页中出现的次数,其中输入数据是网页url以及url中所包含的单词的键值对,对输入数据进行Map操作,转换为 <word, count>的新键值对,然后对进行Reduce操作,将中间数据里相同的Key的Value进行累加,就能够得到一组以单词为Key,出现次数为Value的记录。
2. 整体流程
上述说的只是基本原理,实际上框架的逻辑流程要更复杂一些,如下图所示。
- Map/Reduce首先将输入数据进行切割,分为M份固定大小的片段(M为执行mapper任务的数量)
- 每个数据片段被分发到不同机器上,每个机器对各自的数据片段执行map操作,转换为新的kv形式
- 转换出的新的中间数据存储在本地中,相同Key的数据通过Combiner任务进行合并(目的是减少到Reducer的网络传输量)
- 合并后的数据通过分割器,将数据分为R份(R为执行reducer任务的数量)。
- reducer位于其他机器,通过网络将各mapper负责的数据取回到本地,并进行reduce操作,将相同的key value进行汇总,就得到了结果。
Map/Reducer使用了分而治之的思想,通过多机写作对数据进行全局性的统计。实际任务中,多个Map/Reducer任务往往相互串联,一个任务的数据结果作为后一个任务的输入,以此来完成复杂的计算任务。
3. 其他
3.1 Map/Reduce的优缺点
优点:
- 基于框架之下,应用开发者易于编程,开发效率高
- 扩展性强,简单的增加机器能够有效的提升计算能力
- 高容错性,一旦其中的一个机器崩溃了,可以直接将其转移到另一个机器上运行,这个过程也不需要人手工干预
缺点:
- 不擅长做实时计算:无法在毫秒或者秒级返回结果,因此适合离线处理而不适合在线处理
- 不擅长流式计算:MapReduce的输入数据必须是静态的,不能够动态变化
3.2 数据倾斜
数据倾斜是MR任务中常见的问题,所谓数据倾斜指的是由于数据分配不均,导致mapper或者reducer之间处理的数据量相差过大。
以上述统计单词在网页中出现数量为例,假设输入的网页集合是一个美食站点下的所有网页,有一个单词"米饭",在其中高频出现,最终mapper之后形式为("米饭", 1)的数据占到了整体数据的50%那就会造成一半以上的数据交给一个reducer相加,其余一半分配给其他的reducer处理,这就是所谓数据倾斜。造成的结果就是任务处理进度的长尾,99%的任务在一个小时内跑完,最后1%的任务需要10个小时才能跑完,大大拖慢了整体任务进度,处理量的不同也会带来高负担实例OOM等风险。
根据实际场景的不同,数据倾斜一般可以分为两种情况
- 数据频率倾斜——某一个区域的数据量要远远大于其他区域,例如我们用身高作为数据的主键,并按照身高排序来分区,那最终落在身高160180的数据一定远远大于落在200220的数据
- 数据大小倾斜——部分记录的小远大于平均值,也就是我上述说的高频单词的情况。
对于第一种问题,可以采用hash partition的方式,即不要使用身高排序进行分组,而是将每个数据的身高进行hash,根据hash值来排序分组,hash分组的场景下几乎每个Reducer分到的数据值都是相同的。
当然hash partition对第二个问题无能为力,对于第二种场景可以考虑将重复的数据打散,例如对中间结果每个单词的后缀都拼上一个随机数0~9, 就可以将米饭分为(米饭0,米饭1,米饭2,米饭3.....米饭9)九种不同的key,相应的负责处理的reducer也从1个提升到了10个,就能有效缓解数据倾斜带来的压力。当然这么做也有其弊端,这样处理完的数据是半成品,必须还要做一次MR, 将米饭0,米饭1....米饭9的数据聚合到米饭这一个字段上,才是最终结果。
应对数据倾斜有很多种办法,但是并没有一劳永逸的方式,关键是要了解数据集的分布情况以及计算框架与硬件的运行机制与瓶颈,针对特定场景做特定的优化才行。