欢迎投稿

今日深度:

Hive 优化,

Hive 优化,


Hive 优化

问题:
    数据倾斜(sum ,count 不存在数据倾斜)
    jobs 多
    count(distinct)效率低,数据量一多就出问题

方案:
    设计一个好的数据模型
    减少jobs数
    设置合理的mapper reducd 数目
    对小文件进行合并
    ----------
    1.1 join 优化
        Join 查找操作的基本原则:应该将条目少的表/子查询放在 Join 操作符的左边。原因
        是在 Join 操作的 Reduce 阶段,位于 Join 操作符左边的表的内容会被加载进内存,将
        条目少的表放在左边,可以有效减少发生内存溢出错误的几率。
        Join 查找操作中如果存在多个 join,且所有参与 join 的表中其参与 join 的 key 都相
        同,则会将所有的 join 合并到一个 mapred 程序中。
    1.2 group by 优化

        Map 端聚合,首先在 map 端进行初步聚合,最后在 reduce 端得出最终结果,相关参数:
        hive.map.aggr = true 是否在 Map 端进行聚合,默认为 True
        hive.groupby.mapaggr.checkinterval = 100000 在 Map 端进行聚合操作的条目数目
        数据倾斜聚合优化,设置参数 hive.groupby.skewindata为 true,生成的查询计划会有两个 MR Job。第一个=true,当选项设定
        MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是
        相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过
        程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。

    1.3 合并小文件
        文件数目过多,会给 HDFS 带来压力,并且会影响处理效率,可以通过合并 Map 和 Reduce 的结果文件来消除这样的影响:
         hive.merge.mapfiles = true 是否和并 Map 输出文件,默认为 True
         hive.merge.mapredfiles = false 是否合并 Reduce 输出文件,默认为 False
         hive.merge.size.per.task = 256*1000*1000 合并文件的大小

    1.4 Hive 实现(not) in
        通过 left outer join 进行查询,(假设 B 表中包含另外的一个字段 key1
        select a.key from
        a left outer join
        b on a.key=b.key where
        b.key
        1 is null
        通过 left semi join 实现
        in
        SELECT a.key, a.val FROM a
        LEFT SEMI
        JOIN b on (a.key = b.key)
        Left semi join 的限制:join 条件中右边的表只能出现在 join 条件中


    1.5、排序优化
        Order by 实现全局排序,一个 reduce 实现,效率低
        Sort by 实现部分有序,单个 reduce 输出的结果是有序的,效率高,通常和
        DISTRIBUTE BY 关键字一起使用(DISTRIBUTE BY 关键字 可以指定 map 到reduce端的分发 key
        CLUSTER BY
        col1 等价于 DISTRIBUTE BY col1 SORT BY col1


    1.6、使用分区
        Hive 中的每个分区都对应 hdfs 上的一个目录,分区列也不是表中的一个实际的字段,
        而是一个或者多个伪列,在表的数据文件中实际上并不保存分区列的信息与数据。
        Partition 关键字中排在前面的为主分区(只有一个),后面的为副分区
        静态分区:静态分区在加载数据和使用时都需要在 sql 语句中指定
            案例:(stat_date='20120625',province='hunan')
        动态分区:使用动态分区需要设置 hive.exec.dynamic.partition 参数值为 true,默认值为false
        ,在默认情况下,hive 会假设主分区时静态分区,副分区使用动态分区;如果想都使用动态分区,需要设置 set hive.exec.dynamic.partition.mode=nostrick,默认为strick
            案例:(stat_date='20120625',province)

    1.7 Distinct 使用

        Hive 支持在 group by 时对同一列进行多次 distinct 操作,却不支持在同一个语句中对
        多个列进行 distinct 操作。



    1.8 UDTF
        UDTF 将单一输入行转化为多个输出行,并且在使用 UDTF 时,select 语句中不能包含
        其他的列,UDTF 不支持嵌套,也不支持 group by 、sort by 等语句。如果想避免上述限
        制,需要使用 lateral view 语法,案例:

        继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF,实现initialize, process, close三个方法。
        UDTF首先会调用initialize方法,此方法返回UDTF的返回行的信息(返回个数,类型)。
        初始化完成后,会调用process方法,真正的处理过程在process函数中,在process中,每一次forward()调用产生一行;如果产生多列可以将多个列的值放在一个数组中,然后将该数组传入到forward()函数。
        最后close()方法调用,对需要清理的方法进行清理。

www.htsjk.Com true http://www.htsjk.com/hive/41275.html NewsArticle Hive 优化, Hive 优化 问题: 数据倾斜(sum ,count 不存在数据倾斜) jobs 多 count(distinct)效率低,数据量一多就出问题方案: 设计一个好的数据模型 减少jobs数 设置合理的mapper reducd 数...
相关文章
    暂无相关文章
评论暂时关闭