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

242 阅读2分钟

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

离线数仓架构

一、基础环境准备

1.1 组件版本矩阵

组件推荐版本依赖关系
Hive3.1.3Hadoop 3.x, JDK8
HDFS3.3.6Java 8+
Airflow2.6.3Python 3.8+, MySQL 5.7+
MySQL5.7Hive 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 压缩格式选择

格式压缩比查询速度适用场景
ORCOLAP分析
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 数据校验规则

# 使用Great Expectations进行数据校验
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_bucketP95 > 300s

6.2 日志收集方案

# Filebeat配置示例
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)

生产部署检查清单

  1. 验证Hive元数据备份机制
  2. 配置Airflow SLA Miss告警
  3. 设置HDFS目录配额
  4. 定期执行表统计分析

扩展实践:集成DolphinScheduler实现可视化编排,参考GitHub仓库获取完整Docker编排文件