初识数据仓库——数仓分层到DataX数据采集

一、引言

在之前的博客中,我们学习了Hadoop的底层组件(HDFS、MapReduce、YARN)以及Hive数据仓库工具。我们知道了如何用Hive建表、加载数据、写SQL进行统计分析。

但现实世界的数据并不是一开始就躺在Hive里的。数据的源头,通常是各个业务系统 (如MySQL、Oracle、业务后台等)。业务数据是分散的、局部的、面向事务的 ,而数据分析需要的是全局的、集成的、面向主题的数据。

如何将业务系统中的数据源源不断地抽取到数据仓库中?这就引出了数仓建设的核心流程,以及数据采集工具(如DataX)。

本篇博客将结合企业级数仓建设方法论,从数仓分层架构 讲起,并实战演示如何使用DataX完成从MySQL到HDFS/Hive的全量/增量数据采集。

二、数据仓库分层架构

在构建数仓之前,首先需要明确分层架构。数据仓库通常分为以下几层,目的是为了解耦、复用和提升性能:

分层 英文全称 核心作用
ODS Operational Data Store 贴源层。直接映射业务数据库,不作过多清洗。
DWD Data Warehouse Detail 明细层。进行数据清洗、脱敏、规范化,构建事实表。
DIM Dimension 维度层。存放各类公共维度数据(如时间、地点、用户)。
DWS Data Warehouse Summary 汇总层。轻度汇总,按主题聚合,形成宽表。
ADS Application Data Service 应用层。面向具体报表和业务的直接输出结果。

建库SQL:

sql 复制代码
CREATE DATABASE ods LOCATION '/daas/ods';
CREATE DATABASE dwd LOCATION '/daas/dwd';
CREATE DATABASE dim LOCATION '/daas/dim';
CREATE DATABASE dws LOCATION '/daas/dws';
CREATE DATABASE ads LOCATION '/daas/ads';

三、模拟业务系统数据源

为了完整模拟实战流程,我们在MySQL中创建业务表(模拟刷卡系统)。

1. 创建刷卡源表 szt_data:

sql 复制代码
CREATE TABLE szt.szt_data(
    car_no VARCHAR(255) COMMENT '车牌号',
    card_no VARCHAR(255) COMMENT '卡号',
    close_date VARCHAR(255) COMMENT '结算日期',
    company_name VARCHAR(255) COMMENT '公司名称',
    conn_mark INT COMMENT '联程标记',
    deal_date VARCHAR(255) COMMENT '交易日期时间',
    deal_money DECIMAL(10,2) COMMENT '交易金额',
    deal_type VARCHAR(255) COMMENT '交易类型',
    deal_value DECIMAL(10,2) COMMENT '交易值',
    equ_no VARCHAR(255) COMMENT '设备编码',
    station VARCHAR(255) COMMENT '线路站点'
);

2. 导入测试数据:

sql 复制代码
-- 开启本地文件加载
SET GLOBAL local_infile=1;
LOAD DATA LOCAL INFILE '/root/szt_data.txt' INTO TABLE szt.szt_data FIELDS TERMINATED BY ',';

同样,可以创建用户信息表 szt_user 并导入数据。

四、数据采集神器------DataX

4.1 DataX简介

DataX 是阿里巴巴开源的一款异构数据源离线同步工具。它实现了包括 MySQL、Oracle、HDFS、Hive、HBase 等在内的各种异构数据源之间稳定高效的数据同步功能。

核心架构:DataX采用框架+插件模式,Reader(读插件)和Writer(写插件)由框架调度,通过Channel通道进行高速数据传输。

4.2 下载与安装

bash 复制代码
# 解压并配置环境变量
tar -xvf datax.tar.gz
vim /etc/profile
export DATAX_HOME=/usr/local/soft/datax
export PATH=$PATH:$DATAX_HOME/bin
source /etc/profile

五、实战:DataX从MySQL采集到HDFS

5.1 从MySQL读取数据(测试)

首先,我们可以配置DataX从MySQL读取数据并打印到控制台,用于测试连通性。

配置 szt_data.json:

sql 复制代码
{
    "job": {
        "setting": {
            "speed": {
                 "channel": 3   
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "123456",
                        "column": [
                            "car_no", "card_no", "close_date", "company_name", 
                            "conn_mark", "deal_date", "deal_money", "deal_type", 
                            "deal_value", "equ_no", "station"
                        ],
                        "splitPk": "equ_no",
                        "connection": [
                            {
                                "table": ["szt_data"],
                                "jdbcUrl": ["jdbc:mysql://master:3306/szt"]
                            }
                        ]
                    }
                },
                "writer": {
                    "name": "streamwriter",
                    "parameter": {
                        "print": true
                    }
                }
            }
        ]
    }
}

执行 :datax.py szt_data.json

5.2 增量同步到HDFS(写入ODS层)

在数仓日常调度中,通常是按天进行增量同步 。我们需要在 reader 中增加 where 条件,在 writer 中指定HDFS路径。

DataX 核心配置:

sql 复制代码
{
    "job": {
        "setting": {
            "speed": {"channel": 3},
            "errorLimit": {"record": 0, "percentage": 0.02}
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "123456",
                        "column": ["car_no", "card_no", "deal_date", "deal_money", "equ_no"],
                        "where": "date_format(deal_date,'%Y%m%d')='${dt}'",
                        "splitPk": "equ_no",
                        "connection": [
                            {
                                "table": ["szt_data"],
                                "jdbcUrl": ["jdbc:mysql://master:3306/szt"]
                            }
                        ]
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "defaultFS": "hdfs://master:9000",
                        "fileType": "orc",
                        "path": "/daas/ods/ods_szt_data/dt=${dt}",
                        "fileName": "part",
                        "writeMode": "append",
                        "fieldDelimiter": "\u0001"
                    }
                }
            }
        ]
    }
}

