大数据技术学习——Hive
1 一句话介绍
Hive是基于HDFS的数据仓库,适合存储结构化或半结构化数据。
2 Hive功能定位
Hive本身不存储数据,数据都存储在HDFS上。Hive提供两个核心功能:
- 统一元数据管理。通过MetaStore组件将元数据存储于关系型数据库中(开源默认Derby),将HDFS本地结构化数据映射为数据库表。
- HQL生命周期管理。将用户输入HQL语句转化为MR任务提交给底层计算引擎。例如MapReduce、Tez、Spark(即Hive On Spark,与SparkSQL不同,SparkSQL独立于Hive)。
Hive3.0.0后MetaStore便可独立运行,Presto/Impala等组件采用内存计算,是基于MetaStore的实时SQL分析引擎。
一般仅使用Hive进行数据的大批量转换,后续快速的数据分析适合采用Presto/Impala。
3 Hive架构
- MetaStore:提供元数据服务,处理Hive数据库、表、分区等的结构和属性信息等元数据并将其存储在后端关系型数据库(例如MySQL、DBService)中。
- Driver:驱动引擎,管理HQL执行生命周期(启动会话、执行、监督等),并将执行过程中产生的必要元数据发送给MetaStore,将执行结果返回给上层客户端。
- Compiler:编译器,将HQL转换成MR任务(DAG表示)。
- Optimizer:优化器,优化DAG(聚合Transformation,分割任务等)。
- Executor:执行器,根据优化后的DAG图,执行流水线任务。
- HiveServer:又称Thrift Server,是一种使能客户端使用不同编程语言向Hive提交HQL请求的中间层可选服务。
- Hcatalog:构建于MetaStore之上,是Hadoop的表和存储管理层,能使用户使用不同的数据处理工具(Pig、MR、Hive、Streaming等)读写HDFS数据。
- WebHCat:Hcatalog的Rest接口,使能Rest客户端访问Hive。
- 连接Hive的方式
- Beeline(JDBC命令行工具)、JDBC、Hue等通过Thrift Server连接Driver
- CLI和Hive WebUI直接连接Driver
- HCatalog CLI、WebHCat直接连接Hive
- Tez:Hive默认计算引擎。相较于MR,Tez将多个依赖作业合并成一个作业,减少中间数据落盘。
4 Hive执行流程
- CLI/Beeline/Thrift Server等发送查询命令给Driver
- Driver启动会话,发送编译命令给Complier
- Complier发送请求到MetaStore获取元数据
- MetaStore返回元数据给Compiler
- Complier返回执行计划给Driver
- Driver发送请求给Execution启动任务执行
- Execution向JobTracker发送Job,并且执行元数据操作
- Execution获得从DataNode返回的数据,然后将其转发给Driver
5 Hive Join&GroupBy过程
5.1 Join
select name, orderid
from user t1
join order t2 on t1.uid=t2.uid
5.2 GroupBy
select
rank,
isonline,
count(1)
from
city
group
by
1,
2
- 对于join过程来说,如果出项较多的key值为空或异常的记录,或key值分布不均匀,就容易出现数据倾斜。
- 对于group by 过程来说,如果某一个key值有特别多的记录,其它key值的记录比较少,也容易出项数据倾斜。
6 Hive表
6.1 Hive表特性
- Hive将表的元数据存储在关系型数据库中,表中的结构化或半结构化数据则存储在HDFS上,每个表对应HDFS上的一个目录,表的每个分区对应子目录。
- Hive没有特定的数据存储格式,需要用户指定(textfile、sequencefile、rcfile等)。
6.2 内部表
表的元数据以及数据均位于Hive目录内。导入数据时,数据迁移至Hive内,删除表时元数据以及数据一并删除。
6.3 外部表
表的元数据位于Hive内,数据位于Hive目录外HDFS,可避免数据的导入。导入数据时,数据不迁移(如果数据本身就在HDFS上,会迁移至Hive的目录下,删除表时目录及数据保留),删除表时仅仅删除元数据。
6.4 分区表
根据表中某个字段的取值,将整表分成各个子表存储到子目录下。需要事先准备根据特定字段切分的子文件,并逐个将子文件加载。
分区表分为静态以及动态分区表。静态分区表需要手动添加分区,动态分区表根据实际数据的情况自动创建分区(分区值不确定)。
示例如下:
创建静态分区表:
create table if not exists day_part(uid int,uname string) partitioned by(year int,month int) row format delimited fields terminated by '\t';
加载数据:
load data local inpath 'student.txt' into table day_part partition(year=2017,month=04);
手动添加分区:
alter table day_part add partition(year=2017,month=1) partition(year=2016,month=12);
动态分区参数:
hive.exec.dynamic.partition=true : 允许动态分区
hive.exec.dynamic.partition.mode=strict :严格模式动态分区
动态分区小文件问题:
使用动态分区时, 易误判造成分区数过多,而每个分区都要分配一定的Reduce数量,易造成小文件过多。小文件过多易造成NameNode压力过大,需要的Map/Reduce数量更多,更多的JVM启动消耗更多的资源。
6.5 分桶表
对表中某个字段进行Hash,将整表分成不同的文件分别存储。创建分桶表需要事先打开分桶开关。分桶表不能通过load方式加载数据,只能通过insert方式插入数据。
6.6 事务表
当我们创建表的时候,为表添加'transactional'='true'的属性,该表将会被定义为事务表,即ACID表。ACID表支持insert、update、delete、merge等数据操作,而非ACID表由于不支持事务,仅能进行load、insert操作。
7 Hive参数
参数优先级:配置文件<命令行参数<参数声明
配置文件方式:对本机启动的所有 Hive 进程都有效。
eg:用户自定义(hive-site.xml)会覆盖默认配置文件(hive-default.xml)。
命令行参数方式:仅对当前启动的Hive客户端窗口有效。
eg:bin/hive -hiveconf mapred.reduce.tasks=10
参数声明方式:仅对声明后语句有效。
eg:设置如下参数可防止减轻数据倾斜:
set hive.map.aggr=true;(默认为ture,map端的Combiner)
set hive.groupby.skewindata=true (默认为false)
查看参数:set <参数名>
8 参考命令
以Kaggle Titanic数据为例:
创建数据库:
create database if not exists testDB comment "database fot testing" location "/user/hive/warehouse" with dbproperties ('createdby'='Eric');
创建内部表:
user testDB;
create table if not exists titanic_train (PassengerId BIGINT, Survived TINYINT,Pclass TINYINT,SEX STRING,Age INT,SibSp TINYINT,Parch TINYINT,Ticket STRING,Fare FLOAT,Cabin STRING,Embarked STRING) comment 'train data for titanic' row format delimited fields terminated by ',' stored as textfile;
load data inpath '/test/dataset/train.csv' into table titanic_train;
创建外部表:
create external table if not exists external_titanic_test (PassengerId BIGINT, Survived TINYINT,Pclass TINYINT,SEX STRING,Age INT,SibSp TINYINT,Parch TINYINT,Ticket STRING,Fare FLOAT,Cabin STRING,Embarked STRING) comment 'train data for titanic' row format delimited fields terminated by ',' stored as textfile;
load data inpath '/test/dataset/test.csv' into table external_titanic_test;
创建分区表:
create table if not exists part_titanic_train (PassengerId BIGINT, Survived TINYINT,Pclass TINYINT,Age INT,SibSp TINYINT,Parch TINYINT,Ticket STRING,Fare FLOAT,Cabin STRING,Embarked STRING) partitioned by (SEX STRING) row format delimited fields terminated by ',' stored as textfile;
load data inpath '/test/dataset/test.csv' into table part_titanic_train partition(SEX='male');
load data inpath '/test/dataset/test.csv' into table part_titanic_train partition(SEX='female');
创建分桶表:
create table if not exists bucket_titanic_train (PassengerId BIGINT, Survived TINYINT,Pclass TINYINT,SEX STRING,Age INT,SibSp TINYINT,Parch TINYINT,Ticket STRING,Fare FLOAT,Cabin STRING,Embarked STRING) clustered by (AGE) into 3 buckets row format delimited fields terminated by ',' stored as textfile;
insert into table bucket_titanic_train select * from titanic_train;
9 参考
- https://juejin.cn/post/6910568483126411278
- https://cwiki.apache.org/confluence/display/hive/tutorial
- http://niyanchun.com/hive-architecture-introduction.html
- https://data-flair.training/blogs/apache-hive-tutorial/
- https://zhuanlan.zhihu.com/p/93728864
- https://zhuanlan.zhihu.com/p/80166949
- https://zhuanlan.zhihu.com/p/79384822
- https://zhuanlan.zhihu.com/p/345770553
- 参数配置:https://blog.csdn.net/lzb348110175/article/details/117118351
- Map端预聚合:https://zhuanlan.zhihu.com/p/67484713
- ACID表:https://bbs.huaweicloud.com/blogs/238620
- 点赞
- 收藏
- 关注作者
评论(0)