Hive 学习第一天:搞懂它是什么,并搭好可用的环境
学习环境:CentOS 7 + JDK 8 + Hadoop 3.x + Hive 3.x + MySQL 5.7
前置条件:Hadoop 伪分布式集群已能正常启动(参考 Hadoop 两天笔记)。
学习目标:理解 Hive 的本质和架构,知道它和 MySQL 这类传统数据库的区别;完成生产常用的 MySQL 元数据部署,并用 Beeline 跑通第一个查询。
一、Hive 到底是什么
前面学 MapReduce 时应该有体会:写一个 WordCount 要打包、写 Java 类、处理各种异常,门槛高、开发慢。而现实中大量的数据分析需求本质就是"按某些维度分组统计",如果能用 SQL 来做就好了------Hive 就是干这件事的。
一句话定义:Hive 是建立在 Hadoop 之上的数据仓库工具,它把类 SQL 语句(HQL)自动翻译成分布式计算任务(默认 MapReduce,也可换成 Tez、Spark)在集群上执行。
这里有三个关键词必须理解到位:
- 它不存数据:Hive 的表数据真实存在 HDFS 上,Hive 自己只保存"表的描述信息"(元数据)。
- 它不算数据:真正的计算由 Hadoop 的 MapReduce(或其他引擎)完成。
- 它做的是"翻译 + 管理":把 HQL 解析成执行计划,调度底层引擎运行。
所以一个常见的说法是:Hive 是"SQL 化的 MapReduce 客户端" 。你写一句 SELECT dept, COUNT(*) FROM emp GROUP BY dept,Hive 帮你生成一整套 MapReduce 作业。
二、Hive 的内部架构
理解架构的目的,是为了后面排查问题时知道每一步发生在哪里。
用户(CLI / Beeline / JDBC)
↓ 提交 HQL
Hive Driver(驱动器)
├── 解析器 Parser:SQL 语法解析,生成抽象语法树
├── 编译器 Compiler:结合元数据生成执行计划(DAG)
├── 优化器 Optimizer:对计划做优化(如谓词下推、列裁剪)
└── 执行器 Executor:把计划提交给执行引擎
↓
MapReduce / Tez / Spark → HDFS(真实数据)
↑ 查询元数据
Metastore(元数据服务)→ MySQL(持久化库名、表名、字段、分区、HDFS路径等)
其中 Metastore(元数据服务)是 Hive 的核心,它记录的内容包括:
- 有哪些数据库、表、字段及其类型;
- 表对应 HDFS 上的哪个目录;
- 分区表有哪些分区;
- 表用什么分隔符、什么序列化方式(SerDe)。
Metastore 的存储后端有三种模式,这是第一天最重要的知识点:
| 模式 | 元数据存在哪 | 适用场景 |
|---|---|---|
| 内嵌模式 | 自带的 Derby 数据库 | 仅入门体验,同一时刻只允许一个连接 |
| 本地模式 | 独立的 MySQL,Metastore 服务与客户端在同一进程 | 学习、小团队常用 |
| 远程模式 | 独立 MySQL + 独立启动的 Metastore 服务 | 生产环境,多个 Hive/Spark 共享元数据 |
我们直接配置最主流的方案:MySQL 作为元数据库,一步到位避开 Derby 的连接限制。
三、Hive 与传统数据库(MySQL)的区别
这是面试和实际选型中都绕不开的问题,切忌把 Hive 当 MySQL 用。
| 对比维度 | Hive | MySQL 等传统数据库 |
|---|---|---|
| 定位 | 数据仓库,做海量数据分析(OLAP) | 业务数据库,做增删改查(OLTP) |
| 数据存储 | HDFS | 本地文件系统 / 自有存储 |
| 执行引擎 | MapReduce / Tez / Spark | 自身执行引擎 |
| 延迟 | 高(分钟级,启动作业开销大) | 低(毫秒级) |
| 数据规模 | TB / PB 级 | GB / TB 级 |
| 事务与更新 | 弱(早期不支持,后续版本有限支持行级事务) | 完整支持 |
| 索引 | 很弱(主要靠全表扫描) | 完善 |
结论:要做实时查询、频繁单行增删改,不要用 Hive;要对海量历史数据做批量统计分析,Hive 才合适。 另外注意,Hive 不是分布式数据库,它只是数据仓库工具。
四、安装与配置(MySQL 元数据方案)
4.1 准备工作
1. Hadoop 集群正常
先 start-dfs.sh、start-yarn.sh,并用 jps 确认五个进程都在。同时需要在 HDFS 上创建 Hive 运行要用的目录并授权(Hive 3.x 执行时会用到 /tmp 和用户仓库目录):
bash
hadoop fs -mkdir -p /tmp
hadoop fs -mkdir -p /user/hive/warehouse
hadoop fs -chmod g+w /tmp
hadoop fs -chmod g+w /user/hive/warehouse
2. 安装 MySQL 并建库建用户
MySQL 安装好后,创建 Hive 的元数据库(字符集必须用 latin1 或按版本要求,乱码会导致建表失败)和专用账号,并授权:
sql
CREATE DATABASE hive_metadata CHARACTER SET latin1;
CREATE USER 'hive'@'%' IDENTIFIED BY 'Hive@123';
GRANT ALL PRIVILEGES ON hive_metadata.* TO 'hive'@'%';
FLUSH PRIVILEGES;
3. 准备 MySQL JDBC 驱动
把 mysql-connector-java-x.x.x.jar 放到 Hive 安装目录的 lib/ 下。缺了这个包,启动时一定报找不到驱动,这是最常见的环境问题之一。
4.2 修改 hive-site.xml
Hive 的配置文件是 conf/hive-site.xml(默认没有,可由模板复制创建)。核心配置项有五个,先记住它们各自的作用:
| 配置项 | 作用 |
|---|---|
javax.jdo.option.ConnectionURL |
连接 MySQL 的地址和元数据库名 |
javax.jdo.option.ConnectionDriverName |
JDBC 驱动类名 |
javax.jdo.option.ConnectionUserName |
MySQL 用户名 |
javax.jdo.option.ConnectionPassword |
MySQL 密码 |
hive.metastore.warehouse.dir |
仓库在 HDFS 上的位置(/user/hive/warehouse) |
hive.server2.thrift.bind.host / 端口 |
Beeline 连接 HiveServer2 用的地址和端口(默认 10000) |
ConnectionURL 中要显式带上时区参数(新版 MySQL 驱动否则会报时区错误),形如:
jdbc:mysql://主机名:3306/hive_metadata?useSSL=false&serverTimezone=Asia/Shanghai
另外和 Hadoop 一样,建议在 hive-env.sh 中显式配置 HADOOP_HOME 和 HIVE_HOME,避免脚本找不到环境变量。
4.3 初始化元数据库
这一步绝对不能省。Hive 3.x 要求手动向 MySQL 中初始化元数据表结构:
bash
schematool -dbType mysql -initSchema
看到 schemaTool completed 即成功。此时去 MySQL 的 hive_metadata 库中 show tables;,会看到几十张 Hive 自动建好的元数据表(如 DBS、TBLS、COLUMNS_V2 等)。
📸 截图位置 1 :
schematool -dbType mysql -initSchema初始化成功的终端画面。📸 截图位置 2:MySQL 中查询到 Hive 元数据表列表的画面。
五、两种使用方式:hive CLI 与 Beeline
Hive 3.x 推荐使用 HiveServer2 + Beeline 的方式,老的 hive 命令行已不推荐。
先启动 HiveServer2 服务(它是一个常驻服务,建议放在后台):
bash
hiveserver2 &
等待约 10~20 秒服务起来后,另开一个终端用 Beeline 连接:
bash
beeline -u jdbc:hive2://主机名:10000 -n 用户名
看到 0: jdbc:hive2://...> 提示符,就说明连接成功,可以输入 HQL 了。
📸 截图位置 3:Beeline 成功连接 HiveServer2 的提示符画面。
六、跑通第一个例子
在 Beeline 中依次执行:
sql
CREATE DATABASE demo;
USE demo;
CREATE TABLE student (
id INT,
name STRING,
age INT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
SHOW TABLES;
先在本地准备数据文件 student.txt,字段用 Tab 分隔:
1 张三 20
2 李四 21
3 王五 22
导入数据并查询:
sql
LOAD DATA LOCAL INPATH '/home/数据文件路径/student.txt' INTO TABLE student;
SELECT * FROM student;
SELECT age, COUNT(*) FROM student GROUP BY age;
SELECT * 因为不涉及聚合,可以直接读文件,不触发 MapReduce,秒级返回 ;而带 GROUP BY 的统计语句会触发 MapReduce,能看到任务被提交到 YARN,此时打开 8088 页面可以看到对应的作业。
这个对比值得亲手试一次,它能让你直观理解:不是所有 HQL 都会跑 MR,只有需要分布式计算时才会。
📸 截图位置 4 :SELECT * 查询出三行数据的画面。
📸 截图位置 5:GROUP BY 语句触发 MapReduce 并在 8088 看到作业的画面。
七、第一天踩过的坑与对策
坑 1:schematool 初始化报通信链路失败 / 拒绝连接
排查顺序 :MySQL 服务是否启动(systemctl status mysqld)→ URL 中的主机名和端口对不对 → MySQL 是否允许远程连接(user 表 host 为 %)→ 防火墙是否关闭。
坑 2:报错找不到 MySQL 驱动(ClassNotFoundException: com.mysql.jdbc.Driver)
对策 :确认 JDBC jar 确实放进了 Hive 的 lib/ 目录且版本与 MySQL 匹配。新版驱动类名是 com.mysql.cj.jdbc.Driver,MySQL 8.x 要对应调整。
坑 3:MetaException: Version information not found
原因:Hive 3.x 没有执行初始化,或者初始化到了错误的库。
对策 :先执行 schematool -dbType mysql -initSchema;如果库里已有残留脏数据,先清空元数据库再重新初始化。
坑 4:Beeline 连接 HiveServer2 卡住或拒绝连接
原因:HiveServer2 还没完全启动,或没有配置认证用户的模拟(proxyuser)权限。
对策 :启动后多等一会儿再连;并在 Hadoop 的 core-site.xml 中配置允许启动 HiveServer2 的用户代理其他用户(hadoop.proxyuser.xxx.hosts 设为 *、groups 设为 *),重启 HDFS 后重试。
坑 5:查询报 java.lang.OutOfMemoryError
对策 :Hive 跑在 YARN 上,这本质是 Container 内存不足,调大/调整 yarn-site.xml 中 Container 内存参数(和第二天 Hadoop 笔记一致),或把执行引擎切到更省资源的方式做练习。
八、第一天小结
今天要带走的核心认知:Hive 是把 SQL 翻译成分布式任务的数据仓库工具,数据在 HDFS,元数据在 MySQL,计算靠 MapReduce/Tez/Spark;架构主线是「用户接口 → Driver 解析编译优化执行 → Metastore 提供元数据 → 执行引擎算 HDFS 数据」。环境已就绪,明天开始系统学习建库建表,重点攻克 Hive 最有特色的分区表和复杂数据类型。