Hive
Hive 是基于 Hadoop 的数据仓库工具,将 HiveQL(类 SQL) 自动转换为 MapReduce / Tez / Spark 作业执行,使不熟悉 MapReduce 的分析人员也能处理 HDFS 上的海量数据。适合离线批量分析,不适合低延迟查询。
架构
用户 / BI 工具
│ HiveQL
▼
HiveServer2(JDBC/ODBC 接入)
│
▼
Driver(解析 → 编译 → 优化 → 执行计划)
│
├── Metastore(MySQL 存储表结构/分区元数据)
│
└── 执行引擎(MapReduce / Tez / Spark)
│
▼
HDFS(实际数据)
数据模型
| 概念 | 说明 |
|---|
| Database | 命名空间,对应 HDFS 一个目录 |
| Table | 内部表(数据由 Hive 管理)或外部表(数据独立存储) |
| Partition | 按列值分区,减少全表扫描(如按日期分区) |
| Bucket | 对分区内数据进一步哈希分桶,提高 JOIN 效率 |
常用 HiveQL
-- 创建内部表
CREATE TABLE user_log (
user_id BIGINT,
action STRING,
ts TIMESTAMP
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS ORC;
-- 创建外部表(删表不删数据)
CREATE EXTERNAL TABLE page_view (
url STRING,
user_id BIGINT
)
PARTITIONED BY (dt STRING)
STORED AS PARQUET
LOCATION '/data/page_view';
-- 添加分区
ALTER TABLE page_view ADD PARTITION (dt='2024-01-01')
LOCATION '/data/page_view/dt=2024-01-01';
-- 加载数据
LOAD DATA INPATH '/tmp/user_log.tsv' INTO TABLE user_log;
-- 聚合查询
SELECT action, COUNT(*) AS cnt
FROM user_log
WHERE dt = '2024-01-01'
GROUP BY action
ORDER BY cnt DESC
LIMIT 10;
-- 动态分区插入
SET hive.exec.dynamic.partition.mode = nonstrict;
INSERT INTO page_view PARTITION (dt)
SELECT url, user_id, dt FROM staging_table;
存储格式对比
| 格式 | 特点 | 适用场景 |
|---|
| TextFile | 纯文本,可直接查看 | 原始数据导入 |
| ORC | 列式存储,压缩率高,支持索引 | 生产分析(推荐) |
| Parquet | 列式存储,Spark 兼容性好 | 与 Spark 混用 |
| Avro | 行式,Schema 演进友好 | 数据序列化传输 |
性能调优
-- 开启 CBO(基于代价的优化器)
SET hive.cbo.enable = true;
-- 开启向量化执行
SET hive.vectorized.execution.enabled = true;
-- Map Join(小表广播,避免 Shuffle)
SET hive.auto.convert.join = true;
SET hive.mapjoin.smalltable.filesize = 25000000;
-- 开启压缩输出
SET hive.exec.compress.output = true;
相关链接
- Hadoop — Hive 依赖的底层计算和存储框架
- HDFS — Hive 表数据的实际存储位置
- Spark — 可作为 Hive 执行引擎(Hive on Spark),也可通过 SparkSQL 读取 Hive 元数据
- Flume — 采集原始日志写入 HDFS,供 Hive 分析