Hive
什么是Hive?
Hive是一个Apache提供的数据仓库的软件使用类SQL(Hql)对分布式存储的数据进行读取以及管理,Hive是基于Hadoop来使用的。底层会将sql转换成hadoop的MR来进行操作,hive执行效率较低,一般我们用它来进行离线处理,hive只提供读取功能
Hive中的数据倾斜:
原因:1.key分布不均
2.业务数据本身的原因 3.建表考虑不周 4.某些sql语句本身就要倾斜
5.分组
如何避免hive的数据倾斜?
给key一个随机的值,打散key。
Hive参数调节。Hive.map.aggr = true。 Hive.groupby.skewindata = true。作用,有数据倾斜的时候进行负载均衡,当设定为true时底层会生成俩个MRjob,第一个MRjob中Map输出的结果会随机的分配到reduce中,每个reduce都是做部分聚合操作,这样做的目的是相同的groupbykey分到不同的reduce中,会达到负载均衡的效果。第二个MRjob是按照预处理的结果按照group by key分布到reduce中(确保分到相同的key分到一个reduce中)最后完成最终的聚合操作。
Sql语句的调优:①使用join key分布最均匀的表作为驱动表。②大小表join时候让难度较小的表先进内存。③打表join的时候把空值的key变成一个字符串加上一个随机数,把倾斜的数据分到不同的reduce,④count distinct大量相同特殊值。
Hive中的sort by、order by、cluster by、distribute
by的区别
Sort by不是全局排序,在数据进入reduce中提前完成时排序。
Order by会对输入做全局排序,因此只有一个reduce 如果有多个reduce无法保证全局排序,计算规模较大,会造成时会很长。
Cluster by 除了具有distribute by的功能还具有sort by的功能。
Distribute by 按照指定的字段对数据进行划分输出到不同的reduce。
Hive的流程:
Driver:在hive中进行调度
Compiler:将Sql转换成MR
Exec:和YARN进行交互
Hive中的元数据
表名,字段名,分区名都属于元数据Hive的元数据对应的数据库目前只支持MySQL和Derby,默认是Derby。需要手动将元数据转移到数据库
三种保存方式:内嵌式云存储服务器:本地元存储服务器,远程元存储服务器。
四种表结构:
内部表:手动创建手动加载数据的表,删除时会将HDFS上的目录一起删除
外部表:建表去管理HDFS上的数据,外部表只能具体到目录,删除时删除表,而不会删除HDFS上的目录。
分区表:分区表通常是对数据的分类,每个分区都会在HDFS上生成一个目录,以分区作为查询条件会提高效率,如果跨分区会降低效率,动态分区:从一个未分区表中查询的数据放在以分区的表中
分桶表:按指定字段进行分桶,可以对分桶数据进行抽样,分桶机制默认是不开启的,需要手动开启,分数据的时候会计算指定字段的hash码值对桶数进行取余,取余结果是多少,这条数据就放在哪个桶中
抽样
数据类型
简单数据类型:整型,字符串类型,时间戳,浮点,日期型。
复杂数据类型:映射,map 结构体struct 数组 array
Hive中文件储存格式和文件压缩格式:
TextFile:默认格式 储存方式是行储存,数据不做压缩
SequenceFile:是Hadoop API 提供的一个二进制文件支持,具有使用方便,可压缩,可分割的特点
RCFile:按行分块,每块按列存储,不支持任意方式写入,只提供一种追加接口。
ORCFile: 按行分块。按列存储,压缩快。快速列存取
Hive中的三大自定义函数
UDF :单行进入,单行输出
UDAF: 多行进入,单行输出
UDTF,多行进入,多行输出
数仓和数据库的区别:
视图:
从原表中抽取常用的字段作为视图,如果存储在内存中,称为虚拟视图,如果在磁盘中称为物化视图,hive只支持虚拟视图,Hive在封装视图不会触发,当视图进行第一次select时,才会触发。
索引:
数据库中,会自动根据主键来建立索引,因为Hive,没有主键所以默认不建立索引,但是hive支持索引,可以针对任何一个字段来建立索引
Hive的优化:
当俩个表进行关联查询的时候,将小表放在内存中,然后去处理大表
如果进行联表查询的时候,如果附带where,可以先用子查询执行where语句,然后在进行联表查询
Group up
对数据进行分组,分完组会每一个组交个一个reduceTask来处理,那么就会导致数据倾斜
会自动将group by 拆分为俩个阶段。
4.distinct 和聚合函数 同时出现的时候,先用子查询完成去重过程,这样可以在聚合中降低计算压力。
-
调整切片数,当逻辑复杂的时候,可以将切片调小来增多任务数量,当逻辑简单时,可以将切片调大来减小任务数量
-
fetch抓取:修改配置文件hive.fetxh.task.conversion为more,修改好以后,全局查找以及字段查找 limit都不会触发MR任务。
-
行列过滤:列处理:只拿自己需要的列,如果有,尽量使用分区过滤。行处理:当使用外关联的时候,先完全过关联在过滤。
-
JVM的重用,缺点是task槽会被占用,一直等到任务完才释放。