Hive优化(提高hive运行速度)

文章目录

  • 一、Hive使用本地模式执行操作(Hive使用资源大于20M的时候还是会采用集群yarn的方式运行)
    • 具体设置方法
      • 1.1、设置临时的
      • 1.2、修改hive配置文件(hive-site.xml),永久有效
  • 二、盡量多使用group by 來去重
    • 2.1、问题:Ggroup by非常容易造成数据倾斜 将Map阶段同一Key数据分发给一个reduce,
    • 2.2、解决方法:
      • 2.2.1、是否在Map端进行聚合,默认为True
      • 2.2.2、有数据倾斜的时候进行负载均衡(默认是false)
      • 2.2.3、这样解决的原因
  • 三、大小表 join的时候 把小表放在左边,这样就会把小表放到内存中 进行 map端join 较少了数据倾斜和提高运行效率
  • 四、空KEY过滤或者空key转换
  • 五、慎用count(distinct)
  • 六、避免笛卡尔积(漏斗模型除外)
  • 七、行列过滤
  • 八、合理设置Map及Reduce数
      • 8.1、合理设置 Map及Reduce数 的原因
      • 8.2、如果业务逻辑比较复杂 需要多启动map任务
        • 8.2.1、增加map的原理为:
        • 8.2.2、增加map的方法为:
        • 8.2.3、如果hive中小文件过多 需要进行合并时,使用CombineHiveInputFormat,他具有对小文件进行合并的功能
    • 九、分区(https://blog.csdn.net/qq_44472134/article/details/104105719)
    • 十、分桶 (https://blog.csdn.net/qq_44472134/article/details/104105719)
    • 十一、设置严格模式

一、Hive使用本地模式执行操作(Hive使用资源大于20M的时候还是会采用集群yarn的方式运行)

将hive的job交给yarn执行太慢,hive支持本地模式
設置本地模式之前的,耗時 9.068
Hive优化(提高hive运行速度)_第1张图片
設置本地模式之后的,耗時 0.29Hive优化(提高hive运行速度)_第2张图片

具体设置方法

1.1、设置临时的

在每次执行hql语句之前 都要先执行下面这句话

 set hive.exec.mode.local.auto=true;

1.2、修改hive配置文件(hive-site.xml),永久有效


    hive.exec.mode.local.auto
    true

注意 今天发现这种设置永久有效的方式,不够灵活,如果后期查询语句需要占用内存过大的时候 极 容易报错,所以,我就又在 hive-site.xml 中把这几行 注释了。每次都用临时,就比较灵活了。

二、盡量多使用group by 來去重

2.1、问题:Ggroup by非常容易造成数据倾斜 将Map阶段同一Key数据分发给一个reduce,

当一个key数据过大时就倾斜了。

2.2、解决方法:

开启map端聚合 相当于combiner

2.2.1、是否在Map端进行聚合,默认为True

set hive.map.aggr = true(默认已经是true)

2.2.2、有数据倾斜的时候进行负载均衡(默认是false)

set hive.groupby.skewindata = true

2.2.3、这样解决的原因

生成两个mr job,第一个mr 把相同的key 分发到不同的reduce做一个聚合 从而达到负载均衡的目的
第二个mr 将相同的key分发到一个reduce中,最后完成最终的聚合操作。

三、大小表 join的时候 把小表放在左边,这样就会把小表放到内存中 进行 map端join 较少了数据倾斜和提高运行效率

但是在新版本中 hive已经做了优化 小表坊左边和右边已经没有区别

四、空KEY过滤或者空key转换

大表和大表join 如果大表中有很多的空key 这么这些null值 就会被拿去到一个reduce中 ,造成数据倾斜
所以可以使用空KEY过滤或者空key转换 来减少数据倾斜发生,负载均衡reducer的资源消耗

五、慎用count(distinct)

因为count(distinct) 无论设置几个reduce 只会生成一个reduce任务,这就造成一个Reduce处理的数据量太大,导致整个Job很难完成
所以一般使用count+gruopby的方式来进行代替

六、避免笛卡尔积(漏斗模型除外)

join的时候不加on条件,或者无效的on条件,Hive只能使用1个reducer来完成笛卡尔积。

(distinct) 和笛卡尔积 都会产生一个 reducer进行数据处理 所以说用count+gruopby来代替distinct,除了漏斗模型之外,其余场景避免使用笛卡尔积

七、行列过滤

列处理上 只select 需要的列 尽量使用分区过滤 少用select *
行处理上 最好要先进行 where 过滤再进行join 提高效率
Hive优化(提高hive运行速度)_第3张图片

八、合理设置Map及Reduce数

8.1、合理设置 Map及Reduce数 的原因

1)通常情况下,作业会通过input的目录产生一个或者多个map任务。
主要的决定因素有:input的文件总个数,input的文件大小,集群设置的文件块大小。
2)是不是map数越多越好?
答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。
3)是不是保证每个map处理接近128m的文件块,就高枕无忧了?
答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。
针对上面的问题2和3,我们需要采取两种方式来解决:即减少map数和增加map数;

