1:hive自定义函数
自定义UDF:继承UDF,重写evaluate方法
自定义UDTF:继承GenericUDTF,重写3个方法,initialize(自定义输出的列名和类型),process(将结果返回forward(result)),close
2:hive的执行流程
接收到用户的指令(sql语句),结合元数据(metastore),经过Driver内的解析器,编译器,优化器,执行器转换成mapreduce(将sql转换成抽象语法树AST的解析器,将AST编译成逻辑执行计划的编译器,在对逻辑执行计划进行优化的优化器,最后将逻辑执行计划转换成mapreduce),提交给hadoop中执行,最后将执行返回的结果输出到用户交互接口。
3:MR的工作原理
MapReduce是一个基于集群的计算平台,是一个简化分布式编程的计算框架,是一个将分布式计算抽象为Map和Reduce两个阶段的编程模型。
MapReduce核心思想:分而治之
MapReduce计算模型主要由三个阶段构成:Map、shuffle、Reduce。
map:
一个MapReduce应用逐一处理input splits中的每一条记录。input splits在上一步骤被计算完成之后,map任务便开始处理它们。
map任务处理每一个记录时,会生成一个新的中间键/值对,这个键和值可能与输入对完全不同。map任务的输出就是这些中间键/值对的全部集合。
为每个map任务生成最终的输出文件前,先会依据键进行分区,以便将同一分组的数据交给同一个reduce任务处理。在非常简单的应用场景下,可能只有一个reduce任务,此时map任务的 所有输出都会被写入一个文件。但是在有多个reduce任务的情况下,每个map任务会基于分区键生成多个输出文件。
shuffle
Map步骤之后,开始Reduce处理之前,还有一个重要的步骤叫做Shuffle。MapReduce保证每个reduce任务的输入都是按照键排好序的。系统对map任务的输出执行排序和转换,并映射为reduce任务的输入,此过程就是Shuffle,它是MapReduce的核心处理过程。在Shuffle中,会把map任务输出的一组无规则的数据尽量转换成一组具有一定规则的数据,然后把数据传递给reduce任务运行的节点。Shuffle横跨Map端和Reduce端,在Map端包括spill过程,在Reduce端包括copy和sort过程。
reduce:
当所有的map task完成后,每个map task会形成一个最终文件,并且该文件按区划分。reduce任务启动之前,一个map task完成后,
就会启动线程来拉取map结果数据到相应的reduce task,不断地合并数据,为reduce的数据输入做准备,当所有的map tesk完成后,
数据也拉取合并完毕后,reduce task 启动,最终将输出输出结果存入HDFS上。
4:MR为什么执行慢
Mapreduce 程序效率的瓶颈在于两点:
-
计算机性能
CPU、内存、磁盘健康、网络
(所以万一MR跑得慢了,最简单的方式是提高计算及性能,加内存等等!) -
I/O 操作优化
(1)数据倾斜
(2)map和reduce数设置不合理(切片问题)
(3)reduce等待过久
(4)小文件过多
(5)大量的不可分块的超大文件
(6)spill次数过多(磁盘溢写次数过多)
(7)merge次数过多等(因为要对数据进行归并排序)
mapreduce 优化方法
-
数据输入:
(1)合并小文件:在执行mr任务前将小文件进行合并,大量的小文件会产生大量的map任务,增大map任务装载次数,而任务的装载比较耗时,从而导致 mr 运行较慢。
(2)采用ConbinFileInputFormat来作为输入,解决输入端大量小文件场景。 -
map阶段
(1)减少spill次数:通过调整io.sort.mb及sort.spill.percent参数值,增大触发spill的内存上限,减少spill次数,从而减少磁盘 IO。
注释:因为溢写的次数越多越耗时
io.sort.mb是环形缓冲区的大小
sort.spill.percent是默认百分之多少的时候进行溢写到磁盘
1
2
3
(2)减少merge次数:通过调整io.sort.factor参数,增大merge的文件数目,减少merge的次数,从而缩短mr处理时间。
(3)在 map 之后先进行combine处理,减少 I/O。
- reduce阶段
(1)合理设置map和reduce数:两个都不能设置太少,也不能设置太多。太少,会导致task等待,延长处理时间;太多,会导致 map、reduce任务间竞争资源,造成处理超时等错误。
(2)设置map、reduce共存:调整slowstart.completedmaps参数,使map运行到一定程度后,reduce也开始运行,减少reduce的等待时间。
(3)规避使用reduce,因为Reduce在用于连接数据集的时候将会产生大量的网络消耗(减少shuffle的过程,因为shuffle过程很耗时,消耗的资源很多)
(4)合理设置reduc端的buffer,默认情况下,数据达到一个阈值的时候,buffer中的数据就会写入磁盘,然后reduce会从磁盘中获得所有的数据。也就是说,buffer和reduce是没有直接关联的,中间多个一个写磁盘->读磁盘的过程,既然有这个弊端,那么就可以通过参数来配置,使得buffer中的一部分数据可以直接输送到reduce,从而减少IO开销:mapred.job.reduce.input.buffer.percent,默认为0.0。当值大于0的时候,会保留指定比例的内存读buffer中的数据直接拿给reduce使用。这样一来,设置buffer需要内存,读取数据需要内存,reduce计算也要内存,所以要根据作业的运行情况进行调整。
-
IO传输
(1)采用数据压缩的方式,减少网络IO的的时间。安装Snappy和LZOP压缩编码器。
(2)使用SequenceFile二进制文件(SequenceFile这个格式比较紧凑,可以把小文件封装起来) -
数据倾斜问题
(1)数据倾斜现象
数据频率倾斜——某一个区域的数据量要远远大于其他区域。
数据大小倾斜——部分记录的大小远远大于平均值。
(2)如何收集倾斜数据
在reduce方法中加入记录map输出键的详细情况的功能。