- 对于没有接触过大数据技术的人来说,听到大数据这个名词可能会感到很陌生,会很疑惑大数据是个什么东西。
- 当年刚毕业的我就是这样。几年前刚毕业的时候,浏览各种招聘网站,难免会看到职位类型为大数据招聘信息,年轻的我就把它当作了某种高级程序员,也曾经对它有过憧憬,想着自己能不能成为一个大数据工程师呢。但是点进去看到各种不认识的编程语言后,当时连C语言都学的勉勉强强的我就望而却步了。
- 直到今年四月份,大数据这个名词才重新闯入我的生活,当时来到北大青鸟咨询的时候,说是可以学云计算或者Java,还有大数据。当时大数据这个名词一下子吸引了我,怀揣着成为一名大数据工程师的憧憬就报名了。
- 但是在前期学习了一两个月的Java后,我依然没有搞清楚大数据究竟是做什么的,直到我们开始接触Hadoop三大组件后,才对大数据有了自己一点浅显的理解。今天在这里给大家介绍一下Hadoop三大组件之一——MapReduce,带大家初始大数据的庐山真面目。
MapReduce整体架构图
MapReduce是一个分布式运算程序的编程框架
MapReduce的核心功能是 将用户编写的业务逻辑代码 和自带默认组件整合成一个完成的 分布式运算程序,并发运行在一个Hadoop集群上
2.优缺点 优点- 易于编程。用户只关心业务逻辑。实现框架的接口
- 良好的扩展性:可以动态增加服务器,解决计算资源不够的问题
- 高容错性。任何一台机器挂掉,可以将任务转移到其他节点
- 适合海量数据计算(TB/PB),几千台服务器共同计算
1.不擅长实时计算 MySQL
2.不擅长流式计算 SparkStreaming flink
3.不擅长DAG有向无环图 spark graphx (基于内存)
3.核心编程思想
- MapReduce运算程序一般需要分成2个阶段:Map阶段和Reduce阶段
- Map阶段的并发MapTask,完全并行运行,互不相干
- Reduce阶段的并发ReduceTask,完全互不相干,但是他的数据依赖于上一个阶段的所有MapTask并发实例的输出
序列化:把内存中的对象,转换成字节序列(或者其他数据传输协议)以便于存储到磁盘(持久化)和网络传输
反序列化:将字节序列或者是磁盘的持久化数据,转换成内存中的对象
为什么要序列化序列化可以存储“活的”对象
为什么不用java的序列化java的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(校验信息,Header,继承体系等),不便于在网络中高效传输
hadoop序列化框架只加上了简单的校验信息,因为是在系统内部传输,不需要那么多信息
- 好处
紧凑:存储空间少
快速:传输速度快
互操作性:跨语言传输
MapReduce框架原理-
shuffle中有 排序、分区、压缩、合并
-
FileImputFormat实现类:TextInputFormat、CombineTextInputFormat、自定义InputFormat。以前还有(KeyValueTextInputFormat、LineInputFormat等等)
-
数据切片:数据切片只是在逻辑上对输入进行分片,并不会在磁盘上将其切分成片进行存储。数据切片是MapReduce程序计算输入数据的单位,一个切片会对应启动一个MapTask
-
程序先找到你数据存储的目录
-
开始遍历处理(规划切片)目录下的每一个文件
-
遍历第一个文件sm.txt
- 获取文件大小fs.sizeOf(sm.txt)
- 计算切片大小
computerSplitSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M mapreduce.input.fileinputformat.split.minsize=1默认值为1 mapreduce.input.fileinputformat.split.maxsize=Long.MAXValue 默认值Long.MAXValue
- 默认情况下,切片大小=blocksize
- 开始切片,形成第一个切片:sm.txt——0:128M 第二个切片——128:256M 第三个切片256:300M
每次切片时,都要判断切完剩下的部分是否大于块的1.1倍,不大于1.1被就划分一块新的切片
- 将切片信息写到一个切片规划文件中
- 整个切片的核心过程在getSplit()方法中完成
- InputSplit只记录了切片的元数据信息,比如起始位置、长度以及所在的节点列表等
-
提交切片规划文件到YARN上,YARN上的MrAppMaster就可以根据切片规划文件计算开启MapTask个数
切片机制
- 简单地按照文件的内容长度进行切片
- 切片大小,默认等于Block大小
- 切片时不考虑数据集整体,而是针对每一个文件单独切片
//获取切片的文件名称 String name = inputSplit.getPath().getName(); //根据文件类型获取切片信息 FileSplit inputSplit = (FileSplit)context.getInputSplit();



