每日记忆汇总
Hive的优化
1)MapJoin
使用mapjoin 将小表全部加载到内存在map端进行join,避免reducer处理,因为reducer处理会产生大量的网络IO
2)行列过滤
列处理:尽量减少select * 的使用,使用分区过滤
行处理:进行外关联时,如果将副表的过滤条件写在where后面,就会先将全表关联,之后再过滤。
3)采用分桶
4)采用分区
5)合理设置map数
(1)作业会根据input的目录产生一个或者多个map任务(input的文件总个数,文件的大小,集群设置的块大小)
6)小文件进行合并
map执行之前合并小文件,减少map的数量;CombineHiveInputFormat 具有对小文件合并的功能(默认)
7)合理设置reduce的数量
过多的reduce,启动和初始化时也会消耗很多的时间和资源
有多少个reduce就会产生多少个文件,如果生成了许多的小文件,那么作为下一个任务的输入,就会产生小文件过多的问题
8)常用的参数
set hive.merge.mapfiles=true 在map-only任务结束时合并小文件
set hive.merge.mapredfiles=true 默认时false,在map-reduce 任务结束时合并小文件
Hadoop 的写数据流程
1、首先HDFS client 创建分布式文件系统 DistributedFileSystem 向namenode 申请上传文件
;namenode通过检查目标文件以及父目录是否存在,响应可以上传文件,客户端请求上传第一个文件,请返回datanode,namenode经过计算,返回dn1 dn2 dn3 三个节点(返回的节点大概是与副本的数量是一致的,根据距离以及负载情况计算),
2、由客户端创建文件输出流 FileOutputStream 向三个datanode请求建立通道,在datanode响应成功后(逐级响应),客户端开始上传第一个block(磁盘读取数据放入内存缓存),将文件设置成为一个个的packet ,放入datanode的内存,并且落盘,在传输完毕以后,datanode将清除内存中的数据。在所有的过程完毕之后,客户端向namenode发送数据传输完成
Hadoop 的读数据流程
1、客户端通过DistributedFileSystem 向namenode请求读取文件,namenode 查询元数据的位置,返回所在的datanode位置, 客户端挑选一台节点(就近原则,之后随机)请求读取数据
2、datanode 开始传输数据给客户端,并且是以packet为单位,客户端收到数据,先将数据缓存到本地,然后再写入目标文件
Hadoop shuffle机制
1、shuffle位于map方法之后,reduce方法之前 ,将数据写入环形缓冲区,默认大小100M 左边 是索引 右边是元数据,环形缓冲区到达80%开始溢写,溢写之前对数据进行分区排序,如果涉及的是汇总操作可以采用combiner ,生成spill.index 和spill.out,然后对数据进行归并排序
MapTask工作机制
read阶段:通过自己编写的RecordReader 从inputSplit中解析k/v
Map阶段:将解析出的K/V交给用户编写的map()函数处理,生成一系列新的K/V
Collect阶段:经过map() 函数处理完数据之后 ,通过outputCollector.collect() 输出结果
Spill阶段(溢写阶段):环形缓冲区满后,会进行溢写,将数据写到本地磁盘,并在本地进行一次排序;先根据分区号排序,再根据key进行排序------同一个分区聚合到一块,分区内数据按照key有序
combiner阶段:所有的数据处理完成后 maptask对所有的临时文件进行合并,最终生成一个数据文件