Hive内部是什么
Hive二进制分支版本核心包含3个部分。主要部分是Java代码本身。在$HIVE_HOME/lib 目录下发现有众多的jar包文件。
所有的Hive客户端都需要一个metastoreservice(元数据服务),Hive使用这个服务来存储表模式信息和其他元数据信息。通常情况下会使用一个关系型数据库中的表来存储这些信息。默认情况下,Hive会使用内置的Derby sql服务器, 我这里使用的是MySQL
最后,Hive还提供了一个简单的网页界面,也就是Hive网页界面,提供了远程访问的Hive服务
conf目录下存放了配置Hive的配置文件。Hive具有非常多的配置属性,根据需要后面我们会进行介绍。
启动Hive
在bin目录下 运行./hive
字符串hive>是Hive的提示符:
使用JDBC连接元数据
Hive所需要的组件中只有一个外部组件是Hadoop没有的,那就是metastore(元数据存储)组件。元数据存储中存储了如表的模式和分区信息等元数据信息。
简介
什么是Hive
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。
为什么使用Hive
直接使用Hadoop所面临的问题
– 学习成本高
– 一般项目周期要求短
– MapReduce实现复杂的查询呢逻辑开发难度较大为什么要使用Hive
– 操作接口采用类SQL语法,可以快速开发
– 避免编写MR,减少学习成本
– 扩展功能很方便
Hive的特点
- 可扩展: Hive可以自由的扩展集群规模,一般情况下不需要重启服务
- 延展性: Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数
- 容错: 良好的容错性,节点出现问题SQL仍然可以完成执行
架构
JobTracker是Hadoop1.x中的ResouceManager + AppMaster
TaskTracker相当于NodeManager + YarnChild
基本组成
- 用户接口:CLI、JDBC/ODBC、WebGUI
– CLI是SHELL命令行
– JDBC、ODBC是Hive的Java实现,与传统的JDBC类似
– WebGUI是通过浏览器访问Hive - 元数据存储:Mysql、Derby等
– Hive将元数据存储在数据库中。Hive中的元数据包括表名、列、分区及其属性、表的属性(是否为外部表等)、表数据所在目录等。 - 解释器、编译器、优化器、执行器
– 完成HQL查询语句 词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在HDFS中,并在随后由MapReduce调用执行。Hive与Hadoop的关系
Hive与传统数据库对比
Hive具有SQL数据库的外表,但应用应用场景完全不同,Hive只适合用来做批量的数据统计分析
Hive的数据存储
Hive中所有的数据都存储在HDFS中,没有专门的数据存储格式(可支持Text,SequenceFile,ParquetFile,RCFILE等)
只需要在创建表的时候告诉Hive数据中的列分隔符和行分隔符,Hive就可以解析数据。
Hive中包含以下数据模型:DB、Table、External Table、Partition、Bucket
DB:在HDFS中表现为 ${hive.metastore.warehouse.dir} 目录下的文件夹
Table:在HDFS中表现所属DB目录下的文件夹
External Table:外部表,与Table类似,不过其数据存放的位置可以在任意指定路径。
Table表:删除表后,HDFS上的文件都删除了
External外部表:删除表后,HDFS上的文件没有删除,只是把表删除了
Partition:在HDFS中表现为Table目录下的子目录
Bucket:桶,在HDFS中表现为同一个表目录下根据Hash散列之后的多个文件,会根据不同的文件把数据放到不同的文件夹中
Hive基本操作
DDL操作
创建表
建表语法:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...)
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
说明:
CREATE TABLE
创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。
EXTERNAL
关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
PARTITIONED
表示根据某一个key(不在create table里面)对数据进行分区,体现在HDFS上就是 table目录下有n个不同的分区文件夹(country=China,country=USA)
ROW FORMAT
DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
| SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, …)]
用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive通过 SerDe 确定表的具体的列的数据。
STORED AS
SEQUENCEFILE|TEXTFILE|RCFILE
如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
CLUSTERED BY
对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
show databases;
use hive_test_db;
create table stu_buck(Sno int,Sname string,Sex string,Sage int,Sdept string)
clustered by(Sno)
sorted by(Sno DESC)
into 4 buckets
row format delimited
fields terminated by ',';
设置变量,设置分桶为true, 设置reduce数量是分桶的数量个数
set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;
修改表
增加/删除分区
ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...
partition_spec:
: PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)
ALTER TABLE table_name DROP partition_spec, partition_spec,...
实例:
alter table student_p add partition(part='a') partition(part='b');
重命名表
ALTER TABLE table_name RENAME TO new_table_name
增加/更新列
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)