初识MapReduce
什么是MapReduce
Hadoop MapReduce is a software framework for easily writing applications
which process vast amounts of data (multi-terabyte data-sets <TB级别的数据>)
in-parallel on large clusters<大集群> (thousands of nodes) of commodity
hardware in a reliable<可靠的>,fault-tolerant<高容错性> manner.
组成部分
- Map端
- 读懂数据
- 映射为KV模型
- 并行分布式
- 计算向数据移动
- Reduce端
- Reduce中可以包含不同的key
- 相同的key汇聚到一个Reduce中,相同的key调用一次reduce方法
主要思想
分久必合
核心思想
"相同"的key为一组,调用一次reduce方法,方法内迭代这一组数据进行计算。
分布式计算的原理
归并排序
在介绍分布式计算之前,首先需要了解归并排序的思想。我在这里做一个简单的图解,图片来源 dreamcatcher-cx
我拿上图左边"治"的例子来个演示,4,8;5,7;
- 首先4与5比,4<5,把4提出来;
- 其次让5与8比,5<8,接着把5放到4的后面;
- 接着8再与7比较,8>7,所以把7提出来放到5的后面
- 以此类推···
MapReduce实现思想
Map task shuffle write
一 切片
- 假设我们的数据存储在HDFS上,HDFS block块按照字节来切割,再存储时极有可能会中文乱码问题(UTF-8下一个中文用3个字节来存储,一个中文可能正好被block拆开存储);
- MR计算之前会将HDFS的文件划分为切片**(split)**,为了防止出现乱码问题,所以split的大小往往比block大几KB或小几KB(为了读取完整的中文字符);
二 打标签
- map task将处理后的每一条记录打上标签
- 打标签:也称为分区,一个分区数据对应一个reduce task,默认分区器叫HashPartitioner
- 分区的策略:根据key的HashCode与reduce task 的数量 取模,保证相同的key放在一个reduce task中处理
- 打标签的目的就是为了让这一条数据知道将来被哪一个reduce task处理
- 打标签:也称为分区,一个分区数据对应一个reduce task,默认分区器叫HashPartitioner
三 buffer in memory
- 每个Map task把输出放到内存缓冲区中 默认大小为100MB(80+20)
- 为什么要80+20?数据放在80这块内存中进行排序操作,这时会把这块80内存锁住(如果不锁,新加入的数据影响排序);这是就有了这块20的内存,用来存储新放入的数据;这样的目的是为了防止阻塞,可以并行运算,增加效率。
- 进入buffer之后的每一条记录是由三部分组成:
- 分区号(偏移量)
- key
- value
map task一条条的往buffer中写,一旦超过80MB(80%的溢写比例),就封锁这块内存,封锁后就会对内存中的数据进行combiner(小聚合1),combiner可以减少数据量,节省磁盘空间和网络IO。
- 在combiner后需要进行一次排序(1),根据分区号和key来实现排序,如果分区号相同 就比较 key值。
- 这里需要注意key可以是任何数据类型,可以是int、String等这些数据类型都有默认的排序方式,也就是实现了Comparable接口的compare方法;如果key是自己写的类,务必要实现Comparable接口和compare方法。
- 排序的作用是:将相同分区的数据放在一起,并且分区内的数据是有序的。
- 以上combiner以及排序完成后就开始一些数据到磁盘上,此时的磁盘文件就是一个根据分区号分好区的,并且内部有序的文件
- 如果没有进行任何一次溢写就会产生一个磁盘小文件。
四 合并
- map task计算完毕后,会将磁盘上的小文件合并成一个大文件,在这里又一次用到了排序(2),这里使用的是归并排序,将一个个小文件合并成一个有序的大文件。
- 这里的小文件也是经过排序的所以这次排序效率较高。
- 每一个map task都会经过刚才所说所有一切,也就是每一个map task都会产生一个有分区的并且分区内部有序的大文件。
Reduce task shuffle read
五 reduce读取数据
- reduce从map端读取相应的分区数据,将分区数据写入到内存中,内存默认1024*0.7MB,如果内存满了就会发生溢写,溢写之前会进行combiner(2)和排序(3)。
- 当把所有的数据读取过来后,会将溢写产生的磁盘小文件文件合并,这里会最后一次排序(4),最终合并成一个有序的大文件。
- 为什么产生一个有序的大文件?
- 就是为了提高分组的效率(根据key分组)
六 排序的作用
- 总共出现了四次排序
- 四次排序都简化了下一次的排序,最终是为了提高分组的效率。