- 确定合适的map个数
map个数 = max[ ${maperd.min.split.size}, min( ${dfs.block.size} , ${mapred.max.split.size} )]
maperd.min.split.size:splt最小分片,默认1B
mapred.max.split.size:splt最大分片,默认256M
dfs.block.size:hdfs的block块大小
所以,上述公式取得默认1个map task处理256M数据。增大split分片,可以减少map任务个数。增大split分片,可以减小map任务个数。一般来讲,map task在10~20s完成时,可以考虑减少map任务个数,增大单个map处理的数据量。如果map完成时间接近1分钟或者几分钟,可以考虑减小分片大小,增大map任务个数
- 选择合适的reduce个数(默认3个)
reduce个数 = min[ ${hive.exec.Reducers.max} , ( ${inpt.size}/${hive.exec.Reducers.per.Reducer} ) ]
inpt.size:给reduce的数据总量
hive.exec.Reducers.per.Reducer:每个reducer处理的数据量,默认1G
hive.exec.Reducers.max:hive的最大reduce数量
-
使用RCF文件格式
RCF是行列结合的文件存储格式,首先按照行分块,保证同一行的数据在一个block上,其次,每块数据按列存储,有利于数据压缩和快速存取# 建表时指定RFC存储 hive> create table test3(str STRING) STORED AS RCFILE; # 设置压缩格式 hive> set hive.exec.compress.output=true; hive> set mapred.output.compress=true; hive> set mapred.output.compression.codec=com.hadoop.compression.lzo.LzoCodec; hive> set io.compression.codecs=com.hadoop.compression.lzo.LzoCodec; # 插入数据 hive> INSERT OVERWRITE TABLE test3 SELECT * FROM test1;
-
优先用本地模式运行mapreduce
对于map输入文件个数小于4个,或总共文件大小小于128M的数据,让hive优先用本地模式启动jobhive.exec.mode.local.auto=true hive.exec.mode.local.auto.tasks.max=4 #默认情况下为4 hive.exec.mode.local.auto.inputbytes.max=128m #默认情况下为128m
-
join优化
分布式join采取2种方法:
(1)replication join:复制join,把其中一个表复制到每个节点,使得每个节点用这个小表的全部数据和大表的分片数据join
(2)repartition join:分片join,把2个表的join key按照hash值发到不同节点,让每个节点处理1个hash键值的join
以上2种方法,分别对应map段join和reduce端join。hive默认采用reduce段join(2个表join key的hash值分布join)。当1个表很小的时候,可以考虑map join,因为小表复制的代价,小于大表shuffle到不同节点的代价。多大的表才是小表呢,hive.smalltable.filesize默认为25m的算小表。2种方法开启map端的join:
(1)sql中指定那个表需要被replication:/*+MapJOIN (小表表名)*/
(2)hive.auto.convert.join = true
hive.smalltable.filesize = 25mb
-
数据倾斜
hive的数据倾斜分为group by倾斜和join倾斜
(1)group by倾斜2中解决方案# 1.在map端combiner set hive.Map.aggr=true #默认已经为true # 2. reduce操作时,不要把相同的key发往同一个reduce,要随机发放,在reduce聚合后,开启新一轮mrjob set hive.groupby. skewindata=true
(2)join引起的数据倾斜
当某一个join key很多时,就会发生倾斜,hive的解决方案叫做skew join,即:对于这种大数据量的特殊值,不要进行reduce,先保存成文件,然后开启新一轮的mrjob机选set Hive.optimize.skewjoin = true; #大于该数值个数的join key称特殊值,在下一轮job处理 set hive.skewjoin.key=100000
-
job间并行
hive sql会产生多个job,有些情况下job间可以并行,例如子查询或union操作,或join操作hive.exec.parallel = true hive.exec.parallel. thread.number #设置并行的job个数
-
使用严格模式
严格模式禁止3中查询:
(1)对于分区表,不加分区字段不能查询
(2)对于order by:不加limit不能查询、
(3)不允许笛卡尔集的查询,单独join不允许,要left join -
hive内置的虚拟列
hive.exec.rowoffset = true 开启虚拟列查询
虚拟列有input_file_name , block_offset_inside_file,分别说明该条记录来自于哪个hdfs文件和在文件中的偏移量。这2个字段便于在hdfs中查找错误
-
开启推测执行
当某一个map,reduce任务耗时超过平均任务耗时, 会启动一个新job执行这个mapreduce, 哪个先执行完, 哪个先返回结果,另一个kill掉hive.mapred.reduce.tasks.speculative.execution = true