hive 优化

#######
#本质##    hdfs +mapreduce
#######

##########
#问题所在#
##########
    1、倾斜
        1.1内容倾斜
        1.2groupby
        1.3小表 join 大表
    2、过多
        2.1join过多,导致job过多
        2.2小文件过多
        2.3Mapper或Reducer过多
    3、使用不当
        3.1count(distinct)
        3.2join... where


###########
#解决方案##
###########
#一次任务数据量太小资源浪费
#模型设计
    #整体最优,考虑全局
        合理减少表数量:
            sqoop:query "select ... join..."
            ods->dwd insert into...select ... join...
            数据建模:
                【星型】,雪花,星座
                维度表(静态数据),事实表(动态数据:谁在什么时间做了什么事情)
                维度退化-》星型
    #充分了解业务,提前设计好预聚合
        分层=》轻量聚合
            主题:
                方向:时间(时间维度表),用户(用户画像),产品(三级分类),...
                分析主题            指标
                    时间 
                        用户 
                                本周内用户消费总额
                                本周内连续登录三天或累计登录5天的用户
                        商品
                                ...
                        ...
        分区=》避免交换
            on... where ...
            拉链表
        压缩=》减少体量
            配,压缩格式,表存储格式(是否支持压缩,是否支持切片)
            hadoop
            hive
            spark
            
    #倾斜:热点数据
        内置自动优化
        #join:非大小表
            set hive.skewjoin.key=100000;#默认join键对应的记录数超过该值则进行倾斜分析
            set hive.optimize.skewjoin=true;#默认false,如果join键倾斜则设为true
            set hive.skewjoin.mapjoin.map.tasks=10000;#默认10000,倾斜处理mapper数量上限
            set hive.skewjoin.mapjoin.min.split=32M;#默认32M,倾斜最小切片大小
        #map join :大小表        (在map端join,然后落盘,没有shuffle和reduce)
        set hive.auto.convert.join=true;#默认true
        set hive.mapjoin.smalltable.filesize=25M;#默认小表《=25M 300M
        set hive.optimize.bucketmapjoin=true;默认false,放分桶表mapjoin专用
        #combiner:
        set hive.map.aggr;#默认true
        #broupby :HashPartitioner
        set mapred.reduce.tasks=n;#默认-1,倾斜的倍数,n=skew_data_avg/other_data_avg
        set hive.groupby.skewindata=true;#默认false 
        select* from A from group by a; # a.hashcode()%3=partitionNo
        #sql manunal
        抽样统计,是否倾斜,倾斜程度:20%的键占用了80%的数据
        倾斜建加分割前缀加盐,分组统计,趋盐后再分组统计
        
    #Map后Reduce输出过多小文件合并
        #若满足以下设置条件,任务结束后会单起MapReduce对文件进行合并
        set hive.merge.mapfiles=true;#默认为true,map-only输出是否合并
        set hive.merge.mapredfiles=true;#默认为false,mapreduce输出是否合并
        set hive.merge.size.per.task=256M;#默认256M;合并文件上限
        set hive.merge.smallfiles.avgsize=16M;#默认16M;合并文件下限
        
#控制Mapper和Reducer数量
    ########
    #Mapper#mapper的启动和初始化开销较大,【】
    ########
    int default_num=total_file_size/dfs.block.size;#默认的Mappper数量
    set mapred. map.tasks;#默认为2,只有大于default_num时才会生效
    
    #Mapper数量限制
    #切片大小 Math.max(min.split.size,Math.min(dfs.block.size,max.split.size))
    set dfs.block.size=128M;#默认128M
    set mapred.max.split.size=256M;#默认单个Mapper处理数据上限256M
    set mapred.min.split.size=1;#默认1个字节
    set mapred.min.split.size.per.node=1;#默认单个节点处理的数据下限1个字节
    set mapred.min.split.size.per.rack=1;#默认单个机架处理的数据下限1字节
    
    #Mapper输入对个小文件合并后再切片
    set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
    

计算map个数
blockSize:HDFS的文件块大小
totalSize:输入文件大小
inputFileNum:输入文件的数量

默认map个数
如果不进行任何设置,默认的map个数是和blockSize相关的,defaultNum=totalSize/blockSize
期望个数
可以通过参数mapred.map.tasks来设置期望的map个数,但这个只有在大于默认map个数的时候才生效,goalNum=mapred.map.tasks
设置处理的文件大小
可以通过mapred.min.split.size设置每个task处理的文件大小,但是这个大小只有在大于blockSize的时候才会生效
splitSize=max(mapred.min.split.size,blockSize)
splitNum=totalSize/splitSize
计算的map个数
computeMapNum=min(splitNum,max(defaultNum,goalNum))
除了以上这些配置外,MapReduce还要遵循一些原则。MapReduce的每一个map处理数据是不能跨越文件的。也就是说minMapNum>=inputFileNum,
所以,最终的map个数应该为:
mapNum=max(computeMapNum,inputFileNum)