关键参数解析:

  • ${dt}:DataX 动态传参占位符。

  • fileType: orc:目标文件格式为 ORC,压缩率高。

  • fieldDelimiter: \u0001:使用特殊不可见字符作为分隔符,防止与业务数据中的逗号冲突。

  • channel: 3:并发数为3,加快传输速度。

5.3 在Hive ODS层创建表

在执行DataX之前,需要在Hive中建好对应的外部表,并指定相同的HDFS路径。

sql 复制代码
CREATE EXTERNAL TABLE ods.ods_szt_data(
    car_no STRING COMMENT '车牌号',
    card_no STRING COMMENT '卡号',
    close_date STRING COMMENT '结算日期',
    company_name STRING COMMENT '公司名称',
    conn_mark INT COMMENT '联程标记',
    deal_date STRING COMMENT '交易日期时间',
    deal_money DECIMAL(10,2) COMMENT '交易金额',
    deal_type STRING COMMENT '交易类型',
    deal_value DECIMAL(10,2) COMMENT '交易值',
    equ_no STRING COMMENT '设备编码',
    station STRING COMMENT '线路站点'
)
PARTITIONED BY (dt STRING COMMENT '按天分区')
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\u0001'
STORED AS ORC
LOCATION '/daas/ods/ods_szt_data';

六、脚本优化:自动化采集流程

在真实的企业环境中,每天的数据采集不可能靠手工执行一条条命令。我们需要将过程Shell脚本化 ,方便后续接入 Azkaban 或 DolphinScheduler 调度。

6.1 编写Shell调度脚本 ods_szt_data.sh

bash 复制代码
#!/bin/bash

# 接收外部传入的参数(日期,如 20180831)
dt=$1

if [ -z "$dt" ]; then
    echo "请传入日期参数:如 bash ods_szt_data.sh 20180831"
    exit 1
fi

echo "开始采集 ${dt} 的数据..."

# 1. 删除HDFS上该分区已有数据(保证幂等性,防止重复执行导致数据翻倍)
hdfs dfs -rmr -skipTrash /daas/ods/ods_szt_data/dt=${dt}

# 2. 创建HDFS分区目录
hdfs dfs -mkdir -p /daas/ods/ods_szt_data/dt=${dt}

# 3. 执行DataX采集脚本,传入日期参数
python $DATAX_HOME/bin/datax.py /root/szt_data.json -p"-Ddt=${dt}"

# 4. 检查DataX是否执行成功
if [ $? -eq 0 ]; then
    echo "DataX采集完成,开始同步Hive元数据..."
    # 5. 在Hive中增加对应分区元数据
    hive -e "ALTER TABLE ods.ods_szt_data ADD IF NOT EXISTS PARTITION(dt='${dt}');"
    echo "采集任务全流程成功!"
else
    echo "DataX执行失败,请检查日志!"
    exit 1
fi

6.2 执行优化脚本

bash 复制代码
# 赋予执行权限
chmod +x ods_szt_data.sh

# 执行采集任务(采集8月31日的数据)
bash ods_szt_data.sh 20180831

对于用户信息表 szt_user,只需将 ods_szt_data.sh 中的表名、路径和 JSON 脚本替换,即可用同样的流程完成采集。

七、总结

本篇博客完整走了一遍从业务数据库 到数据仓库ODS层的数据接入流程。

步骤 核心操作 关键技术
1. 数仓规划 建立ODS、DWD、DIM、DWS、ADS库 Hive DDL
2. 业务模拟 在MySQL建表并导入数据 MySQL
3. 抽取工具 下载并配置DataX JSON配置
4. 数据同步 MySQL → HDFS (ORC) DataX Reader/Writer
5. 映射建表 ODS外部表映射HDFS路径 Hive External Table
6. 自动化 Shell脚本封装建目录、DataX、加分区 Bash Scripting
相关推荐
棣廷2 小时前
初识Hive(2)
数据仓库·hive·hadoop
geovindu1 天前
Pivoting and Unpivoting Data in SQL using postgreSQL 18
大数据·数据库·数据仓库·sql·postgresql·数据库开发·数据库架构
数据库小学妹1 天前
OLAP数据库怎么选?看清OLTP、数仓、湖仓边界
数据仓库·mpp·列式存储·联机分析处理·数据库选型·olap数据库
程序 代码狂人2 天前
切片表与分区表的区别(数据开发面试版)
java·大数据·开发语言·数据仓库·算法
天河归来2 天前
从原始消息到业务数据:三层数据架构的设计与实践
数据库·数据仓库·架构
注塑机数据采集联网3 天前
中科晟达注塑机 MES 系统:从车间到数字化的智能制造实践
大数据·数据仓库·人工智能·物联网·制造·数据库架构
泡海椒3 天前
JQuick-SQL 逻辑数据仓库:以注册数据集构建轻量分析层
数据库·数据仓库·sql
geovindu4 天前
sql:SQL Pagination and Limiting Results using PorstgreSQL 18.0
大数据·数据仓库·sql·postgresql·数据库开发·数据库架构·1024程序员节