在hadoop中最重要的就是基于hdfs的MapReduce分布式计算模型(以下简称“MR模型”)。hadoop周边的框架都是基于MapReduce做的各种操作,因此MapReduce是学好hadoop的基础。但是,很多初学者对Map、Reduce的本来面目不了解,一时之间不明白map、reduce到底是干什么的,为什么这个样子。下文试图逐一详解。
Map、Reduce是两个函数,属于函数式编程语言中的固有函数。我们java属于面向对象语言,与函数式编程语言有很大区别。以下就以python为例讲述:
a=[1,2,3,4,5]
m = map(lambda x:x+3, a)
list(m)
#[4, 5, 6, 7, 8] |
以上4条语句是用python写的。我现在逐一讲述每条语句。
第一句是定义一个list,包含5个元素,赋值给一个变量a(python声明时不需要指定数据类型)。
第二句是关键。其中蓝色的“lambda”是关键词,用于定义一个匿名函数。该匿名函数的形式参数是x,函数定义是返回x+3.那么“lambda x:x+3”就是定义一个匿名函数,形式参数是x,返回x+3。就这么简单。简单的理解为java中new一个接口就行了。好了,继续分析。这里的map就是一个函数。map函数包括两个参数,第一个就是刚才定义的匿名函数,第二个是一个a,即第一句中定义的list。map函数执行后,把返回值赋值给变量m。
第三句是显示语句,使用list函数显示上面的运算结果m的值。
第四句是显示第三句的运行结果。我们发现,map函数结果也是一个list,并且list中包含的元素个数与参数a的元素个数相同,但是m中的每个元素都是a中对应元素执行匿名函数的结果。
以上就是python写的四句代码的全部含义。大家不要纠结python的语法,只需要关注map的含义即可。
总结Mapper的含义是“对输入的列表中的每一个元素执行一个函数,生成一个列表结果。运算前后列表的元素数量不变化。”
我们在写MR模型时,覆盖Mapper类的map方法时,map函数的每个输入就是外部文件的每一行啊。这正是上面例子中map函数体现的要点。
下面来看reduce函数的本来面目,还是以python代码为例:
import functools a = [1,2,3,4,5] s = functools.reduce(lambda x,y:x+y,a) print(s) #15 |
以上一共包含5行python代码。
第一行是导入类库。
第二行是声明一个列表,包含5个元素,赋值给一个变量a。
第三行是关键。首先看到一个匿名函数“lambda x,y:x+y”。该函数两个形式参数x和y。方法体是x+y。函数reduce的参数有两个,第一个是上面讲的匿名函数,第二个是列表a。运算后赋值给变量s。
第四行是打印s。
第五行是显示结果15.
从以上例子可以看到,15是列表a执行匿名函数的结果。
总结Reduce的含义就是“Reduce是对输入的列表中的所有元素执行一个函数操作,并将中间结果作为参数继续执行函数”。
好像还是没理解吧?继续向下看Reduce的深度分析。
Reduce中匿名函数的两个形参是x和y(假设默认值都是0),这个匿名函数在运行时传入的参数是a中的各个元素。其中x分别是1,2,3,4,5;那么y会传入什么值哪?y是x+y的累计值。
一步步的遍历a中的元素,过程如下:
1.x、y默认值都是 0
2.当x=1,y=0时,运算完成后x+y,即1+0,等于1;
3.当x=2,y=1时,运算完成后x+y,即2+1,等于3;
4.当x=3,y=3时,运算完成后x+y,即3+3,等于6;
5.当x=4,y=6时,运算完成后x+y,即4+6,等于10;
6.当x=5,y=10时,运算完成后x+y,即5+10,等于15;
可能会感觉到reduce的用法这么奇怪,因为python是函数式编程语言。函数语言中函数是一等公民,就像java中类一样普遍。
python中的map、reduce函数会分别遍历参数a中的每一个元素,有点类似于java中的for循环,不必扣细节,大体理解就可以。举例子的目的就是为了让大家有个大致了解,方便以后的hadoop学习。
同学们,理解map、reduce函数的本质了吗?不明白的,请留言吧
|
|