简介
本实验介绍 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 的基本数据单元
- 数据库:用于避免命名冲突并增强安全性的命名空间。
- 表:具有相同架构的同类数据单元。例如,
page_views表可以包含时间戳、用户 ID 和页面 URL 等列。 - 分区:根据键将数据划分为多个分区,以提高数据检索效率。
- 分桶:根据哈希函数的值将分区数据划分为多个桶,以提高查询效率。
Hive 数据类型
- Hive 支持基本数据类型和复杂数据类型。详情请参阅 Hive 数据类型文档。
Hive 面向数据仓库任务,而非联机事务处理(OLTP),重点关注可扩展性、性能、可靠性和容错能力。Hive 支持多种输入格式,也可以通过连接器扩展以支持不同格式。了解 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 Server,并创建数据库 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 会进入预装 Hive 的命令行。要进入刚配置好的 Hive 命令行,请使用其绝对路径!
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 决定,因此无法手动更改行分隔符。
通常,列数据已确定的表会使用分桶存储,这有助于高效地对数据集进行抽样查询。如果不使用分桶,即使可以对表进行随机抽样,也无法在扫描全部数据时实现高效抽样。下面的示例展示如何为 page_view 表启用分桶,并按 userid 列分桶。
以下语句仅用于演示,不要在 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;
修改表
要重命名已有表,请使用带有 RENAME TO 的 ALTER TABLE 语句。如果新表名已存在,Hive 会返回错误。以下语句仅作示例,不要执行,因为下一步会使用你创建的 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 命令时,Hive 也会隐式删除基于该表创建的所有索引。
以下示例用于删除表。本实验中不要执行:
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 作为数据仓库软件,还有许多功能值得进一步探索。请养成主动查阅技术资料的习惯,并继续学习后续课程。



