基于Hive+HDFS+Airflow的离线数仓ETL部署指南

一、基础环境准备
1.1 组件版本矩阵
| 组件 | 推荐版本 | 依赖关系 |
|---|
| Hive | 3.1.3 | Hadoop 3.x, JDK8 |
| HDFS | 3.3.6 | Java 8+ |
| Airflow | 2.6.3 | Python 3.8+, MySQL 5.7+ |
| MySQL | 5.7 | Hive Metastore依赖 |
1.2 目录结构规划
/data/warehouse/
├── raw_data
├── stage_data
├── dwd
├── dws
├── ads
└── archive
二、Hive表设计规范
2.1 分层建模策略
graph TD
A[业务系统] -->|增量抽取| B(ODS层)
B -->|数据清洗| C(DWD层)
C -->|维度建模| D(DWS层)
D -->|指标计算| E(ADS层)
style B fill:#FF9800
style E fill:#4CAF50
2.2 分区表设计示例
CREATE EXTERNAL TABLE ods.user_behavior(
user_id BIGINT,
item_id BIGINT,
action STRING
) PARTITIONED BY (dt STRING)
STORED AS ORC
LOCATION '/data/warehouse/ods/user_behavior'
TBLPROPERTIES ("orc.compress"="SNAPPY");
三、Airflow DAG编排
3.1 ETL任务DAG示例
from airflow import DAG
from airflow.providers.apache.hive.operators.hive import HiveOperator
from airflow.providers.apache.hdfs.sensors.hdfs import HdfsSensor
default_args = {
'retries': 3,
'retry_delay': timedelta(minutes=5)
}
with DAG('etl_pipeline',
schedule_interval='@daily',
default_args=default_args) as dag:
wait_raw_data = HdfsSensor(
task_id='wait_raw_data',
filepath='/data/warehouse/raw_data/{{ ds }}/_SUCCESS'
)
load_ods = HiveOperator(
task_id='load_ods',
hql='scripts/load_ods.hql',
hive_cli_conn_id='hive_prod'
)
transform_dwd = HiveOperator(
task_id='transform_dwd',
hql='scripts/dwd_transform.hql'
)
wait_raw_data >> load_ods >> transform_dwd
3.2 关键Operator配置
| Operator类型 | 用途说明 | 关键参数 |
|---|
| HiveOperator | 执行HQL脚本 | hql, hive_cli_conn_id |
| HdfsSensor | 监控上游数据就绪 | filepath, timeout |
| EmailOperator | 任务失败通知 | to, subject, html_content |
| PythonOperator | 自定义处理逻辑 | python_callable |
四、Hive性能调优
4.1 压缩格式选择
| 格式 | 压缩比 | 查询速度 | 适用场景 |
|---|
| ORC | 高 | 快 | OLAP分析 |
| Parquet | 中 | 快 | 嵌套数据结构 |
| Text | 无 | 慢 | 原始数据暂存 |
4.2 参数优化配置
SET hive.vectorized.execution.enabled = true;
SET hive.merge.mapfiles = true;
SET hive.merge.size.per.task = 256000000;
SET hive.merge.smallfiles.avgsize = 128000000;
SET hive.exec.dynamic.partition.mode=nonstrict;
SET hive.exec.max.dynamic.partitions=1000;
五、数据质量保障
5.1 数据校验规则
import great_expectations as ge
df = ge.read_hive(
table="dwd.user_behavior",
partitions={"dt": "2023-07-20"}
)
result = df.expect_column_values_to_not_be_null("user_id")
if not result["success"]:
send_alert("存在空用户ID")
5.2 数据血统追踪
graph LR
A[MySQL业务库] --> B{每日增量}
B -->|Airflow| C[ODS层]
C -->|Hive ETL| D[DWD层]
D -->|聚合| E[DWS层]
E -->|报表| F[BI系统]
六、运维监控体系
6.1 监控指标看板
| 指标类型 | PromQL查询示例 | 告警阈值 |
|---|
| ETL任务延迟 | airflow_dagrun_duration{task_id="load_ods"} | > 2h |
| HDFS存储使用 | hdfs_namenode_capacity_used_percent | > 85% |
| Hive查询耗时 | hive_query_duration_seconds_bucket | P95 > 300s |
6.2 日志收集方案
filebeat.inputs:
- type: log
paths:
- /var/log/hive/*.log
fields:
service: hive
output.elasticsearch:
hosts: ["es-node:9200"]
index: "hive-logs-%{+yyyy.MM.dd}"
七、典型ETL场景
7.1 增量数据同步
INSERT INTO TABLE dwd.orders
SELECT * FROM ods.orders
WHERE update_time > '{{ prev_ds }}'
AND update_time <= '{{ ds }}'
7.2 缓慢变化维处理
MERGE INTO dim_user AS T
USING (
SELECT user_id, name, address
FROM ods.user_updates
) AS S
ON T.user_id = S.user_id
WHEN MATCHED THEN
UPDATE SET T.address = S.address
WHEN NOT MATCHED THEN
INSERT VALUES (S.user_id, S.name, S.address)
生产部署检查清单:
- 验证Hive元数据备份机制
- 配置Airflow SLA Miss告警
- 设置HDFS目录配额
- 定期执行表统计分析
扩展实践:集成DolphinScheduler实现可视化编排,参考GitHub仓库获取完整Docker编排文件