本文是大数据系列第 15 篇,深入讲解 Hive Metastore 的作用、三种部署模式的区别,以及在生产集群中配置远程 Metastore 高可用的实战步骤。
什么是 Metastore
Hive Metastore 是管理元数据的核心组件,负责存储和维护以下信息:
- 数据库、表、列的定义(Schema)
- 分区信息
- 数据存储在 HDFS 的路径映射
- 表的统计信息(用于查询优化)
- SerDe(序列化/反序列化)配置
Metastore 将元数据持久化到关系型数据库(生产环境用 MySQL/MariaDB),对外通过 Thrift 接口提供服务。
三种部署模式
模式一:内嵌模式(Embedded)
HiveServer2 进程
└── Metastore(内嵌)
└── Derby(内嵌数据库)
- Derby 数据库随 Hive 进程内嵌运行
- 只支持单用户,不支持并发访问
- 元数据存储在本地磁盘(
metastore_db/目录) - 仅适合本地单机测试,不可用于多节点集群
模式二:本地模式(Local)
HiveServer2 进程
└── Metastore(同进程内)
└── MySQL/MariaDB(独立数据库)
- Metastore 服务与 HiveServer2 运行在同一个 JVM 进程中
- 启动 HiveServer2 时 Metastore 自动启动
- 支持多用户,元数据存储在外部 MySQL
- 适合开发/测试环境
模式三:远程模式(Remote)— 生产推荐
多个客户端
↓ Thrift
独立 Metastore 服务(9083端口)
└── MySQL/MariaDB
- Metastore 作为独立进程运行,通过 Thrift 提供服务
- 客户端(HiveServer2、Spark、Impala 等)通过
hive.metastore.uris连接 - 支持多 Metastore 实例实现高可用
- 元数据存储与计算分离,稳定可靠
三种模式对比
| 特性 | 内嵌模式 | 本地模式 | 远程模式 |
|---|---|---|---|
| 并发支持 | 单用户 | 多用户 | 多用户 |
| 元数据库 | Derby(内嵌) | MySQL(独立) | MySQL(独立) |
| 服务进程 | 同一进程 | 同一进程 | 独立进程 |
| 高可用 | 否 | 否 | 支持多实例 |
| 适用场景 | 本地测试 | 开发测试 | 生产环境 |
集群环境配置(远程模式)
本示例集群:
- h121:运行 Metastore 服务 + NameNode
- h122:Hive 客户端节点
- h123:运行 Metastore 服务 + DataNode
h121 和 h123(Metastore 服务节点)配置
hive-site.xml 需包含 MySQL 连接信息和 Metastore 配置:
<configuration>
<!-- MySQL 连接 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://h121.wzk.icu:3306/hive_meta?useSSL=false&characterEncoding=UTF-8</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>hive123</value>
</property>
<!-- 仓库路径 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
</configuration>
h122(客户端节点)配置
客户端不需要 MySQL 连接信息,只需指向远程 Metastore 地址:
<configuration>
<!-- 远程 Metastore 地址(配置两个实现高可用) -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://h121.wzk.icu:9083,thrift://h123.wzk.icu:9083</value>
</property>
<!-- 仓库路径保持一致 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
</configuration>
启动与验证
启动 Metastore 服务(h121 和 h123 上各执行)
# 后台启动 Metastore 服务
nohup hive --service metastore > /opt/logs/metastore.log 2>&1 &
# 验证端口 9083 是否监听
lsof -i:9083
# 或
netstat -tlnp | grep 9083
预期输出(端口正常监听):
COMMAND PID USER TYPE DEVICE NAME
java 1234 hadoop TCP *:9083 (LISTEN)
客户端连接测试(h122 上执行)
hive
-- 测试元数据访问
SHOW DATABASES;
USE default;
SHOW TABLES;
SELECT * FROM emp LIMIT 5;
如果能正常返回结果,说明远程 Metastore 配置成功。
常见问题排查
问题1:连接 Metastore 超时
检查 h121/h123 上 Metastore 进程是否存活:
jps | grep HiveMetaStore
问题2:元数据版本不匹配
重新执行初始化:
schematool -dbType mysql -initSchema
# 如已存在则升级
schematool -dbType mysql -upgradeSchema
问题3:多节点元数据不一致
确保 h121 和 h123 连接的是同一个 MySQL 实例,而非各自独立的数据库。两个 Metastore 实例共享同一份元数据,通过 MySQL 的并发控制保证一致性。
Metastore 与其他计算引擎共享
远程 Metastore 最大的价值在于可以被多个计算引擎共用:
Hive ─┐
Spark ─┤──→ Metastore(thrift://h121:9083)──→ MySQL
Impala─┘
Spark 通过 spark.hadoop.hive.metastore.uris 配置即可访问同一份 Hive 元数据,实现跨引擎的表共享,这是构建统一数据湖的基础。