一、Hive基本概念
(一)什么是Hive
- Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。
- Hive本质是将HQL转化成MapReduce程序。Hive处理的数据存储在HDFS上。分析数据的底层实现是MapReduce。执行程序运行在Yarn上。
- Hive的执行延迟比较高。适合处理大数据,常用于数据分析,对实时性要求不高的场合。
- Hive的HQL表达能力有限,对迭代式算法无法表达,数据挖掘方面也不擅长。Hive自动生成的MR作业,通常情况下不够智能化。Hive调优比较困难,粒度较粗。
- 由于 Hive 采用了类似SQL 的查询语言 HQL(Hive Query Language),因此很容易将 Hive 理解为数据库。其实从结构上来看,Hive 和数据库除了拥有类似的查询语言,再无类似之处。数据库可以用在 Online 的应用中,但是Hive 是为数据仓库而设计的,清楚这一点,有助于从应用角度理解 Hive 的特性。
(二)Hive架构原理
如图中所示,Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口。
- 用户接口:Client
CLI(Hive shell)、JDBC/ODBC(java访问hive)、WEBUI(浏览器访问hive)。 - 元数据:Meat store
元数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;默认存储在自带的derby数据库中,推荐使用MySQL存储Metastore。 - Hadoop:使用HDFS进行存储,使用MapReduce进行计算。
- 驱动器:Driver
(1) 解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
(2)编译器(Physical Plan):将AST编译生成逻辑执行计划。
(3)优化器(Query Optimizer):对逻辑执行计划进行优化。
(4)执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于Hive来说,就是MR/Spark。
二、Hive安装及测试
(一)Hive安装地址说明
- Hive官网地址:http://hive.apache.org/
- 文档查看地址:https://cwiki.apache.org/confluence/display/Hive/GettingStarted
- 下载地址:http://archive.apache.org/dist/hive/
- github地址:https://github.com/apache/hive
(二)Hive安装部署
- MySql安装:Hive默认把Meatstore存储在自带的derby数据库中,打开多个客户端窗口启动hive时,会产生java.sql.SQLException。推荐使用MySQL存储Metastore。
(1)查看mysql是否安装,如果安装了,卸载mysql
查看 rpm -qa|grep -i mysql
卸载 rpm -e --nodeps mysql-libs-xxx
- Hive安装及配置
(1)把apache-hive-x.x.x-bin.tar.gz上传到linux的/opt/software目录下。
(2)解压apache-hive-x.x.x-bin.tar.gz到/opt/module/目录下面。
(3)修改apache-hive-x.x.x-bin的名称为hive
(4)修改/opt/module/apache-hive-x.x.x-bin/conf目录下的hive-env.sh.template名称为hive-env.sh。
(5)配置hive-env.sh。修改HADOOP_HOME路径和HIVE_CONF_DIR路径。
(6)驱动拷贝:拷贝mysql-connector-java-5.1.27-bin.jar到/opt/module/hive/lib/
(7)在/opt/module/hive/conf目录下创建一个hive-site.xml,根据官方文档配置参数,拷贝数据到hive-site.xml文件中。具体参数配置:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop102:3306/metastore?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>000000</value>
<description>password to use against metastore database</description>
</property>
</configuration>
(8)配置完毕后,如果启动hive异常,可以重新启动虚拟机。(重启后,别忘了启动hadoop集群)。
(9)多窗口启动Hive测试,MySQL窗口查看数据库,显示增加了metastore数据库。
1. Hadoop集群配置
(1)必须启动hdfs和yarn。
(2)在HDFS上创建/tmp和/user/hive/warehouse两个目录并修改他们的同组权限可写。
2. Hive基本操作
(1)启动hive:[root@hadoop102 hive]$ bin/hive。
(2)创建一张表:hive> create table people(id int, name string) row format delimited fields terminated by ‘\t’;
(3)向表中插入数据:hive> insert into people values(1000,”ss”);
(4)查询表中数据:hive> select * from people;
(5)退出hive:hive>quit;
3. 将本地文件导入Hive案例
需求:将本地/opt/module/datas/people.txt这个目录下的数据导入到hive的people(id int, name string)表中。
(1)在/opt/module/datas/目录下创建student.txt文件并添加数据
[root@hadoop102 module]$ touch people.txt
[root@hadoop102 module]$ vi people.txt
1001 zhangshan
1002 lishi
1003 zhaoliu
注意以tab键间隔。
(2)加载/opt/module/datas/people.txt 文件到people数据库表中。
hive> load data local inpath '/opt/module/datas/people.txt' into table people;
(3)Hive查询结果
hive> select * from people;
OK
1001 zhangshan
1002 lishi
1003 zhaoliu
Time taken: 0.266 seconds, Fetched: 3 row(s)
Hive常用交互命令
[root@hadoop102 hive]$ bin/hive -help
usage: hive
-d,--define <key=value> Variable subsitution to apply to hive
commands. e.g. -d A=B or --define A=B
--database <databasename> Specify the database to use
-e <quoted-query-string> SQL from command line
-f <filename> SQL from files
-H,--help Print help information
--hiveconf <property=value> Use value for given property
--hivevar <key=value> Variable subsitution to apply to hive
commands. e.g. --hivevar A=B
-i <filename> Initialization SQL file
-S,--silent Silent mode in interactive shell
-v,--verbose Verbose mode (echo executed SQL to the
console)
(1)“-e”不进入hive的交互窗口执行hql语句
(2)“-f”执行脚本中hql语句
Hive常见属性配置
default数据仓库原始位置
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
<description>location of default database for the warehouse</description>
</property>
在hive-site.xml文件中添加如下配置信息,就可以实现显示当前数据库,以及查询表的头信息配置。
<property>
<name>hive.cli.print.header</name>
<value>true</value>
</property>
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
</property>
修改/opt/module/hive/conf/hive-log4j.properties.template文件名称为hive-log4j.properties
mv hive-log4j.properties.template hive-log4j.properties
在hive-log4j.properties文件中修改log存放位置
hive.log.dir=/opt/module/hive/logs
查看当前所有的配置信息
hive>set;
参数的配置三种方式及优先级
(1)默认配置文件:hive-default.xml
用户自定义配置文件:hive-site.xml
注意:用户自定义配置会覆盖默认配置。另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。配置文件的设定对本机启动的所有Hive进程都有效。
(2)命令行参数方式
[root@hadoop103 hive]$ bin/hive -hiveconf mapred.reduce.tasks=10;
(3)参数声明方式
hive (default)> set mapred.reduce.tasks=100;
上述三种设定方式的优先级依次递增。即配置文件<命令行参数<参数声明。注意某些系统级的参数,例如log4j相关的设定,必须用前两种方式设定,因为那些参数的读取在会话建立以前已经完成了。
三、Hive创建表
建表语法
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]
2)字段解释说明:
(1)CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。
(2)EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
(3)COMMENT:为表和列添加注释。
(4)PARTITIONED BY创建分区表
(5)CLUSTERED BY创建分桶表
(6)SORTED BY不常用
(7)
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确定表的具体的列的数据。
(8)STORED AS 指定存储文件类型
常用的存储文件类型:SEQUENCEFILE(二进制序列文件)、TEXTFILE(文本)、RCFILE(列式存储格式文件)
如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
(9)LOCATION :指定表在HDFS上的存储位置。
(10)LIKE允许用户复制现有的表结构,但是不复制数据。
四、Hive数据类型
1 基本数据类型
2 集合数据类型
案例实操
1)假设某表有如下一行,我们用JSON格式来表示其数据结构。在Hive下访问的格式为
{
“name”: “songsong”,
“friends”: [“bingbing” , “lili”] , //列表Array,
“children”: { //键值Map,
“xiao song”: 18 ,
“xiaoxiao song”: 19
}
“address”: { //结构Struct,
“street”: “hui long guan” ,
“city”: “beijing”
}
}
2)基于上述数据结构,我们在Hive里创建对应的表,并导入数据。
创建本地测试文件test.txt
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing
yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing
注意,MAP,STRUCT和ARRAY里的元素间关系都可以用同一个字符表示,这里用“_”。
3)Hive上创建测试表test
create table test(
name string,
friends array<string>,
children map<string, int>,
address struct<street:string, city:string>
)
row format delimited fields terminated by ','
collection items terminated by '_'
map keys terminated by ':'
lines terminated by '\n';
字段解释:
`row format delimited fields terminated by ','` -- 列分隔符
`collection items terminated by '_' --MAP STRUCT 和 ARRAY 的分隔符(数据分`割符号)
map keys terminated by ':' -- MAP中的key与value的分隔符
lines terminated by '\n'; -- 行分隔符
4)导入文本数据到测试表
hive (default)> load data local inpath '/opt/module/datas/test.txt' into table test;
5)访问三种集合列里的数据,以下分别是ARRAY,MAP,STRUCT的访问方式
hive (default)> select friends[1],children['xiao song'],address.city from test where name="songsong";
OK
_c0 _c1 city
lili 18 beijing
Time taken: 0.076 seconds, Fetched: 1 row(s)
类型转化
Hive的原子数据类型是可以进行隐式转换的,类似于Java的类型转换,例如某表达式使用INT类型,TINYINT会自动转换为INT类型,但是Hive不会进行反向转化,例如,某表达式使用TINYINT类型,INT不会自动转换为TINYINT类型,它会返回错误,除非使用CAST 操作。
1)隐式类型转换规则如下。
(1)任何整数类型都可以隐式地转换为一个范围更广的类型,如TINYINT可以转换成INT,INT可以转换成BIGINT。
(2)所有整数类型、FLOAT和STRING类型都可以隐式地转换成DOUBLE。
(3)TINYINT、SMALLINT、INT都可以转换为FLOAT。
(4)BOOLEAN类型不可以转换为任何其它的类型。
2)可以使用CAST操作显示进行数据类型转换,例如CAST(‘1’ AS INT)将把字符串’1’ 转换成整数1;如果强制类型转换失败,如执行CAST(‘X’ AS INT),表达式返回空值 NULL。