简介:
1 是Hadoop中的一个用于进行分布式计算的框架
2 意味着将计算2个阶段:Map(映射)阶段和Reduce(规约)阶段
Mapper组件的知识点
- Mapper组件开发方式:自定义一个类,继承Mapper
- Mapper组件的作用是定义每一个MapTask具体要怎么处理数据。例如一个文件,257MB,会生成3个MapTask。即三个MapTask处理逻辑是一样的,只是每个MapTask处理的数据不一样。
- KEYIN:LongWritable,对应的Mapper的输入key。输入key是每行的行首偏移量
- VALUEIN:Text,对应的Mapper的输入Value。输入value是每行的内容
- KEYOUT:对应的Mapper的输出key,根据业务来定义
- VALUEOUT:对应的Mapper的输出value,根据业务来定义
- 注意:初学时,KEYIN和VALUEIN写死。KEYOUT和VALUEOUT不固定
- Writable机制是Hadoop自身的序列化机制,常用的类型:
- LongWritable
- Text(String)
- IntWritable
- NullWritable
- 定义MapTask的任务逻辑是通过重写map()方法来实现的。读取一行数据就会调用一次此方法,同时会把输入key和输入value进行传递
- 在实际开发中,最重要的是拿到输入value(每行内容)
- 输出方法:通过context.write(输出key,输出value)
- 开发一个MapReduce程序(job),Mapper可以单独存储,此时,最后的输出的结果文件内容就是Mapper的输出。
- Reducer组件不能单独存在,因为Reducer要依赖于Mapper的输出。当引入了Reducer之后,最后输出的结果文件的结果就是Reducer的输出。
四、 Reducer组件知识点
- Reducer组件用于接收Mapper组件的输出
- reduce的输入key,需要和mapper的输出key类型一致
- reduce的输入value,需要和mapper的输出value类型一致
- reduce的输出key类型,根据具体业务决定
- reduce的输出value类型,根据具体业务决定
- reduce收到map的输出,会按相同的key做聚合,形成:key Iterable 形式然后通过reduce方法进行传递
- reduce方法中的Iterable是一次性的,即遍历一次之后,再遍历,里面就没有数据了。所以,在某些业务场景,会涉及到多次操作此迭代器,处理的方法是:①先创建一个List ②把Iterable装到List ③多次去使用List即可
用:
1 在Hadoop的集群工作过程中,一般是利用RPC来进行集群节点之间的通信和消息的传输,所以要求MapReduce处理的对象必须可以进行序列化/反序列操作。
2 Hadoop并没有使用Java原生的序列化,而是利用的是Avro实现的序列化和反序列,并且在其基础上进行了更好的封装,提供了便捷的API
3 在Hadoop中要求被序列化的对象对应的类必须实现Writable接口
4 序列化过程中要求属性值不能为null
分区:
- 分区操作是shuffle操作中的一个重要过程,作用就是将map的结果按照规则分发到不同reduce中进行处理,从而按照分区得到多个输出结果。
- Partitioner是分区的基类,如果需要定制partitioner也需要继承该类
- HashPartitioner是MapReduce的默认partitioner。计算方法是:which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks
- 默认情况下,reduceTask数量为1
- 很多时候MapReduce自带的分区规则并不能满足业务需求,为了实现特定的效果,可以需要自己来定义分区规则
- Partitioner将会将数据发往不同reducer,这就要求Reducer的数量应该大于等于Partitioner的数量,如果少于则在执行的过程中会报错。
job执行流程
- run job:客户端提交一个mr的jar包给JobClient。提交方式:hadoop jar …
- 做job环境信息的收集,比如各个组件类,输入输出的kv类型等,检测是否合法
- 检测输入输出的路径是否合法
- JobClient通过RPC和ResourceManager进行通信,返回一个存放jar包的地址(HDFS)和jobId。jobID是全局唯一的,用于标识该job
- client将jar包写入到HDFS当中(path = hdfs上的地址 + jobId)
- 开始提交任务(任务的描述信息,不是jar, 包括jobid,jar存放的位置,配置信息等等)
- JobTracker进行初始化任务
- 读取HDFS上的要处理的文件,开始计算输入切片,每一个切片对应一个MapperTask。注意,切片是一个对象,存储的是这个切片的数据描述信息;切块是文件块(数据块),里面存储的是真正的文件数据
- TaskTracker通过心跳机制领取任务(任务的描述信息)。切片一般和切块是一样的,即在实际开发中,切块和切片认为是相同的。在领取到任务之后,要满足数据本地化策略
- 下载所需的jar,配置文件等。体现的思想:移动的是运算,而不是数据
- TaskTracker启动一个java child子进程,用来执行具体的任务(MapperTask或ReducerTask)
- 将结果写入到HDFS当中
排序:
要排序的对象对应类实现WritableComparable接口,根据返回值的正负决定排序顺序
合并:
- 每一个MapperTask可能会产生大量的输出,Combiner的作用就是在MapperTask端对输出先做一次合并,以减少传输到reducerTask的数据量。
- Combiner是实现在Mapper端进行key的归并,Combiner具有类似本地的reduce功能。
- 如果不用Combiner,那么,所有的结果都是Reducer完成,效率会相对低下。使用Combiner,先完成在Mapper的本地聚合,从而提升速度。
Shuffle
Mapper的Shuffle
- MapTask在接收到FileSplit之后进行按行读取
- 每读取一行调用一次map方法
- 执行完一次map之后会将输出的数据写到缓冲区中
- 缓冲区的大小默认是100M,可以通过io.sort.mb来进行调节
- 在缓冲区中,会对数据进行分区-partition,排序 - sort,合并 - combine操作
- 当缓冲区的容量利用率达到阈值0.8的时候,会启动给一个后台线程将缓冲区中的数据写到指定目录下的溢写文件中,这个过程称之为是溢写 (Spill)
- 内存 --磁盘
- 每次的Spill都会产生一个新的溢写文件
- 等最后所有的数据都写完之后,会将所有的溢写文件进行一次合并 (merge),合并到一个新的分区并且排序的文件中
- 如果在最终合并的时候,溢写文件个数>=3,那么合并完成之后会再执行一次Combiner
二、注意问题
- 当产生溢写的时候,缓冲区最后残留的数据会flush到最后一个溢写文件中Spill理论上默认是80M,但是要考虑序列化以及最后的冲刷等因素
- 不能凭借一个MapTask处理的切片大小来衡量MapTask之后的输出数据的多少
- 每一个切片对应一个MapTask,每一个MapTask对应一个缓冲区
- 缓冲区本质上是一个字节数组
- 缓冲区又叫环形缓冲区,好处在于可以重复利用同一块地址的缓冲区
- 阈值的作用是避免Spill过程产生阻塞
- merge过程可能不会发生
三、Reducer的Shuffle
- ReduceTask通过Http的方式来得到输出文件的分区,这个过程称之为fetch
- 每一个ReduceTask将获取的分区的数据再次进行merge,然后进行排序
- 将相同的key做聚合,将值放入迭代器中,这一步称之为grouping
- 调用reduce方法,将key和迭代器传入
四、注意问题
- fetch的默认线程数是5
- ReduceTask的阈值为5%,即当5%的MapTask完成之后,ReduceTask就开始启动
- Merge因子默认为10,即每10个文件合并成一个文件
Shuffle调优
Map的调优:
1,调大缓冲区 ,从100M调大250--400M(建议)
2 调大阈值
3 可以引入combine过程 (建议)
Reduce端:
增多fetch线程的数量 (建议) 增大merge因子 ,减少ReduceTask的阈值
InputFormat
1 控制着数据项map的输入,默认情况下,会对文件进行切片进行按行获取
2.如果需要自定义输入格式,,继承inputFormat (验证文件是否存在,对文件进行切片,提供对每一个切片进行)
数据倾斜
1 数据分布是不均匀,导致有的任务执行快或慢
2 数据倾斜大部分情况是因为数据本身有倾斜的情况
3 大部分情况下的数据倾斜是reduce端的数据倾斜
combine
4 map端生成数据倾斜,多源输入并且文件不可切,且文件的大小不同
小文件处理:
一。小文件的危害:(存 和算)
1.在HDFS,每一个小文件都生成一个元数据,如果在HDFS中存入大量的小文件,则生成大量的元数据,大量NameData
2 在MapReduce中,每一个小文件都会应一个切块,意味大量的MapTask(线程),线程太多,对服务器的负载压力增大
二。小文件的处理:
1 将多个小文件合并一个大文件
2 在hadoop中,提供原生合并小文件Hadoop Achive。(将多个文件打成har包,) hadoop archive -archiveName **.har /txt /re (本质是mapReduce) ,源文件没有删除