8.2、如果业务逻辑比较复杂 需要多启动map任务

8.2.1、增加map的原理为:

根据computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M公式,调整maxSize最大值。让maxSize最大值低于blocksize就可以增加map的个数。

8.2.2、增加map的方法为:

设置最大切片值 合理调整map的数量
set mapreduce.input.fileinputformat.split.maxsize=100

8.2.3、如果hive中小文件过多 需要进行合并时,使用CombineHiveInputFormat,他具有对小文件进行合并的功能

(1)在map执行前合并小文件,减少map数:CombineHiveInputFormat具有对小文件进行合并的功能(系统默认的格式)。HiveInputFormat没有对小文件合并功能。

set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

(2)在Map-Reduce的任务结束时合并小文件的设置:
在map-only任务结束时合并小文件,默认true
SET hive.merge.mapfiles = true;
在map-reduce任务结束时合并小文件,默认false
SET hive.merge.mapredfiles = true;
合并文件的大小,默认256M
SET hive.merge.size.per.task = 268435456;
当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
SET hive.merge.smallfiles.avgsize = 16777216;

九、分区(https://blog.csdn.net/qq_44472134/article/details/104105719)

十、分桶 (https://blog.csdn.net/qq_44472134/article/details/104105719)

十一、设置严格模式

Hive提供了一个严格模式,可以防止用户执行那些可能意想不到的不好的影响的查询。
通过设置属性hive.mapred.mode值为默认是非严格模式nonstrict 。开启严格模式需要修改hive.mapred.mode值为strict,开启严格模式可以禁止3种类型的查询。

<property>
    <name>hive.mapred.mode</name>
    <value>strict</value>
    <description>
      The mode in which the Hive operations are being performed. 
      In strict mode, some risky queries are not allowed to run. They include:
        Cartesian Product.
        No partition being picked up for a query.
        Comparing bigints and strings.
        Comparing bigints and doubles.
        Orderby without limit.
</description>
</property>
  1. 对于分区表,除非where语句中含有分区字段过滤条件来限制范围,否则不允许执行。换句话说,就是用户不允许扫描所有分区。进行这个限制的原因是,通常分区表都拥有非常大的数据集,而且数据增加迅速。没有进行分区限制的查询可能会消耗令人不可接受的巨大资源来处理这个表。
  2. 对于使用了order by语句的查询,要求必须使用limit语句。因为order by为了执行排序过程会将所有的结果数据分发到同一个Reducer中进行处理,强制要求用户增加这个LIMIT语句可以防止Reducer额外执行很长一段时间。
  3. 限制笛卡尔积的查询。对关系型数据库非常了解的用户可能期望在执行JOIN查询的时候不使用ON语句而是使用where语句,这样关系数据库的执行优化器就可以高效地将WHERE语句转化成那个ON语句。不幸的是,Hive并不会执行这种优化,因此,如果表足够大,那么这个查询就会出现不可控的情况。

你可能感兴趣的:(#,hive數據倉庫操作,#,新增知识)