[大数据] HiveQL知识点

Q1:什么是数据倾斜,怎么产生,怎么解决?

查询时,mapper的结果经过shuffle,按照key的hash来分配到不同的reducer上,如果分配不均匀,导致其中一个或几个reducer的运行时间过长,导致整个mapreducer完成得很慢,这就是数据倾斜。
  原因可能是,join、group by、count(distinct )的时候,key的值比较集中,导致这个值的大量数据全放到一个reducer里,如果这个key有大量null值,也导致数据倾斜;
  解决方法是:
  1. 增大reducer个数
  2. 设置负载平衡(会生成两个MR job,先后执行。第一个是随机分配到reducer,可以平衡负载,实现初步的聚合,减少后面的工作量。第二个按照key的hash取mod之后分配到reducer,完成最终的聚合)
  3. 小表join大表时,使用mapjoin,可以让小表存入内存,只在map端进行聚合。把小表写在前,大表写在后。
  4. 有大量null值时,把null值变成一个字符串加上随机数,反正join时关联不上,不会影响最终结果
  5. 需要实现count(distinct )的时候,先对key做group by,然后count(1)即可
  注意:对于count(),sum()这种可以由部分结果得到最终结果的聚合函数,方法2、3是有效的,但是对于avg(),mean()这种不能由部分结果得到最终结果的聚合函数,是无效的。
   [ 原理 ]

Q2:什么是hive的严格模式(strict mode)?

用来限制某些后果不好的查询,它们会消耗大量资源,包括:
  1. 如果表使用了分区,但是查询没有用where过滤分区
  2. 使用了order by,但是没有加limit限制
  3. 笛卡尔乘积,即join不用on而是用where的

Q3:order by, sort by, distribute by, cluster by的区别?

1. 使用order by的话,全局排序,所有数据最终在一个reducer里排序,耗时较多,在strict mode下,必须加limit限制,适用于数据量不太大的场景(不清楚加了limit之后是否影响结果???)
  2. 使用sort by的话,局部排序,数据分别在各自的reducer排序,不保证最终结果有序
  3. distribute by,在map端控制按照哪个字段的hash值分发给各个reducer,通常配合sort by使用,相当于分组排序,distribute by X sort by X相当于全局排序。适用于数据量比较大的排序场景,sort by一定要放在distrubute by后面。例如对于表

typepricebrand
noodle1600huafeng
bread1231meixin
noodle1221tongyi
beer1432zhujiang
select type, price, brand from store distribute by type sort by type asc, price asc

type相同的会放入同一个reducer,同一个reducer内按照type和price排序,相当于做了分组排序,结果如下

typepricebrand
beer1432zhujiang
bread1231meixin
noodle1221tongyi
noodle1600huafeng

4.cluster by相当于distribute by X sort by X,但是只能降序排列

Q4:collect_all()的作用?

属于一种聚合函数,与group by配合使用,可以把组内某个字段所有取值拿出来,作为新的字段。collect_set()、collect_list()作用类同。

Q5:三个排名函数的区别?

1. row_number()返回连续、不重复的排名,key相同时排名也不重复
  2. dens_rank()返回连续、重复的排名
  3. rank()返回不连续、重复的排名
  例如对于:3 3 4 5 5 6  
|排名函数|返回排名|
|:|:|
|row_number() |1 2 3 4 5 6 |
|dens_rank() |1 1 2 3 3 4 |
|rank() |1 1 3 4 4 6 |

Q6:Hive原理

hive是运行在hadoop之上的一个数据仓库框架,数据放在HDFS上,查询使用MapReduce来执行查询。它支持类似SQL的语言,它其实是个编译器,把SQL编译为MapReduc的作业。
  因为基于Hadoop,它拥有hadoop的所有优点和缺点。
  优点:
  使用类SQL语言,非常方便
  使用磁盘而不是内存,所以能处理海量数据,很适合处理大规模的离线数据分析处理。
  高容错性,自动备份数据,自动检测并回复故障。
  缺点:
  数据一词写入多次写出,因此已有的数据表不可更新。
  不能做到低延迟

Q7:Hive存储元数据的方式?

1. 存在内存derby存储,只能开一个客户端,不推荐
  2. 存在MySQL数据库,可以多客户端使用,推荐

Q8:Hive优化方法

1. join优化。小表放在join左边,大表放在join右边。因为join在reducer端时,左表会放入内存,所以小表最好放左边
  2. 少用order by优化。order by只在一个reducer内排序,太慢了。使用distribute by X sort by X也能达到全局排序。
  3. 尽早过滤数据,例如使用分区。
  4. 其他参考这篇,写得很好 [ 数据分析利器之hive优化十大原则 ]

Q9:什么时候可以用别名,什么时候不可以?

由于sql在执行语句的时候,是按照以下顺序执行的:

where->group by->having->select->order by

因为别名是在select里面取的,要在select之后才能被识别,所以where,group by, having都不可以用别名,order by可以用别名。
解决方法:
  1. 在where,group by, having用原字段构成的表达式
  2. 在在内层加个子查询,把字段名字改了,再在外层用where,group by, having

Q10:hive怎么确定mapper、reducer的个数?
  1. 对于mapper:根据传入文件的个数及大小,一个文件对应一个mapper,若文件超出128M,则拆分到两个mapper
  2. 对于reducer:根据输入的数据量,及以下两个参数,hive自动估计

hive.exec.reducers.bytes.per.reducer(每个reducer最多可接受数据量,默认为1000^3)
hive.exec.reducers.max(集群中最多可以开多少个reducer,默认为999)

但是mapper不宜过多,每个mapper都需要启动的开销,一个mapper启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。

Q11:分区、分桶、索引的区别?
  1. 分区:hive通常会对全表扫描,如果使用了分区,就避免全表扫描,提高查询效率。Hive的分区使用HDFS的子目录功能实现,把一个大表的数据按照某个字段划分,分别放到不同的文件夹里,文件夹名字就是“字段+字段值”。但是这个字段其实是伪字段,它并不存在于表的数据里。
  2. 分桶:在分区数量过于庞大以至于可能导致文件系统崩溃时,我们就需要使用分桶来解决问题了。分桶将整个表或者某个分区内所有数据,按照某字段的hash值取模进行区分。分桶可以指定桶的个数,不像分区不确定分区的个数(可能会出现很多个分区)。如果join的两个表对key字段都做了分桶,那么是很有利于mapjoin的。分桶是依据数据表中真实的字段而不是伪字段。
  3. 索引:在hive中比较少用,适用于不更新的静态字段,以免总是重建索引数据。每次建立、更新数据后,都要重建索引以构建索引表。使用索引查询时,首先需要一个mp job来扫描索引表,然后才能去扫描表数据,非常繁琐。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值