1 mapReduce基本原理及介绍
HDFS提供分布式存储,mapReduce提供并行计算框架。mapReduce主要特点:
- 提供并行计算能力,随着节点增加近似线性递增
- 分而治之思想
- 编程结构透明
1.1 基本原理
1.1.1 job和task
- job是客户端要求执行的一个工作单元,输入数据、mapReduce程序、配置
- task是mapreduce将job拆分的小单元,分为map任务、reduce任务
- job tracker节点(master):调度task在task tracker上运行,协调所有作业运行;如 果一个task失败,job tracker指定下一个task tracker重新开始。
- task tracker节点(worker):执行任务,发送进度报告。
1.1.2 实际工作流程
- 划分输入文件,称为分片split,将用户进程拷贝到集群内其他机器
- master负责调度,为空闲worker分配作业,分为Map作业和Reduce作业
- 分配Map作业的worker读取对应split的输入数据,Map作业数和split数对应;Map作业 从 输入数据抽取键值对,作为参数传递给map函数,map函数产生的中间键值对缓存在 内存中
- 缓存的中间键值对 定期写入本地磁盘 ,分为R个区,每个区对应一个Reduce作业;这些中 间键值对的位置通报给master,master把信息转发给Reduce worker
- Reduce worker把它负责的中间键值对都读过来(copy/fetch by http), 先进行排序 (sort) ,使得相同键的值聚集在一起(merge)。(因为不同的键可能会存在同一分区)
- Reduce worker遍历排序后的中间键值对,将 每个键与其关联的一组值 传递给reduce函 数,reduce函数产生的输出添加到这个分区的输出文件中
- 所有Map和Reduce作业都完成后,master唤醒user program,MapReduce调用返回user program的代码
说明: MapReduce把输入的数据划分成等长的小数据块,称为输入分片input split分片。分片越小, 负载越平衡,开销越大。 计算数据本地化。在本地存有HDFS数据节点上运行map任务。 因需要分片,mapReduce的输入需要为可分割类型。如常见文本类型,或hdfs特定类型(如 textFiles、sequenceFile)等
1.1.3 mapReduce模型
- shuffle过程
map和reduce之间的整个过程,会占用非常大的带宽开销
- partition函数
将map函数产生的中间键值对映射到多个分区
- 每个分区一部分键,对应的值全部在这个分区中
- 每个partition对应一个reduce
- 最简单的实现:将键求hash再对分区数R取模
- combiner函数
提前在map节点进行部分reduce任务,减少shuffle数据量
- merge过程
reduce节点将它负责的中间键值对读过来先进行排序
- 每个map节点的分区内有多个键
- 每个键都可能在多个map节点的分区存在
- 采用外部归并排序(使用磁盘),因为数据量大
- 排序时内存保留最小化堆
- shuffle过程
- shuffle之Spill过程
- collect(收集阶段)
不断收集<key,value>对,放在内存kvbuffer中。kvindex记录kvbuffer的位置
kvbuffer说明: (1)环形字节数组,节省内存空间 (2)放置<key, value>外还放置一些索引kvmeta (3)数据和索引互不重叠,用分界点equator分割,每次spill后,分界点会换位置 。数据向 上增长,index向下增长 (4)kvmeta是对<key, value>的索引,是个四元组,包括value起始位置、key起始位置、 partition值、value长度,占用4个int – 一个四元组对应一个kv对。kvbuffer快满的时 候,spill写进磁盘 (5)80%开始spill,有单独的spill线程执行
- sort(排序阶段)
kvbuffer中的数据按照partition和key升序排列。排序的只是kvindex,键值对位置不变
- spill(溢写阶段)
把kvbuffer中的数据写进磁盘文件,一个partition在文件中叫做一个段segment。spill阶 段具体包括两个过程。
- merge(合并阶段)
把spill出来的文件merge
- 如果map输出数据过多,会有多次spill,多个out和index文件,分布在一个节点的不同磁盘
- merge在spill结束之后,kvbuffer占用的内存可以释放
- 不同out文件中对应相同partition的segment合并
- 最小化堆多路归并排序,过多可以分多次
- collect(收集阶段)
- shuffle之copy过程
- reduce通过HTTP从各个map拖数据
- 获取的数据内存中能放下就放内存,达到一定程度merge,把merge完的数据写入磁盘
- 有些map获得的数据过大直接写进磁盘,文件数达到一定阈值开启磁盘merge
- shuffle之Merge Sort过程
- 这里的merge与map端的merge类似
- map的结果已经有序,reduce端再进行一次归并排序
- 一般reduce一边copy一边sort,两个阶段重叠
- shuffle之Spill过程
1.2 相关操作
利用wordcount程序,说明mapReduce工作原理
bash-4.1$ vim /tmp/a
bash-4.1$ cat /tmp/a //人工创建文件a,用于测试wordcount程序
1
2
3
one
one
two two
three1
2
3
one
one
two two
three
bash-4.1$ hadoop dfs -put /tmp/a /wordinput //把文件a上传到hadoop集群/wordinput目录下(hdfs文件形式)
DEPRECATED: Use of this script to execute hdfs command is deprecated.
Instead use the hdfs command for it.
bash-4.1$ hdfs dfs -ls /wordinput //查看hadoop集群的wordinput目录,a文件存在
Found 1 items
-rw-r--r-- 3 hdfs hbase 57 2015-09-15 16:09 /wordinput/a
用yarn框架执行mapReduce程序,jar包为hadoop-mapreduce-examples.jar。输出文件 /wordinput/a,输出文件目录/wordoutput
bash-4.1$ yarn jar hadoop-mapreduce-examples.jar wordcount /wordinput/a /wordoutput
2015-09-15 16:11:00,297 INFO client.RMProxy: Connecting to ResourceManager at hadoop1/192.168.180.134:8032 //向yarn的resourceManager申请资源
2015-09-15 16:11:01,175 INFO input.FileInputFormat: Total input paths to process : 1
2015-09-15 16:11:01,275 INFO mapreduce.JobSubmitter: number of splits:1 //只有1个分片,启动1个mapper
2015-09-15 16:11:01,512 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1442218852576_0013 //提交job,分配job id
2015-09-15 16:11:01,782 INFO impl.YarnClientImpl: Submitted application application_1442218852576_0013 //为job分配资源
2015-09-15 16:11:01,836 INFO mapreduce.Job: The url to track the job: http://hadoop1:8088/proxy/application_1442218852576_0013/
2015-09-15 16:11:01,837 INFO mapreduce.Job: Running job: job_1442218852576_0013 //执行job
2015-09-15 16:11:09,072 INFO mapreduce.Job: Job job_1442218852576_0013 running in uber mode : false
2015-09-15 16:11:09,073 INFO mapreduce.Job: map 0% reduce 0%
2015-09-15 16:11:14,130 INFO mapreduce.Job: map 100% reduce 0% //完成map过程
2015-09-15 16:11:21,187 INFO mapreduce.Job: map 100% reduce 100% //完成reduce过程
2015-09-15 16:11:22,202 INFO mapreduce.Job: Job job_1442218852576_0013 completed successfully //任务结束
2015-09-15 16:11:22,380 INFO mapreduce.Job: Counters: 49
File System Counters
FILE: Number of bytes read=75
FILE: Number of bytes written=204539
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=153
HDFS: Number of bytes written=41
HDFS: Number of read operations=6
HDFS: Number of large read operations=0
HDFS: Number of write operations=2
Job Counters
Launched map tasks=1
Launched reduce tasks=1
Data-local map tasks=1
Total time spent by all maps in occupied slots (ms)=3967
Total time spent by all reduces in occupied slots (ms)=4121
Total time spent by all map tasks (ms)=3967
Total time spent by all reduce tasks (ms)=4121
Total vcore-seconds taken by all map tasks=3967
Total vcore-seconds taken by all reduce tasks=4121
Total megabyte-seconds taken by all map tasks=4062208
Total megabyte-seconds taken by all reduce tasks=4219904
Map-Reduce Framework
Map input records=13
Map output records=15
Map output bytes=115
Map output materialized bytes=75
Input split bytes=96
Combine input records=15
Combine output records=7
Reduce input groups=7
Reduce shuffle bytes=75
Reduce input records=7
Reduce output records=7
Spilled Records=14
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=43
CPU time spent (ms)=1970
Physical memory (bytes) snapshot=599707648
Virtual memory (bytes) snapshot=5495390208
Total committed heap usage (bytes)=1009778688
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=57
File Output Format Counters
Bytes Written=41
查看mapReduce执行结果
bash-4.1$ hdfs dfs -ls /
Found 9 items
drwxr-xr-x - hbase hbase 0 2015-09-15 14:39 /hyperbase1
drwxr-xr-x - hbase hbase 0 2015-09-15 14:25 /hyperbase1_hregionindex
drwxr-xr-x - hdfs hbase 0 2015-09-14 16:24 /inceptorsql1
drwxrwxrwx - hdfs hadoop 0 2015-09-14 16:20 /tmp
drwxr-xr-x - hdfs hbase 0 2015-09-15 16:13 /transwarp-health-check-dir
drwxrwxrwx - hdfs hadoop 0 2015-09-14 16:29 /user
drwxr-xr-x - hdfs hbase 0 2015-09-15 16:09 /wordinput
drwxr-xr-x - hdfs hbase 0 2015-09-15 16:11 /wordoutput
drwxr-xr-x - hdfs hbase 0 2015-09-14 16:20 /yarn1
bash-4.1$ hdfs dfs -ls /wordoutput
Found 2 items
-rw-r--r-- 3 hdfs hbase 0 2015-09-15 16:11 /wordoutput/_SUCCESS
-rw-r--r-- 3 hdfs hbase 41 2015-09-15 16:11 /wordoutput/part-r-00000
bash-4.1$ hdfs dfs -cat /wordoutput/part-r-00000 //注意结果已经排序
1 1
2 2
3 2
one 4
three 1
three1 1
two 4