简介
本实验介绍 Hive 的配置和基本操作,面向具有一定 SQL 基础的学习者,帮助你了解 Hive 的架构、基本部署和使用方法。
请尽量亲自输入文档中的所有示例代码,不要直接复制粘贴。只有这样,你才能更加熟悉这些代码。如果遇到问题,请仔细查看文档,也可以前往论坛寻求帮助并交流。
Hive 简介
在本步骤中,你将学习 Apache Hive 如何为存储在 Hadoop 中的大型数据集提供 SQL 接口,以便查询和分析数据。下面介绍 Hive 的架构和主要特性:
Hive 架构
- 组件:Hive 包含用于表和存储管理的
HCatalog,以及用于运行 MapReduce 任务、Pig 查询或通过 REST API 与 Hive 元数据交互的WebHCat。 - 特性:
- 支持 SQL 查询,可用于数据仓库中的 ETL、数据分析和报表生成等任务。
- 数据存储在 HDFS 或 HBase 等存储系统中;查询操作由 Tez、Spark 或 MapReduce 等计算引擎执行。
- 支持过程语言和 HPL-SQL,并支持通过 Hive LLAP、YARN 和 Slider 进行子查询检索。
Hive 中的基本数据单元
- 数据库(Database):用于避免命名冲突并增强安全性的命名空间。
- 表(Table):具有相同模式的同类数据单元。例如,
page_views表可以包含 timestamp、userid、page_url 等列。 - 分区(Partition):根据键将数据划分为多个分区,以提高数据检索效率。
- 桶(Bucket):根据哈希函数值将分区数据进一步划分为多个桶,以提高查询效率。
Hive 数据类型
- 支持基本数据类型和复杂数据类型。详细信息请参阅 Hive 数据类型文档。
Hive 主要面向数据仓库任务,而不是在线事务处理(OLTP),重点关注可扩展性、性能、可靠性和容错能力。Hive 支持多种输入格式,也可以通过连接器扩展以支持不同格式。要充分利用 Hive 进行大数据分析,必须理解它的架构、数据单元和数据类型。
Hive 的安装与部署
在本步骤中,你将了解 Hive 的安装和部署,包括目录结构、环境变量、元数据存储以及系统参数。
首先切换到 hadoop 用户,以便执行后续操作。双击桌面上的 Xfce 终端并输入以下命令:
su - hadoop
提示:用户 hadoop 的密码是 hadoop。
然后使用 wget 命令下载 Hive 的最新稳定版本。本实验使用 Hive 2.3.3:
sudo wget https://labexfile.oss-us-west-1.aliyuncs.com/courses/144/apache-hive-2.3.3-bin.tar.gz
接下来解压下载的安装包。在终端中输入以下命令:
tar -zxvf apache-hive-2.3.3-bin.tar.gz
使用 sudo 权限将解压后的目录移动到 /opt 目录。如果不使用 sudo 权限,可能无法写入 /opt 目录:
sudo mv /home/hadoop/apache-hive-2.3.3-bin /opt/hive-2.3.3
移动目录后,将 Hive 目录的所有者和用户组都修改为 hadoop。在终端中输入以下命令:
sudo chown -R hadoop:hadoop /opt/hive-2.3.3
提示:你也可以打开另一个终端,使用 sudo 权限执行上述操作。
labex:~/ $ ls -al /opt/
total 24
drwxrwxr-x 10 hadoop hadoop 4096 Mar 3 12:01 hive-2.3.3
...
设置环境变量
在本步骤中,你将设置 Hive 的环境变量,使 HIVE_HOME 指向 Hive 的安装目录。
首先使用 vim 编辑器打开 hadoop 用户的 .bashrc 文件。在终端中输入以下命令:
vim /home/hadoop/.bashrc
将以下内容添加到文件末尾。请根据当前实验环境的实际情况修改 PATH。$PATH 表示现有的 PATH 内容。直接在 PATH 环境变量末尾添加 :$HIVE_HOME/bin:
export HIVE_HOME=/opt/hive-2.3.3
export PATH=$PATH:$HIVE_HOME/bin
编辑完成后保存文件并退出编辑器。然后使用 source 命令激活上述环境变量。
本实验已经预先安装了 Hive,因此不需要执行 source 来加载环境变量;但在实际安装过程中,需要根据具体情况完成这一步。
设置配置
在本步骤中,你将查看预安装的 Hive 配置,并创建检查所需的配置文件。
元数据库配置
正式使用 Hive 之前,需要先设置元数据存储。默认情况下,Hive 将元信息存储在内嵌的 Derby 数据库中。磁盘上的存储位置由 Hive 配置文件 conf/hive-default.xml 中的配置项 javax.jdo.option.ConnectionURL 决定,默认位置为 ./metastore_db。
但在本实验中,我们将使用 MySQL 存储元数据。因此,需要修改 Hive 配置文件。
使用 vim 创建并打开我们要配置的文件:
vim /opt/hive-2.3.3/conf/hive-site.xml
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive_metastore1?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hiveuser1</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123qweQWE...</value>
</property>
</configuration>
完成上述配置项的编辑后,保存文件并退出编辑器。
创建 MySQL 数据库
使用 sudo mysql 启动 MySQL 服务器,并创建数据库 hive_metastore:
CREATE DATABASE hive_metastore1;
CREATE USER 'hiveuser1'@'localhost' IDENTIFIED BY '123qweQWE...';
GRANT ALL PRIVILEGES ON hive_metastore1.* TO 'hiveuser1'@'localhost';
FLUSH PRIVILEGES;
exit;
然后下载 MySQL JDBC 驱动,并将其复制到 /opt/hive-2.3.3/lib 目录:
cp /usr/local/hive/lib/mysql-connector-j-8.3.0.jar /opt/hive-2.3.3/lib
设置 Hive 系统参数
配置元数据库后,需要设置 Hive 的内部配置项,以指定 Hadoop 的位置、内部配置文件路径等信息。
首先使用 cp 命令复制设置模板,使配置能够生效。
请在终端中输入以下命令:
cp /opt/hive-2.3.3/conf/hive-env.sh.template /opt/hive-2.3.3/conf/hive-env.sh
然后使用 vim 编辑器打开 hive-env.sh 文件:
vim /opt/hive-2.3.3/conf/hive-env.sh
在第 48 行,将 HADOOP_HOME 设置为 Hadoop 的安装路径:
HADOOP_HOME=/home/hadoop/hadoop
完成上述配置项的编辑后,保存文件并退出编辑器。
初始化元数据库
在本步骤中,你将初始化 Hive 元数据库,并启动 Hive 所需的 Hadoop 服务。
由于后续使用的数据将存储在 HDFS 中,因此需要提前启动 HDFS。请在终端中输入以下命令启动 HDFS:
start-dfs.sh
start-yarn.sh
输入 jps 查看服务状态:
hadoop:~/ $ jps [17:31:43]
8960 Jps
3153 NodeManager
2823 SecondaryNameNode
3017 ResourceManager
2570 DataNode
2428 NameNode
如果你是第一次使用 Hadoop,需要删除 Hadoop 数据,并使用 hdfs namenode -format 进行初始化。
本实验已经使用默认数据库初始化了预安装的 Hive。如果你希望初始化刚刚下载的 Hive,请使用以下命令:
/opt/hive-2.3.3/bin/schematool -initSchema -dbType mysql
Initialization script completed
schemaTool completed
如果你第一次初始化刚刚下载的 Hive,需要将 ~/.bashrc 中的 HIVE_HOME 路径修改为刚安装的 Hive 路径,然后执行 source 加载配置。建议不要这样做,因为后续的 Hive 测试都基于预安装的 Hive。
当提示信息表明初始化完成后,可以使用 hive 命令进入 Hive 命令行。请在终端中输入以下命令:
hive
提示:直接在预安装的 Hive shell 中输入 hive,并添加绝对路径,即可进入刚刚设置的 Hive shell。
Hive Session ID = 3eee2693-175d-4452-82d2-47f1b639d9d5
Logging initialized using configuration in jar:file:/usr/local/hive/lib/hive-common-3.1.3.jar!/hive-log4j2.properties Async: true
Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
Hive Session ID = 68d0d345-92c3-4eb1-8393-7ee34f56363f
hive>
Hive 的基本操作
在本步骤中,你将学习 Hive 表的基本操作。所有 Hive 语句也可以在其 Language Manual 中找到。
创建表
首先获取一些数据。本实验本部分使用的数据主要是模拟 NginX 服务器的日志文件,可以用来分析网站的页面访问量。
重新打开一个终端,在终端中输入以下命令下载示例数据:
su hadoop
cd ~
wget http://labfile.oss-cn-hangzhou.aliyuncs.com/courses/567/log_example.csv
然后将文件上传到 HDFS:
hdfs dfs -mkdir -p /user/data/staging/page_view
hdfs dfs -put /home/hadoop/log_example.csv /user/data/staging/page_view
获取数据后,首先创建表。如果要为上述数据创建 page_view 表,请在 Hive 命令行中输入以下语句:
CREATE TABLE page_view(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
STORED AS SEQUENCEFILE;
在这个示例中,为表中的每一列指定了合适的数据类型。同时,可以在列级别和表级别添加注释。此外,PARTITIONED BY 子句定义了不同于数据列的分区列。分区列不会与数据列一起存储。以这种方式指定分区列时,每一行使用换行符作为分隔符。
如果数据不是上述格式,可以像下面的示例一样设置字段分隔符:
以下语句仅用于演示,不要在 hive shell 中输入。
CREATE TABLE page_view1(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '1'
STORED AS SEQUENCEFILE;
由于行分隔符由 Hadoop 系统中的分隔符决定,而不是由 Hive 决定,因此不能手动修改行分隔符。
通常,根据列数据确定的表会存储在桶中,这有助于高效地对数据集查询进行采样。如果没有桶,即使可以完成表的随机采样,在扫描全部数据的过程中也无法实现高效采样。下面的示例展示了如何在 userid 列上为 page_view 表启用桶存储。
以下语句仅用于演示,不要在 hive shell 中输入。
CREATE TABLE page_view2(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '1'
COLLECTION ITEMS TERMINATED BY '2'
MAP KEYS TERMINATED BY '3'
STORED AS SEQUENCEFILE;
在上面的示例中,表中的 userid 列通过哈希函数聚合到 32 个桶中。每个桶中的数据按照 viewTime 升序排列。这种数据组织方式可以让用户有效地对聚合列(此处为 userid 列)进行采样,而排序功能则让数据管理者可以通过更好的数据结构更高效地评估查询。
以下语句仅用于演示,不要在 hive shell 中输入。
CREATE TABLE page_view3(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Friends ARRAY<BIGINT>, properties MAP<STRING, STRING>,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
CLUSTERED BY(userid) SORTED BY(viewTime) INTO 32 BUCKETS
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '1'
COLLECTION ITEMS TERMINATED BY '2'
MAP KEYS TERMINATED BY '3'
STORED AS SEQUENCEFILE;
在上面的示例中,通过字段名和类型定义表中每一行的格式,这与其他编程语言中的类型定义非常相似。请注意,表名和列名不区分大小写。IP Address of the User 和下面的 COMMENT 语句表示可以在列级别和表级别添加注释。此外,PARTITIONED BY 子句定义了不同于数据列的分区列。如前所述,分区列实际上不存储数据。CLUSTERED BY 子句指定使用哪一列创建桶,以及创建多少个桶。ROW FORMAT DELIMITED 子句指定 Hive 表中行的存储方式。对于分隔格式,该语句指定字段结束符、集合(数组或映射)中元素的结束符,以及映射键的结束符,其中这些数字采用 ASCII 编码。STORED AS SEQUENCEFILE 表示数据以二进制格式存储在 HDFS 中,具体来说是 Hadoop 的 SequenceFile 类型。其中,ROW FORMAT 和 STORED AS 子句中的设置是 Hive 当前使用的默认值。因此,在最开始创建表的语句中没有显式写出这些设置。
浏览表和分区
如果要列出数据仓库中现有的表,可以使用以下语句:
SHOW TABLES;
如果表很多,上面的语句会返回大量信息。你可以指定前缀来缩小范围。例如,如果要列出以 page 为前缀的表,可以使用以下语句:
SHOW TABLES 'page.*';
该语句的匹配规则与正则表达式语法相同,其中句点(.)表示通配符。
如果要列出某个表的分区,请使用以下语句。如果该表不是分区表,则不会返回任何信息:
SHOW PARTITIONS page_view;
如果要列出表的列及其数据类型,可以使用 DESCRIBE 语句:
DESCRIBE page_view;
如果要列出表的列以及其他所有属性,需要添加 EXTENDED 关键词。该命令会输出大量信息,通常用于调试:
DESCRIBE EXTENDED page_view;
修改表
如果要重命名现有表,请将 ALTER TABLE 语句与 RENAME TO 一起使用。如果新表名已经存在,将返回错误。以下语句仅用于示例,请不要执行,因为下一步骤会使用你创建的 page_view 表:
ALTER TABLE page_view RENAME TO new_page_view;
查看结果:
hive> ALTER TABLE page_view RENAME TO new_page_view;
OK
Time taken: 0.124 seconds
hive> show tables;
OK
new_page_view
...
Time taken: 0.021 seconds, Fetched: 4 row(s)
也可以重命名现有表的列。但请注意,必须使用相同的列类型,并为每个现有列包含一条记录:
ALTER TABLE new_page_view REPLACE COLUMNS (viewTime INT, userid BIGINT, page_url STRING, referrer_url STRING, ipaddr STRING COMMENT 'IP Address of the User');
此外,还可以向现有表添加新列:
ALTER TABLE new_page_view ADD COLUMNS (new_column INT COMMENT 'a new int column');
请注意,模式发生变化时(例如添加列),表旧分区的模式会被保留,以防止其变成分区表。访问这些列并在旧分区上运行的所有查询,都会隐式地为这些列返回 null 值或指定的默认值。
删除表和分区
由于 Hive 是为数据仓库设计的,销毁数据通常会带来负面影响。因此,删除表的操作稍微复杂一些。对表使用 DROP 命令时,会隐式删除在该表上创建的所有索引。
下面的示例会删除一个表。在本实验中不要执行:
DROP TABLE new_page_view;
加载和查询数据
在本步骤中,你将把暂存数据加载到 Hive 分区表中,并查询加载结果。
加载数据
将数据加载到 Hive 表有多种方式。用户可以创建指向 HDFS 特定位置的外部表。在这种用法中,用户可以使用 HDFS 的 put 或 copy 命令,将数据文件复制到指定位置,然后创建一个指向该位置的表。该表会包含所有相关的行格式信息。
创建外部表后,用户可以转换数据,并将其插入其他 Hive 表。我们已经将 log_example.csv 文件上传到 HDFS,并将其命名为 page_view。如果要将它加载到对应分区的 page_view 表中,可以使用以下命令。
首先创建一个外部表,并将其关联到指定文件:
CREATE EXTERNAL TABLE page_view_stg(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User',
Country STRING COMMENT 'country of origin')
COMMENT 'This is the staging page view table'
ROW FORMAT DELIMITED FIELDS TERMINATED BY '44' LINES TERMINATED BY '\n' STORED AS TEXTFILE
LOCATION '/user/data/staging/page_view';
然后创建一个用于最终存储数据的 page_view 表:
CREATE TABLE page_view(viewTime INT, userid BIGINT,
Page_url STRING, referrer_url STRING,
Ip STRING COMMENT 'IP Address of the User')
COMMENT 'This is the page view table'
PARTITIONED BY(dt STRING, country STRING)
STORED AS SEQUENCEFILE;
这个小型练习数据集不需要分布式 YARN 作业。为当前 Hive 会话配置 Hadoop 的本地作业运行器,使插入操作能够在实验虚拟机中可靠运行:
SET mapreduce.framework.name=local;
最后,将外部表中的数据插入 page_view 表:
FROM page_view_stg pvs
INSERT OVERWRITE TABLE page_view
PARTITION(dt='2015-05-17', country='us')
SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, pvs.ip
WHERE pvs.country = 'us';
本地作业应在几秒内完成,并将匹配的行加载到 page_view 分区中。
...
Loading data to table default.page_view partition (dt=2015-05-17, country=us)
MapReduce Jobs Launched:
Stage-Stage-1: HDFS Read: ... HDFS Write: ... SUCCESS
Total MapReduce CPU Time Spent: 0 msec
OK
Time taken: ... seconds
简单查询
插入数据后,可以执行简单查询。这与常见的 SQL 语句类似。在 Hive 命令行界面中输入以下语句:
SELECT * FROM page_view WHERE userid = 0 LIMIT 10;
返回的信息就是查询到的记录:
hive> select * from page_view;
OK
NULL 490 /downloads/product_1 /archives/webroot 217.168.17.5 2015-05-17 us
NULL 490 /downloads/product_2 /archives/webroot 217.168.17.5 2015-05-17 us
NULL 3316 /downloads/product_2 /archives/webroot 217.168.17.5 2015-05-17 us
...
关闭服务
在本步骤中,你将退出 Hive,并在查看以下学习资源后停止 Hadoop 服务:
使用完成后,可以使用 quit 命令退出 Hive 命令行界面:
quit;
当然,不要忘记关闭 HDFS 服务。在终端中输入以下命令:
stop-yarn.sh
stop-dfs.sh
总结
本实验介绍了 Hive 的架构、安装与部署,以及基本的 HQL 语句。同时,我们还学习了如何使用示例数据导入数据。
本实验涵盖的主要内容包括:
- Hive 架构
- Hive 的基本数据单元
- 如何部署 Hive
- Hive HQL 语言
总体而言,作为一种数据仓库软件包,Hive 的功能还需要进一步探索。请养成主动复习技术资料的习惯,并继续学习后续课程。



