hive调优

自定义函数

  • hive内置函数不满足业务可以使用java写自定义函数导入hive
  • UDF函数:大部分都是,

    • 一进一出
  • UDAF

    • 多进一出

      • 如:聚合函数
  • UDTF

    • 一进多出

      • 如:explode

hive调优

压缩

  • 压缩方案常用的gzip,bzip2,lzo,snappy,考虑的不仅是压缩后体积,而应该再结合解压和压缩的速度

image.png

  • 设置不同阶段的输出

    • 输入map,
    • map输出到reduce时,
    • reduce输出时可以压缩
  • 配置压缩参数可以到mapred-site.xml,core-site.xml中

    • io.compression.codecs
    • mapreduce.map.output.compress
    • mapreduce.output

存储格式

  • textFile行,sequenceFile行,orc列,parquet列是
  • 常用textFile,orc

    • 只有textFile支持load加载
  • 行式存储,列式存储

    • 空间,查询速度

      • 行存储在查找时只需要找到其中一个值其余的数据在相邻位置
      • 列存储可以有针对性的查找,而舍弃一些无关数据查找的损耗

        • 压缩明显
        • 减少不必要的io开销
        • 数据空间小,读盘更快
        • 自由的压缩算法,更灵活

image.png

其他优化

  • fetch本地抓去,能不走mr尽量不走
  • 能本地mr尽量本地mr

hive join优化

  • 编写sql时:1.x之前小表在join前面。之后都一样
  • 小表和大表join

    • hdfs提供distribute block cache分布式块缓存
    • 自动开启mapjoin
    • 配置大小表阈值
  • 中大型表join大表

    • 先过滤(看是否可以转为小表)再join
    • bucket join: 分桶的mapjoin方案
  • 大表和大表

    • 先过滤再join,减少map到reduce数据传输量
    • 如果大表中的数据有很多空值,需要解决, 因为空值会导致reduce容易出现数据倾斜

      • 方案一:提前过滤null
      • 方案二:随机数替换null
    • SMB JOIN :分桶表排序 MAPJOIN方案

sql优化

  • 列裁剪
  • 分区裁剪

    • 操作分区表,建议携带上分区字段,从而减少扫描量,提升效率,同时如果表能过滤,就先过滤再join
  • combiner解决数据倾斜
  • 两次mr,将数据不论男女平均分发给两个reduce
  • 避免count(distinct) ,对整个表进行聚合操作翻译后只有一个reduce,若此时执行一个distinct(reduce中执行),而去重操作必须在reduce端才可以,数据量大的话,reduce端会承受大量数据,导致执行效率变慢
select count(ip) from (select ip from table group by ip) tmp;
执行两个mr后面那个可用于去重,先group by再count虽然会多一个job但是在数据量大的情况下会更优
  • 笛卡尔积:hive中多表join不给on(一边关联,一边过滤),不能用where(先笛卡尔再条件过滤)

动态分区

  • sql查询原始表中,必须要将分区字段放置在整个表结果最后面
  • 关闭hive严格语法模式
insert into table 分区表2 partition(month) select * from 分区表1;

动态倾斜

  • 如何调整map数量和reduce数量

    • 缩小map数:

      • map之前合并文件
      • 调大文件切片
    • 增大map数:

    -

    • combiner
    • 默认hive会自动调整reduce数量

      • hive.exec.reducers.max 默认999
      • hive.exec.reducers.bytes.per.reducer 调小reducer增多
      • order by只有一个reduce,没有group by的聚合只有一个reduce,笛卡尔积也只有一个(关联的时候用了where)

并行执行

  • 执行hive sql时可能会被翻译为多个mr,并且多个mr之间没有任何关联,那么此时可以运行多个mr并行执行提升效率
  • set hive.exec.parallel=true; -- 打开任务并行执行执行
  • set hive.exec.parallel.thread.number = 16; -- 最大并行读,默认为8
select * from A
union all
select * from B;

严格模式(数据量大的情况下): 限制(执行效率差的)sql的请求

  • 分区表查询,不携带分区字段
  • 使用order by 不用limit
  • sql中出现笛卡尔

内置的jvm重用

  • 让mr可重复使用资源容器

推测执行

  • 关掉,否则失败重复申请资源做相同的任务,仍然有大概率失败

你可能感兴趣的:(hive)