post on 01 Jun 2025 about 3608words require 13min
CC BY 4.0 (除特别声明或转载文章外)
如果这篇博客帮助到你,可以请我喝一杯咖啡~
Apache Hive 是基于 Hadoop 构建的数据仓库工具,它为海量结构化数据提供类 SQL 的查询能力,并将查询翻译为 MapReduce、Tez 或 Spark 作业执行。Hive 简化了大数据批量分析的使用门槛,让熟悉 SQL 的开发者能够在 Hadoop 生态上轻松进行 ETL、OLAP 和 BI 分析。
Hive 的执行流程
Hive 的运行深度依赖于 Hadoop 的核心生态,包括其分布式文件系统 HDFS、计算框架 MapReduce 以及资源调度器 YARN,因此可以将 Hive 理解为一种构建在 Hadoop 之上的 “SQL on Hadoop” 应用。其核心工作机制是将用户输入的类 SQL 查询语句转换为底层的 MapReduce 任务来执行,也正是因为多了这一步从 SQL 到 MapReduce 的转化开销,所以在同等条件下,Hive 查询的执行效率通常会低于直接编写原生 MapReduce 程序。
Hive 的核心组件包括:
Hive 客户端(CLI、Beeline、JDBC/ODBC)
Driver
Compiler / Optimizer
Execution Engine
Metastore
数据库:创建表时如果不指定数据库,则默认为 default 数据库。 表:物理概念,实际对应 HDFS 上的一个目录。 分区:对应所在表所在目录下的一个子目录。 桶:对应表或分区所在路径的一个文件
1
2
3
4
5
6
7
8
9
-- 创建按日期分区的 ORC 表
CREATE EXTERNAL TABLE logs (
user_id BIGINT,
action STRING,
ts TIMESTAMP
)
PARTITIONED BY (dt STRING)
STORED AS ORC
LOCATION '/data/logs/';
1
2
3
4
5
CREATE TABLE IF NOT EXISTS example.employee(
Id INT COMMENT 'employeeid',
Company STRING COMMENT 'your company',
Money FLOAT COMMENT 'work money',)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE;
可以发现就是对应的 SQL 语句
1
2
3
4
SELECT id, name FROM employee WHERE salary >= 10000;
SELECT department, avg(salary) FROM employee GROUP BY department;
SELECT id, salary, date FROM employee_a UNION ALL
SELECT id, salary, date FROM employee_b;
1
2
3
4
5
6
7
8
9
10
11
-- 加载数据到表(分区)
ALTER TABLE logs ADD PARTITION (dt='2025-06-01');
LOAD DATA INPATH '/raw/logs/2025-06-01/*.log'
INTO TABLE logs PARTITION (dt='2025-06-01');
-- 简单查询
SELECT user_id, COUNT(*) AS cnt
FROM logs
WHERE dt='2025-06-01'
GROUP BY user_id
ORDER BY cnt DESC
LIMIT 10;
1
2
3
4
5
6
-- 统计每个用户每天的前 3 次操作
SELECT dt, user_id, action, ts,
ROW_NUMBER() OVER (PARTITION BY dt, user_id ORDER BY ts) AS rn
FROM logs
WHERE dt >= '2025-06-01' AND dt <= '2025-06-07'
AND rn <= 3;
在 Hive on Spark 模式下,HiveQL 会被提交到 Spark 引擎执行,兼享 Spark 的低延迟与丰富算子。
1
2
-- 启动 Hive 使用 Spark 执行引擎
set hive.execution.engine=spark;
ETL 批量处理
多维 OLAP 分析
数据探索与报表
机器学习特征工程
合理分区
使用列式存储
开启成本模型优化
1
SET hive.cbo.enable=true;
利用 Tez/Spark
小文件合并
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- 1. 计算用户首次活跃日期
CREATE TABLE user_first (
user_id BIGINT,
first_dt STRING
)
STORED AS ORC
AS
SELECT user_id, MIN(dt) AS first_dt
FROM logs
GROUP BY user_id;
-- 2. 次日留存:join 当天活跃用户与第一天活跃日期后一天
SELECT f.first_dt AS reg_dt,
l.dt AS act_dt,
COUNT(DISTINCT f.user_id) AS reg_users,
COUNT(DISTINCT l.user_id) AS retained_users,
ROUND(COUNT(DISTINCT l.user_id) / COUNT(DISTINCT f.user_id), 4) AS retention_rate
FROM user_first f
JOIN logs l
ON f.user_id = l.user_id
AND l.dt = date_add(f.first_dt, 1)
GROUP BY f.first_dt, l.dt
ORDER BY f.first_dt;
Related posts