MapReduce是Hadoop的批处理框架。
MapReduce参与者
MapReduce运行机制
海量的数据通过Map后被分为
的结果,再由Reduce合并value
的结果,得到最终结果存储到HDFS中,呈现给需要的节点。这些任务由JobTracker协调,由TakTracker计算。
文件要存储在HDFS中,每个文件切分成多个一定大小(默认64M或128M)的Block(默认3个备份)存储在多个节点(DataNode)上。
输入和拆分:不属于map和reduce的主要过程,但属于整个计算框架消耗时间的一部分,该部分会为正式的map过程准备数据,在节点上将数据加载到HDFS文件系统。
分片(split)操作:MapReduce框架使用InputFormat基础类做map前的预处理,比如验证输入的格式是否符合输入定义;然后,将输入文件切分为逻辑上的多个input split,input split是MapReduce对文件进行处理和运算的输入单位,只是一个逻辑概念。在进行map计算之前,mapreduce会根据输入文件计算输入分片(input split),每个输入分片(input split)针对一个map任务,输入分片(input split)存储的并非数据本身,而是一个分片长度和一个记录数据的位置的数组。split操作知识将源文件的内容分片形成一系列的input split,每个input split中存储着该分片的数据信息(例如,文件块信息、起始位置、数据长度、所在节点列表…),并不是对文件实际分割成多个小文件,每个input split都由一个map任务进行后续处理。
数据格式化(Format)操作:将划分好的input split格式化成键值对形式的数据。其中key为偏移量,value为每一行的内容。map任务执行过程中,会不停地执行数据格式化操作,每生成一个键值对就会将其传入map进行处理。最终形成一个
。
上图将HDFS的数据进行split操作,同时进行的形成一个个的
map阶段: 对
执行map函数了,一般map操作都是本地化操作也就是在数据存储节点上进行。
map词频统计:HDFSZ中存在test.txt内容为,hadoop ,spark,hadoop,storm,hadoop,spark。经过Split分块再有Map操作就变为了
,
Map shuffle阶段:在交由Reduce最终处理时还需要经过shuffle阶段,Shuffle 过程是指map产生的直接输出结果,经过一系列的处理,成为最终的reduce直接输入的数据的过程。该过程可以分为两个阶段:
写入缓冲区
中,spill处理溢出文件。对数据执行分区partition,排序sort,合并combiner等操作。归并merge
,每次溢写会生成一个溢写文件,这些溢写文件最终需要被归并成一个大文件。归并的意思:生成key和对应的value-list。 在Map任务全部结束之前进行归并,归并得到一个大的文件,放在本地磁盘。合并(Combine)和归并(Merge)的区别: 两个键值对<“a”,1>和<“a”,1>,如果合并,会得到<“a”,2>,如果归并,会得到<“a”,<1,1>>。
Reduce阶段
Copy阶段
:reduce端可能从n个map的结果中获取数据,而这些map的执行速度不尽相同,当其中一个map运行结束时,reduce就会从JobTracker中获取该信息。map运行结束后TaskTracker会得到消息,进而将消息汇报给 JobTracker,reduce定时从JobTracker获取该信息,reduce端默认有5个数据复制线程从map端复制数据。
Sort阶段
:Reduce复制数据先放入缓存,来自不同Map机器,与map一样,内存缓冲区满时,也通过sort和combiner,将数据溢写到磁盘文件中。如果形成了多个磁盘文件还会进行merge归并,最后一次归并的结果作为reduce的输入而不是写入到磁盘中。文件中的键值对是排序的。
当数据很少时,不需要溢写到磁盘,直接在缓存中归并,然后输出给Reduce。
reduce端的shuffle
由于map和reduce往往不在同一个节点上运行,所以reduce需要从多个节点上下载map的结果数据,多个节点的map里相同分区内的数据被复制到同一个reduce上,并对这些数据进行处理,然后才能作为reduce的输入数据被reduce处理。
注意:当Reduce的输入文件确定后,整个Shuffle操作才最终结束。之后就是Reduce的执行了,最后Reduce会把结果存到HDFS上。
Reduce端流程:
Reduce会接收到不同map任务传来的数据,并且每个map传来的数据都是有序的。如果reduce端接受的数据量相当小,则直接存储在内存中(缓冲区大小由mapred.job.shuffle.input.buffer.percent属性控制,表示用作此用途的堆空间的百分比),如果数据量超过了该缓冲区大小的一定比例(由mapred.job.shuffle.merge.percent决定),则对数据合并后溢写到磁盘中。随着溢写文件的增多,后台线程会将它们合并成一个更大的有序的文件,这样做事为了给后面的合并节省时间。其实不管在map端还是reduce端,MapReduce都是反复地执行排序,合并操作,所以排序是hadoop的灵魂。
Map与Reduce通信
Reduce从Map中复制数据,那么分区中的数据怎么知道它对应的reduce是哪个呢?
map任务一直和其父TaskTracker保持联系,而TaskTracker又一直和JobTracker保持通讯。所以JobTracker中保存了整个集群的宏观信息,只要reduce任务向JobTracker获取对应的map输出位置即可。
MapReduece数据本地化
HDFS和MapReduce是Hadoop的核心设计。对于HDFS,是存储基础,在数据层面上提供了海量数据存储的支持。而MapReduce,是在数据的上一层,通过编写MapReduce程序对海量数据进行计算处理。
在HDFS中,NameNode是文件系统的名字节点进程,DataNode是文件系统的数据节点进程。MapReduce计算框架中也有类似的节点JobTracker协调整个作业的执行和TakTracker数据片段上执行Map或Reduce任务。
MapReduce计算框架中负责计算任务调度的JobTracker对应HDFS的NameNode角色,只不过一个负责计算任务调度,一个负责存储任务调度。MapReduce中负责真正计算任务的TaskTracker对应到HDFS的DataNode角色,一个负责计算,一个负责管理存储数据。考虑到“本地化原则”,一般地,将NameNode和JobTracker部署到同一台机器上,各个DataNode和TaskTracker也同样部署到同一台机器,四个角色分工明确,共同完成作业。
MapReduce的优势在于“计算移动,数据不移动”。免去了大量网络开销。map在本地执行其HDFS上的数据,将结果返回给reduce,由其执行作业得到最终结果,reduce任务时并不考虑数据本地化。
Word Count
Word Count 就是"词语统计",这是 MapReduce 工作程序中最经典的一种。它的主要任务是对一个文本文件中的词语作归纳统计,统计出每个出现过的词语一共出现的次数。
DEPRECATED: Use of this script to execute hdfs command is deprecated. Instead use the hdfs command for it.
的意思是,版本更新后hadoop
命令换成了hdfs
命令。如:hadoop
i like hadoop
mapreduce is a member of hadoop
how to use hadoop
mapreduce
# 编辑本地文件
vi words.txt
# 将本地文件words.txt上传到hdfs文件系统的wordcount目录下
hdfs dfs -put words.txt /wordcount
# 查看wordcount目录
hdfs dfs -ls /wordcount
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.10.1.jar wordcount /wordcount /wordount/output
执行的命令是mapreduce的命令很长,主要有五个部分,hadoop jar
是第一部分固定名,用于执行jar工具包;第二部分是jar工具包的路径,如下:
该工具包位于hadoop解压文件夹的/share/hadoop/mapredce
下,通过配置的环境变量$HADOOP_HOME
配置了hadoop路径,这样就免去了上下文连接,当然也可以写全:
/home/user/hadoop/hadoop-2.10.1/share/hadoop/mapreduce/...mapreduce-examples-2.10.1.jar
第三部分是工具包的wordcount
是词频统计命令;第四部分是被执行文件的路径;第五部分是执行结果输出目录。命令之间有空格隔开。
hadoop jar [jar_path] wordcount [resource] [target]
输出上面图片上的内容即为执行成功。
上面执行命令输出目录wordcount写错了,但不影响结果的查看。
hdfs dfs -rm -R /wordount
删除命令,连带删除。
MapReduce远程运行需要配置YARN资源管理框架,Reduce从个节点copy被Map处理的结果。
配置YARN在mapred-site.xml
,复制 mapred-site.xml.template 文件生成 mapred-site.xml进行如下配置:
<configuration>
<property>
<name>mapreduce.framework.namename>
<value>yarnvalue>
property>
configuration>
配置yarn-site.xml
:
yarn.resourcemanager.hostname
属性为资源管理器的主机,设置为主机 IP 地址。
yarn.nodemanager.aux-services
属性为节点管理器的辅助服务器,默认值为空,设置为 mapreduce_shuffle
。
<configuration>
<property>
<name>yarn.resourcemanager.hostnamename>
<value>ip-addrvalue>
property>
<property>
<name>yarn.nodemanager.aux-servicesname>
<value>mapreduce_shufflevalue>
property>
configuration>