hive加载数据
1、使用 hdfs dfs -put '本地数据' 'hive表对应的HDFS目录下'
2、使用 load data inpath
hive shell命令行
// 将HDFS上的/input1目录下面的数据 移动至 students表对应的HDFS目录下,注意是 移动、移动、移动
load data inpath '/input1/students.txt' into table students;
3、create table xxx as SQL语句
insert into table xxxx SQL语句 (没有as)
insert into table students2 select * from students;
insert overwrite table students2 select * from students;
hive建表
使用默认建表方式
指定location
指定Hive表的数据的存储位置,一般在数据已经上传到HDFS,想要直接使用,会指定Location,通常Locaion会跟外部表一起使用,内部表一般使用默认的location
指定存储格式
指定储存格式为rcfile,inputFormat:RCFileInputFormat,outputFormat:RCFileOutputFormat,如果不指定,默认为textfile,注意:除textfile以外,其他的存储格式的数据都不能直接加载,需要使用从表加载的方式。
sql
create table students4 as select * from students2;
只建表不加载数据
create table students5 like students;
hive和数据库比较
数据存储位置
hive存储在hdfs中。
数据库将数据保存在块设备或者本地文件系统中。
数据更新
hive不建议对数据进行改写。
数据库中的数据通常需要进行修改的
执行延迟
数据规模较小时:hive执行延迟较高,数据库执行延迟较低。
当数据库规模大到超过数据库的处理能力的时候。hive的并行计算体现巨大优势。
数据规模
hive支持很大规模的计算
数据库可以支持的数据规模很小
架构
用户接口:client
元数据:Metastore
mysql
用mysql存储元数据的原因
1、支持多用户
2、获取元数据的操作需要立即相应 show table...
3、元数据一般不会很大
元数据存储在mysql上:表结构,表的目录,属性,对应的hdfs目录
hadoop
hdfs
负责存储
MapReduce
计算
yarn
资源调度
Driver
解析器
编译器
执行器
优化器
hadoop
hdfs
负责存储
MapReduce
计算
yarn
资源调度
内部外部表
内部表
删除内部表的时候,表中的数据(HDFS上的文件)会被同表的元数据一起删除
外部表
删除外部表的时候,只会删除表的元数据,不会删除表中的数据(HDFS上的文件) 建表语句加上external
一般在公司中,使用外部表多一点,因为数据可以需要被多个程序使用,避免误删,通常外部表会结合location一起使用
分区
静态分区
分区表实际上是在表的目录下在以分区命名,建子目录
进行分区裁剪,避免全表扫描,减少MapReduce处理的数据量,提高效率
一般在公司的hive中,所有的表基本上都是分区表,通常按日期分区、地域分区
分区表在使用的时候记得加上分区字段
增加分区:alter table students_pt add partition(pt='20210622');
减少分区:alter table students_pt drop partition(pt='20210112');
查看某个表的所有分区: show partitions students_pt; // 推荐这种方式(直接从元数据中获取分区信息)
动态分区
动态分区:根据数据中某几列的不同的取值 划分 不同的分区
// 分区字段需要放在 select 的最后,如果有多个分区字段 同理,它是按位置匹配,不是按名字匹配
insert into table students_dt_p partition(dt) select id,name,age,gender,clazz,dt from students_dt;
// 比如下面这条语句会使用age作为分区字段,而不会使用student_dt中的dt作为分区字段
insert into table students_dt_p partition(dt) select id,name,age,gender,dt,age from students_dt;
分桶
分桶实际上是对文件(数据)的进一步切分,分桶字段需要根据业务进行设定,可以解决数据倾斜问题
4个by
order by
为了保证全局有序,必须使用一个reduce任务对全局数据进行排序,效率非常低,尽量避免使用
group by
通常结合聚合函数一起使用
sort by
会对每一个reduce输出的结果进行排序,只能保证在相同的reduce任务中有序
distribute by
只是控制map端的输出结果如何分布到Reduce中,并不会对reduce中的数据进行排序 。类似MR中Partition,进行分区,结合sort by使用。
Cluster by
Cluster by=distribute by+sort by。当distribute by和sort by字段相同时,可以直接使用clueter by,排序只能是升序排序
函数
系统函数
集体细节参照hive第四天笔记
开窗函数
Rank
(1)RANK() 排序相同时会重复,总数不会变
(2)DENSE_RANK() 排序相同时会重复,总数会减少
(3)ROW_NUMBER() 会根据顺序计算
Over
(1)CURRENT ROW:当前行
(2)n PRECEDING:往前n行数据
(3) n FOLLOWING:往后n行数据
(4)UNBOUNDED:起点,UNBOUNDED PRECEDING 表示从前面的起点, UNBOUNDED FOLLOWING表示到后面的终点
(5) LAG(col,n):往前第n行数据
(6)LEAD(col,n):往后第n行数据
(7) NTILE(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,NTILE返回此行所属的组的编号。注意:n必须为int类型。
TopN
自定义函数
UDF
一进一出,用UDF函数解析公共字段
继承UDF,重写evaluate方法
UDTF
因为自定义函数,可以自己埋点Log打印日志,出错或者数据异常,方便调试。
一进多出,用UDTF函数解析事件字段
继承UDTF,重写3个方法
initialize(自定义输出的列名和类型)
process(将结果返回forword(result))
close
具体参考hive第四天笔记
优化
MapJoin
如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理
行列过滤
列处理
在SELECT中,只拿需要的列,如果有,尽量使用分区过滤,少用SELECT *。
行处理
在分区剪裁中,当使用外关联时,如果将副表的过滤条件写在Where后面,那么就会先全表关联,之后再过滤。
列式存储
采用分区技术
合理设置Map数
合理设置Reduce数
压缩
设置Map端输出,中间结果压缩(不完全是解决数据倾斜问题,但是减少了IO读写和网络传输,能提高很多效率)
采用tez引擎或者spark引擎
小文件问题(优化)
小文件如何产生的
动态分区插入数据,产生大量小文件,从而导致map数量剧增
reduce数量越多,小文件越多,reduce个数和输出文件是对应的
数据源本身就包含了大量小文件
小文件解决方案
在Map执行前合并小文件,减少Map数
merge
开启JVM重用
解决数据倾斜(数据分布不均)方法
怎么产生的数据倾斜
不同数据类型关联产生数据倾斜
解决方式:转换成相同的数据类型
控制空值分布
在生产环境经常会有大量空值数据进入到一个Reduce中,导致数据倾斜
解决数据倾斜的方法
group by
group by优于distinct group,解决方式:采用sum() group by的方式来替换count(distinct)完成计算。
mapjoin
开启数据倾斜时负载均衡
set hive.groupby.skewindata=true;
字段分隔符问题
Tez引擎
Tez优点
Tez可以将多个有依赖的作业转换为一个作业,这样只需要写一次HDFS,且中间节点较少,从而大大提升作业的计算性能。
Mr/tez/spark区别
Mr引擎:多job串联,基于磁盘,落盘的地方比较多。虽然慢,但一定能跑出结果。一般处理,周、月、年指标。
Spark引擎:虽然在Shuffle过程中也落盘,但是并不是所有算子都需要Shuffle,尤其是多算子过程,中间过程不落盘 DAG有向无环图。 兼顾了可靠性和效率。一般处理天指标。
Tez引擎:完全基于内存。 注意:如果数据量特别大,慎重使用。容易OOM(内存溢出)。一般用于快速出结果,数据量比较小的场景。
Mysql元数据备份
具体参照博客
Union和Union all区别
1)union会将联合的结果集去重,效率较union all差
2)union all不会对结果集去重,所以效率高