#########
#Reducer#
#########
    
    set mapred.reduce.tasks=1;#默认-1,可以根据需求在客户端设置

    #如未按设置 mapred.reduce.tasks 自动计算 Reducer数量
    #Math.min(SIZE/bytes.per.reducer,max)
    set hive.exec.reducers.bytes.per.reducer=256M;默认每个reducer的数据为256M;
    set hive.exec.reducers.max=1009;#默认单个任务最大的reducer数量

    #Reducer为1的情况
    #没有group by,直接使用sum,count,max,min,avg,collect_list,concat_ws等聚合函数
        #优化方案    先选一个键分组,同键分组聚合,最后在总聚合
        select sum(sum_a) from (select sum(a) from A group by TEMP) T
    #使用order by    (会在一起排序)
        #优化方案
        #group by 和distribute by 区别:group by 同键分组且必须聚合;distribute by 仅按键分散数据
        #order by 全局排序仅一个Reducer,sort by仅分区内有序
        #被distribute by设定的字段为KEY,数据会被HASH分发到不同的reducer机器上,
        #然后sort by会对同一个reducer机器上的每组数据进行局部排序。
        #distribute+sort的结果是按组有序而全局无序的,在distribute+sort后再进行orderby阶段,实现间接的全局排序
        set mapred.reduce.tasks=3;
        select * from (select * from A distribute by a sort by a ) order a;

    #存在笛卡尔积,尽量不用(一张表的每一行和另一张表的所有行关联)(打散道多台机器上关联)
        #若出现小表+大表的笛卡尔积
            1.小表扩展,根据需求随机生成n个join ke
            2.大表扩展复制n份,每一份添加小表的一个的join key,n份对应小表的n个join key
            3.大表每一份根据join key和小表分别关联起来

    #减少数据规模
        #调整数据存储格式
            #create建表的默认格式和分区表        
                set hive.default.fileformat=orc;#默认TextFile,可选:orchid,RCFile,SequenceFile
            
            #提升IO性能,但会增加CPU压力        
                set hive.exec.compress.output=true;#默认false,任务输出是否压缩
                set hive.exec.compress.intermediate=true;#默认false,任务过程输出是否压缩

            #动态分区
                set hive.exec.dynamic.partition=true;#默认开启
                set hive.exec.dynamic.partition.mode=nonstrict;#默认strict
                set hive.exec.max.dynamic.partitions=1000;#默认最大动态分区数1000
                set hive.exec.max.dynamic.partitions.pernode=100;#默认单节点最大动态分区数100

            #count(distinct)
                不妥:select count(district b) from TAB group by a 
                稳妥:select count(b) from (select a,b from TAB group by a,b) group by a
                
                select count(distinct colA) from table1;
                select count(1) from (select colA from table1 group by colA)alias_1;
                
            #筛选条件放在子查询或on之后:开启谓词下推(见以下表格)
            
                #谓词下推:就是在不影响结果的情况下,尽量将过滤条件提前执行。
                #谓词下推后,过滤条件在map端执行,减少了map端的输出,降低了数据在集群上传输的量,节约了集群的资源,也提升了任务的性能。
                #条件尽量放在on或子查询中
                set hive.optimize.ppd=true;#默认为true
                    
                Join(inner join)            Left Outer Join                Right Outer Join            Full Outer Join
                Left Table    Right Table        Left Table    Right Table        Left Table    Right Table        Left Table    Right Table
Join Predicate    Pushed    Pushed                Not Pushed    Pushed            Pushed        Not Pushed        Not Pushed    Not Pushed
Where Predicate    Pushed    Pushed                Pushed        Not Pushed        Not Pushed    Pushed            Not Pushed    Not Pushed
                
            #列裁剪
            set hive.cbo.enable=true;#默认为true

            #分区裁剪
                #以on,where多条件字段顺序,建【多重】分区表

                默认开启支持,以分区字段为条件筛选数据
                tez引擎:动态分区剪裁支持 不要动
                set hive.execution.engine=tez;#默认mr,tez|spark DAG
            
            #并行执行无依赖job
                set hive.exec.parallel=true;#默认false(关闭)
                set hive.exec.parallel.thread.number=8;#默认8,最大并行任务数

            #jvm重用
                #依赖hadoop mapred-site.xml以下配置
                mapreduce.job.jvm.numtasks=8; #每个jvm运行的任务数

            #本地化运算
                set mapred.reduce.tasks=0/1;#默认-1,启动本地化模式,reducer数量必须为0|1
                set hive.exec.mode.local.auto.input.files.max=4;#默认4,本地化文件数量上限
                set hive.exec.mode.local.auto.inputbytes.max=128M;#默认128M,本地化文件大小上限
                set hive.exec.mode.local.auto=true;#默认false,hive决定是否启用本地化模式
                #可能会导致内存溢出:java.lang.OutOfMemoryError: java heap space
                #修改  mv hive-env.sh.template hive-env.sh
                #vim hive-env.sh
                ###########################
                #去掉注释
                export HADOOP_HEAPSIZE=1024
                ###########################

            #LLAP
            set hive.execution.mode=llap;#默认container,2.0之后扩展此项,llap可选
            #llap为DataNode常驻进程,混合模型,小型任务可以由llap解决,大型任务有yarn容器执行

            #fetch
            set hive.fetch.task.conversion=more;#默认more,简单查询不走mr,直接提取

            #explain select ... 查看执行计划

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值