大数据-234 离线数仓 - Hive ADS 导出 MySQL DataX(hdfsreader→mysqlwriter)实战配置与踩坑速查

0 阅读5分钟

TL;DR

  • 场景:离线数仓 ADS 四张 Hive 表按分区 dt 导出到 MySQL(Hive/HDFS → MySQL)。
  • 结论:DataX 用 hdfsreader 读 Hive 表落地文件路径 + mysqlwriter replace 写入,关键在“分区路径、字段映射、JDBC 参数、脚本变量”。
  • 产出:一套可复用 JSON + 一键脚本模板 + 常见报错的定位与修复清单。

大数据-234 离线数仓 - Hive ADS 导出 MySQL DataX(hdfsreader→mysqlwriter)实战配置与踩坑速查

版本矩阵

状态项目说明
DataX JSON 结构与参数替换DataX 3.x 常见分发版 JSON 结构与 -p "-Ddo_date=..." 参数替换为通用用法;不同发行包插件名一致但插件参数可能略有差异(以实际插件文档为准)。
Hive 表落地到 HDFS 读取方式通过 Hive warehouse 路径 + 分区目录读取,前提是目标表确实以文本文件方式落地且分隔符与配置一致。
MySQL 5.7/8.0 兼容写入mysqlwriter + writeMode=replace 常用于按主键覆盖;需确保目标表主键/唯一键设计正确。
⚠️Kerberos/HDFS HA 场景defaultFS、NameNode、认证与 HA 配置会额外影响读取;本文配置偏“非 Kerberos + 单 NameNode”示例。
⚠️ORC/Parquet 存储格式hdfsreader 读的是文件行,不会自动解析 ORC/Parquet;若 Hive 表为 ORC/Parquet,需要走其他 Reader 或先转 text/CSV 落地。

离线数仓 整体架构图规划

基本架构

之前已经完成了Flume的数据采集到HDFS中,现在我们将依次走通流程:

  • ODS
  • DWD
  • DWS
  • ADS
  • DataX数据导出到MySQL 离线数仓 数据流转流程 ADS有4张表需要从数据仓库的ADS层导入MySQL,即:Hive => MySQL
ads.ads_member_active_count
ads.ads_member_retention_count
ads.ads_member_retention_rate
ads.ads_new_member_cnt

在Hive中可以看到这几张表: Hive 中查看表

创建库表

-- MySQL 建表
-- 活跃会员数
create database dwads;
drop table if exists dwads.ads_member_active_count;
create table dwads.ads_member_active_count(
  `dt` varchar(10) COMMENT '统计日期',
  `day_count` int COMMENT '当日会员数量',
  `week_count` int COMMENT '当周会员数量',
  `month_count` int COMMENT '当月会员数量',
  primary key (dt)
);

-- 新增会员数
drop table if exists dwads.ads_new_member_cnt;
create table dwads.ads_new_member_cnt
(
  `dt` varchar(10) COMMENT '统计日期',
  `cnt` int,
  primary key (dt)
);

-- 会员留存数
drop table if exists dwads.ads_member_retention_count;
create table dwads.ads_member_retention_count
(
  `dt` varchar(10) COMMENT '统计日期',
  `add_date` varchar(10) comment '新增日期',
  `retention_day` int comment '截止当前日期留存天数',
  `retention_count` bigint comment '留存数',
  primary key (dt)
) COMMENT '会员留存情况';

-- 会员留存率
drop table if exists dwads.ads_member_retention_rate;
create table dwads.ads_member_retention_rate
(
  `dt` varchar(10) COMMENT '统计日期',
  `add_date` varchar(10) comment '新增日期',
  `retention_day` int comment '截止当前日期留存天数',
  `retention_count` bigint comment '留存数',
  `new_mid_count` bigint comment '当日会员新增数',
  `retention_ratio` decimal(10,2) comment '留存率',
  primary key (dt)
) COMMENT '会员留存率';

执行结果如下图: 创建聚合表

DataX

DataX 之前章节已经介绍过了 这里就简单一说 详细教程看之前的

基本介绍

DataX 是阿里巴巴开源的一款分布式数据同步工具,用于实现各种异构数据源之间高效、稳定的数据同步。其主要功能包括数据的批量导入、导出和实时传输,支持多种主流数据源,例如关系型数据库、NoSQL 数据库、大数据存储系统等。

DataX 的核心思想是“插件化架构”,通过灵活的 Reader 和 Writer 插件实现不同数据源之间的数据交换。

DataX 的特点

插件化架构

  • Reader:用于从数据源读取数据。
  • Writer:用于将数据写入目标存储。
  • 插件开发简单,可以根据需要扩展支持新的数据源。

高性能与高扩展性

  • 支持大规模数据同步,处理速度快。
  • 支持多线程并发传输,利用 CPU 和 IO 性能。
  • 可配置分片任务(Shard),实现分布式同步。

兼容性强

  • 支持丰富的异构数据源,包括 MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、HDFS、Hive、ODPS、ElasticSearch 等。
  • 可在不同系统之间传输数据,比如从传统 RDBMS 数据库迁移到大数据系统。

易用性

  • 配置简单,基于 JSON 文件定义任务,易于上手。
  • 提供详尽的运行日志,便于定位和解决问题。
  • 开源代码,支持二次开发。

可监控性

  • 提供详细的任务运行指标,比如吞吐量、数据量等。
  • 支持失败任务自动重试,确保数据同步过程的可靠性。

配置文件

导出活跃会员数(ads_member_active_count),编写一个JSON出来:

vim /opt/wzk/datax/export_member_active_count.json

hdfsreader => mysqlwriter

