• Hive优化


    Hive理论
    1、Hive是什么?一个sql解析引擎,将SQL解析成MR,Hive本质就是MR
    2、Hive不存数据的,数据实际存在HDFS上,元数据基本上都存在mysql上
    3、Hive内容是读多写少,不支持数据的改写和删除
    4、Hive的SQL和传统SQL区别:
    可扩展性:用户自定义函数
    1)UDF:用户自定义普通函数,例:map,一对一
    2)UDAF:用户自定义聚合函数,例:groupByKey,多对一
    3)UDTF:用户自定义表生成函数,例:flatMap,一对多
    数据检查:
    HQL(hive):读时模式
    加载load数据的速度非常快,加载过程中不需要对数据解析,仅仅涉及到文件的复制和移动
    但读的时候慢
    SQL(传统):写时模式
    加载数据的时候速度非常慢,但是读的时候快
    5、Hive体系架构
    1)用户接口Cli
    2)语句转化Driver:将SQl转换成MR
    3)数据存储:元数据(mysql)+实际数据(HDFS)
    默认derby:本地,单用户模式
    建mysql:多用户模式(本地+远程)

    6、Hive数据管理:
    1)Table:内部表
    2)External Table:外部表
    3)Partition:辅助查询,缩小查询范围,加快数据检索速度
    4)Bucket:桶,reduce,采样,控制reduce的数量

    7、Hive数据类型
    1)原生类型int string bool double
    2)复合类型

    8、hive优化(mapreduce优化)
    1)map优化
    优化并发个数
    block大小会影响并发度
    hive.map.aggr=true ,相当于开启Combiner功能

    2)reduce优化
    优化并发个数
    set mapred.reduce.tasks=10

    3)mapreduce出现痛点:只有一个reduce的情况
    1、没有group by
    2、order by,建议用distribute by和sort by来替代
    order by:全局排序,因此只有一个reduce,当输入数据规模较大时,计算时间消耗严重
    sort by:不是全局排序,如果用sort by排序,并且设置多个reduce,
    每个reduce输出是有序的,但是不保证全局排序
    distribute by:控制map端的数据如果拆分给redcuce,可控制分区文件的个数
    cluster by:相当于distribute by和sort by的结合,但是只默认升序排序

    先在map阶段进行排序,再根据不同的key进行分发
    例子1:select * from TableA distribute by userid sort by itemid;

    例子2:
    select * from TableA distribute by itemid sort by itemid asc;
    select * from TableA cluster by itemid;
    3、笛卡尔积
    使用join的时候,尽量有效的使用on条件

    4)mapreduce出现痛点:如何加快查询速度(横向尽可能多并发,纵向尽可能少依赖)
    1、分区Partition
    2、Map Join:指定表是小表,内存处理,通常不超过1个G或者50w记录
    3、union all:先把两张表union all,然后再做join或者group by,可以减少mr的数量
    union 和 union all区别:union相当记录合并,union all不合并,性能后者更优
    4、multi-insert & multi group by
    5、Automatic merge:为了多个小文件合并
    6、Multi-Count Distinct
    一个MR,拆成多个的目的是为了降低数据倾斜的压力
    7、并行执行:set hive.exec.parallel=true

    5)mapreduce出现痛点:如何加快join操作
    1、语句优化:
    多表连接:如果join中多个表的join key是同一个,则join会转化为单个mr任务
    表的连接顺序:指定大、小表
    Hive默认把左表数据放到缓存中,右边的表的数据做流数据
    2、如果避免join过程中出现大量结果,尽可能在on中完成所有条件判断

    SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key) WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

    ASELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key AND b.ds='2009-07-07' AND a.ds='2009-07-07')

     执行顺序是,首先完成2表JOIN,然后再通过WHERE条件进行过滤,这样在JOIN过程中可能会 输出大量结果,再对这些结果进行过滤,比较耗时。可以进行优化,将WHERE条件放在ON后 ,在JOIN的过程中,就对不满足条件的记录进行了预先过滤。

    6)并行实行:

    – 同步执行hive的多个阶段,hive在执行过程,将一个查询转化成一个或者多个阶段。

    某个特 定的job可能包含众多的阶段,而这些阶段可能并非完全相互依赖的,也就是说可以并行执行 的,这样可能使得整个job的执行时间缩短。

    hive执行开启:set hive.exec.parallel=true


    7)数据倾斜

    mapreduce解决数据倾斜问题
    1、大小表关联
    2、大大表关联

    操作

    • Join

    • Group by

    • Count Distinct

    • 原因

      • key分布不均导致的

      • 人为的建表疏忽

      • 业务数据特点

    • 症状

      • 任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。 • 查看未完成的子任务,可以看到本地读写数据量积累非常大,通常超过10GB可以认定为发生数据倾斜。

    • 倾斜度

      • 平均记录数超过50w且最大记录数是超过平均记录数的4倍。

      • 最长时长比平均时长超过4分钟,且最大时长超过平均时长的2倍。

    • 万能方法 • hive.groupby.skewindata=true

    H i v e 的优化——数据倾斜——大小表关联

    • 原因

      • Hive在进行join时,按照join的key进行分发,而在join左边的表的数据会首先读入内存,如果左边表的key相对 分散,读入内存的数据会比较小,join任务执行会比较快;而如果左边的表key比较集中,而这张表的数据量很大, 那么数据倾斜就会比较严重,而如果这张表是小表,则还是应该把这张表放在join左边。
    • 思路

      • 将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率 • 使用map join让小的维度表先进内存。
    • 方法

      • Small_table join big_table

    8)设置 hive的执行引擎

    set hive.execution.engine=spark;
    set spark.executor.memory=8g;
    set spark.executor.cores=4;

    9)优化 in/exists 语句

    虽然经过测试,hive1.2.1 也支持 in/exists 操作,但还是推荐使用 hive的一个高效替代方案:left semi join

    比如说:

    select a.id,a.name from a where a.id in (select b.id from b)

    select a.id,a.name from a where exists (select id from b where a.id = b.id )

    应该转换成:
    select a.id ,a.name from a left semi join b on a.id = b.id

    10) map join 能解释一下 map join 的原理吗

    理论分析:

    如果不指定MapJoin 或者不符合 MapJoin的条件,那么HIve 解析器会将Join操作转换成Common Join,即:在 Reduce阶段完成 Join。容易发生数据倾斜。

    可以用MapJoin 把小表全部加载到内存,在map端进行 join,避免 reducer处理。

    1)开启 MapJoin 参数设置:

    (1)设置自动选择MapJoin

    set hive.auto.convert.join = true ;默认为 true

    (2)大表小表的阀值设置(默认25M以下认为是小表)

    set hive.mapjoin.smalltable.filesize=25000000;

    2)MapJoin 工作机制

     首先是Task A,它是一个 Local Task(在客户端本地执行的Task),负责扫描小表b的数据,将其转换成一个HashTable的数据结构,并写入本地文件中,之后将该文件加载到

    DistributeCache中。

    接下来是Task B,该任务是一个没有Reduce的MR,启动MapTasks扫描大表a,在Map阶段,根据 a的每一条记录去和DistributeCache中 b表对应的HashTable关联,并直接输出

    结果。

    由于MapJoin没有Reduce,所以由Map直接输出结果文件,有多少个Map Task,就有多少个结果文件。

  • 相关阅读:
    JAVA消息对话框
    stringbuffer capacity()的疑问
    JAVA确认对话框
    c/c++实现获取NOD32升级账号密码
    复制构造函数(拷贝构造函数)
    使用VC将sqlite3.def转化为sqlite3.lib
    Windows下安装OpenSSL
    java中io与nio的使用
    使用 XStream 把 Java 对象序列化为 XML
    使用 XStream 把 Java 对象序列化为 XML
  • 原文地址:https://www.cnblogs.com/ssqq5200936/p/11300245.html
Copyright © 2020-2023  润新知