大数据 003hive基础知识2
1.大表join小表产生的问题,怎么解决?
mapjoin方案
- join因为空值导致长尾(key为空值是用随机值代替)
- join因为热点值导致长尾,也可以将热点数据和非热点数据分开处理,最后合并
2.udf udaf udtf区别
- UDF操作作用于单个数据行,并且产生一个数据行作为输出。大多数函数都属于这一类(比如数学函数和字符串函数)。
- UDAF 接受多个输入数据行,并产生一个输出数据行。像COUNT和MAX这样的函数就是聚集函数。
- UDTF 操作作用于单个数据行,并且产生多个数据行——-一个表作为输出。lateral view explore()
简单来说:
- UDF:返回对应值,一对一
- UDAF:返回聚类值,多对一
- UDTF:返回拆分值,一对多
3.hive有哪些保存元数据的方式,个有什么特点。
- 内存数据库derby,安装小,但是数据存在内存,不稳定
- mysql数据库,数据存储模式可以自己设置,持久化好,查看方便。
4.hive内部表和外部表的区别
- 内部表:加载数据到hive所在的hdfs目录,删除时,元数据和数据文件都删除
- 外部表:不加载数据到hive所在的hdfs目录,删除时,只删除表结构。
这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。
5.生产环境中为什么建议使用外部表?
- 因为外部表不会加载数据到hive,减少数据传输、数据还能共享。
- hive不会修改数据,所以无需担心数据的损坏
- 删除表时,只删除表结构、不删除数据。
6.insert into 和 insert overwrite区别?
- insert into:将数据追加写到表中
- insert overwrite:覆盖之前的内容,先删除分区或表数据在写入
7.hive的判断函数有哪些
hive 的条件判断(if、coalesce、case)
8.简单描述一下HIVE的功能?用hive创建表有几种方式?hive表有几种?
- hive主要是做离线分析的,把hiveSQL转换成mapreduce程序,提交到yarn集群上运行,简化了mr程序的开发。
hive建表有三种方式
- 直接建表法
- 查询建表法(通过AS 查询语句完成建表:将子查询的结果存在新表里,有数据,一般用于中间表)
- like建表法(会创建结构完全相同的表,但是没有数据)
hive表有2种:内部表和外部表
9.union all和union的区别
- union 去重
- union oll 不去重
10.如何解决hive数据倾斜的问题
1.group by
注:group by 优于 distinct
- 情形:group by 维度过小,某值的数量过多
- 后果:处理某值的 reduce 非常耗时
- 解决方式:采用 sum() group by 的方式来替换 count(distinct)完成计算。
2.count(distinct)
count(distinct xx)
- 情形:某特殊值过多
- 后果:处理此特殊值的 reduce 耗时;只有一个 reduce 任务
- 解决方式:count distinct 时,将值为空的情况单独处理,比如可以直接过滤空值的行,
- 在最后结果中加 1。如果还有其他计算,需要进行 group by,可以先将值为空的记录单独处理,再和其他计算结果进行 union。
3.mapjoin
采用mapjoin方法,在map时候进行关联,适用于小表
4.不同数据类型关联产生数据倾斜
-
情形:比如用户表中 user_id 字段为 int,log 表中 user_id 字段既有 string 类型也有 int 类型。当按照 user_id 进行两个表的 Join 操作时。
-
后果:处理此特殊值的 reduce 耗时;只有一个 reduce 任务
默认的 Hash 操作会按 int 型的 id 来进行分配,这样会导致所有 string 类型 id 的记录都分配到一个 Reducer 中。
-
解决方式:把数字类型转换成字符串类型
|
|
5.开启数据倾斜时负载均衡
- set hive.groupby.skewindata=true;
- 思想:就是先随机分发并处理,再按照 key group by 来分发处理。
- 操作:当选项设定为 true,生成的查询计划会有两个 MRJob。
第一个 MRJob 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 GroupBy Key 有可能被分发到不同的Reduce 中,从而达到负载均衡的目的;
第二个 MRJob 再根据预处理的数据结果按照 GroupBy Key 分布到 Reduce 中(这个过程可以保证相同的原始 GroupBy Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
点评:它使计算变成了两个 mapreduce,先在第一个中在 shuffle 过程 partition 时随机给 key 打标记,使每个 key 随机均匀分布到各个 reduce 上计算,但是这样只能完成部分计算,因为相同 key 没有分配到相同 reduce 上。
所以需要第二次的 mapreduce,这次就回归正常 shuffle,但是数据分布不均匀的问题在第一次 mapreduce 已经有了很大的改善,因此基本解决数据倾斜。因为大量计算已经在第一次mr 中随机分布到各个节点完成。
6.控制空值分布
将为空的 key 转变为字符串加随机数或纯随机数,将因空值而造成倾斜的数据分不到多个 Reducer。
注:对于异常值如果不需要的话,最好是提前在 where 条件里过滤掉,这样可以使计算量大大减少
11.hive性能优化常用的方法
1. MapJoin
如果不指定 MapJoin 或者不符合 MapJoin 的条件,那么 Hive 解析器会将 Join 操作转换成 Common Join,即:在 Reduce 阶段完成 join。容易发生数据倾斜。可以用 MapJoin 把小表全部加载到内存在 map 端进行 join,避免 reducer 处理。
2.行列过滤
- 列处理:在 SELECT 中,只拿需要的列,如果有,尽量使用分区过滤,少用 SELECT *。
- 行处理:在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在 Where 后面,那么就会先全表关联,之后再过滤。
3.列式存储
parquet,ORCFile
4.采用分区技术
partition(ptime=20210321070000)
5.合理设置 Map 数
-
通常情况下,作业会通过 input 的目录产生一个或者多个 map 任务。
主要的决定因素有:input 的文件总个数,input 的文件大小,集群设置的文件块大小。
-
是不是 map 数越多越好?
答案是否定的。如果一个任务有很多小文件(远远小于块大小 128m),则每个小文件也会被当做一个块,用一个 map 任务来完成,而一个 map 任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的 map 数是受限的。
-
是不是保证每个 map 处理接近 128m 的文件块,就高枕无忧了?
答案也是不一定。比如有一个 127m 的文件,正常会用一个 map 去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果 map 处理的逻辑比较复杂,用一个 map任务去做,肯定也比较耗时。
针对上面的问题 2 和 3,我们需要采取两种方式来解决:即减少 map 数和增加 map 数;
6.小文件进行合并
在 Map 执行前合并小文件,减少 Map 数:
- CombineHiveInputFormat 具有对小文件进行合并的功能(系统默认的格式)。
- HiveInputFormat 没有对小文件合并功能。
7.合理设置 Reduce 数
Reduce 个数并不是越多越好
1. 过多的启动和初始化 Reduce 也会消耗时间和资源;
2. 另外,有多少个 Reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;
在设置 Reduce 个数的时候也需要考虑这两个原则:
- 处理大数据量利用合适的 Reduce数;
- 使单个 Reduce 任务处理数据量大小要合适;
8.常用参数
|
|
9.开启 map 端 combiner(不影响最终业务逻辑)
|
|
10.压缩(选择快的)
设置 map 端输出、中间结果压缩。(不完全是解决数据倾斜的问题,但是减少了 IO 读写和网络传输,能提高很多效率)
11.开启 JVM 重用
13.简述delete,drop,truncate的区别
- delet 删除数据
- drop 删除表
- truncate 摧毁表结构并重建
14.四个by的区别
- Sort By:分区内有序;
- Order By:全局排序,只有一个 Reducer;
- Distrbute By:类似 MR 中 Partition,进行分区,结合 sort by 使用。
- Cluster By:当 Distribute by 和 Sorts by 字段相同时,可以使用 Cluster by 方式。Cluster by 除了具有 Distribute by 的功能外还兼具 Sort by 的功能。但是排序只能是升序排序,不能 指定排序规则为 ASC 或者 DESC。
15.分区分桶的区别,为什么要分区
- 分区表:原来的一个大表存储的时候分成不同的数据目录进行存储。如果说是单分区表,那么在表的目录下就只有一级子目录,如果说是多分区表,那么在表的目录下有多少分区就有多少级子目录。不管是单分区表,还是多分区表,在表的目录下,和非最终分区目录下是不能直接存储数据文件的
- 分桶表:原理和hashpartitioner 一样,将hive中的一张表的数据进行归纳分类的时候,归纳分类规则就是hashpartitioner。(需要指定分桶字段,指定分成多少桶)
分区表和分桶的区别除了存储的格式不同外,最主要的是作用:
-
分区表:细化数据管理,缩小mapreduce程序 需要扫描的数据量。
-
分桶表:提高join查询的效率,在一份数据会被经常用来做连接查询的时候建立分桶,分桶字段就是连接字段;提高采样的效率。