{
  "job": {
    "setting": {
      "speed": {
        "channel": 1
      }
    },
    "content": [{
      "reader": {
        "name": "hdfsreader",
        "parameter": {
          "path":
          "/user/hive/warehouse/ads.db/ads_member_active_count/dt=$do_date/*",
          "defaultFS": "hdfs://h121.wzk.icu:9000",
          "column": [{
            "type": "string",
            "value": "$do_date"
          }, {
            "index": 0,
            "type": "string"
          },
            {
              "index": 1,
              "type": "string"
            },
            {
              "index": 2,
              "type": "string"
            }
          ],
          "fileType": "text",
          "encoding": "UTF-8",
          "fieldDelimiter": ","
        }
      },
      "writer": {
        "name": "mysqlwriter",
        "parameter": {
          "writeMode": "replace",
          "username": "hive",
          "password": "hive@wzk.icu",
          "column": ["dt","day_count","week_count","month_count"],
          "preSql": [
            ""
          ],
          "connection": [{
            "jdbcUrl":
            "jdbc:mysql://h122.wzk.icu:3306/dwads?
            useUnicode=true&characterEncoding=utf-8",
            "table": [
              "ads_member_active_count"
            ]
          }]
        }
      }
    }]
  }
}

写入的内容如下所示: DataX 数据写入

编写命令

DataX的运行的方式如下所示:

python datax.py -p "-Ddo_date=2020-07-21" /opt/wzk/datax/export_member_active_count.json

编写脚本

编写一个脚本用来完成这个流程:

vim /opt/wzk/hive/export_member_active_count.sh

写入的内容如下所示:

#!/bin/bash
JSON= /opt/wzk/datax
source /etc/profile
if [ -n "$1" ] ;then
do_date=$1
else
do_date=`date -d "-1 day" +%F`
fi
python $DATAX_HOME/bin/datax.py -p "-Ddo_date=$do_date" $JSON/export_member_active_count.json

写入的内容如下所示: 启动 DataX 的脚本编写

错误速查

症状根因定位修复
DataX 运行成功但 MySQL 没数据HDFS 路径匹配不到分区目录(dt 不存在/日期变量没替换)看 DataX 日志:reader 侧读到的 record 数是否为 0;检查实际 HDFS 目录是否存在 dt=2020-07-21
确认 -Ddo_date 传入;检查 path 是否为真实 warehouse 路径;必要时先 hdfs dfs -ls 验证
报错 “FileNotFoundException”/“No such file or directory”path 写错、表名/库名不一致、dt 分区目录缺失直接在 HDFS 上 ls /user/hive/warehouse/.../dt=...
修正 path;保证 Hive 表已生成对应 dt 分区数据(跑完 ADS 产出任务)
MySQL 端报错 “Unknown database/table”MySQL 库表未建或库名不一致(dwads)MySQL 连接后 show databases; show tables;
先建库建表;保持 DataX jdbcUrl 的库名与建表一致
MySQL 写入报 “Data truncation / Incorrect integer value”DataX column 类型/顺序与 MySQL 字段不匹配;把数字当 string 或列错位查看 DataX writer 侧异常行;对照 MySQL 表结构与 column 映射
保证 reader column index 顺序与 writer column 顺序一致;必要时在 reader 侧设置 type(int/long)或在 MySQL 表侧放宽类型
replace 覆盖异常:数据被重复/丢失writeMode=replace 依赖主键/唯一键;你的表主键设计不合理(例如留存表主键只用 dt)观察同 dt 不同 add_date/retention_day 的记录是否互相覆盖
为多维明细表设计联合主键(如 dt+add_date+retention_day)或改为 insert + 先清分区数据
DataX JSON 解析失败JSON 格式不合法:换行、引号、尾逗号、注释;jdbcUrl 被写成多行DataX 启动即报 JSON parse error;定位到具体行号
用单行字符串写 jdbcUrl;移除注释;用 jq/IDE 校验 JSON
连接 MySQL 报 “Communications link failure/Access denied”网络不通/端口未放行/账号权限不足/密码错误telnet/nc 3306;MySQL 登录测试;查看 MySQL user grants
放通网络与 3306;修正账号密码;授予目标库表权限
脚本执行报 “datax.py: command not found”DATAX_HOME 未生效或路径写错;未 source 环境echo $DATAX_HOME;which python;检查脚本是否 source /etc/profile
在脚本中明确 export DATAX_HOME=... 或确保 profile 正确;用绝对路径调用 datax.py
脚本里 JSON 目录变量为空导致找不到文件JSON= /opt/wzk/datax 写法有空格,变量实际为空set -x 或 echo $JSON
改为 JSON=/opt/wzk/datax(等号两侧不能有空格)
读到数据但字段 dt 不对reader 里 dt 用 value 写死 $do_date,但参数没传或变量名不一致打印运行参数;检查 DataX 参数替换是否发生
保持 -Ddo_date 与 JSON 中一致;必要时把 dt 从文件内容读取而不是写死

其他系列

🚀 AI篇持续更新中(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南! AI研究-132 Java 生态前沿 2025:Spring、Quarkus、GraalVM、CRaC 与云原生落地 🔗 AI模块直达链接

💻 Java篇持续更新中(长期更新)

Java-218 RocketMQ Java API 实战:同步/异步 Producer 与 Pull/Push Consumer MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务已完结,Dubbo已完结,MySQL已完结,MongoDB已完结,Neo4j已完结,FastDFS 已完结,OSS已完结,GuavaCache已完结,EVCache已完结,RabbitMQ已完结,RocketMQ正在更新... 深入浅出助你打牢基础! 🔗 Java模块直达链接

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解 🔗 大数据模块直达链接