自定义函数
- hive内置函数不满足业务可以使用java写自定义函数导入hive
UDF函数:大部分都是,
- 一进一出
UDAF
多进一出
- 如:聚合函数
UDTF
一进多出
- 如:explode
hive调优
压缩
- 压缩方案常用的gzip,bzip2,lzo,snappy,考虑的不仅是压缩后体积,而应该再结合解压和压缩的速度
设置不同阶段的输出
- 输入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开销
- 数据空间小,读盘更快
- 自由的压缩算法,更灵活
其他优化
- 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可重复使用资源容器
推测执行
- 关掉,否则失败重复申请资源做相同的任务,仍然有大概率失败
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。