TL;DR

  • 场景:离线广告数仓中,ADS 层 Hive 数据按天装载后,需要稳定导出到 MySQL 做查询与展示。
  • 结论:用 Shell + Hive 分区脚本 + DataX JSON 参数化,是一套简单且可复用的离线导数方案。
  • 产出:给出 ADS 装载、DataX 导出、MySQL 落库、常见报错定位与修复清单。

导入数据

加载 ADS 层

ad_show_page

sh /opt/wzk/hive/ads_load_ad_show_page.sh 2020-07-21

查看 Hive 中的数据:

hive

use ads;
select * from ads_ad_show_place limit 5;

继续导入其他数据:

sh /opt/wzk/hive/ads_load_ad_show_page.sh 2020-07-22
sh /opt/wzk/hive/ads_load_ad_show_page.sh 2020-07-23
sh /opt/wzk/hive/ads_load_ad_show_page.sh 2020-07-24

最终的 Hive 的数据量如下所示:

select count(*) from ads_ad_show_place;

ad_show_page_window

sh /opt/wzk/hive/ads_load_ad_show_page_window.sh 2020-07-21

查看 Hive 中的数据如下:

hive

use ads;
select * from ads_ad_show_place_window limit 5;

继续加载其他的数据:

sh /opt/wzk/hive/ads_load_ad_show_page_window.sh 2020-07-22
sh /opt/wzk/hive/ads_load_ad_show_page_window.sh 2020-07-23
sh /opt/wzk/hive/ads_load_ad_show_page_window.sh 2020-07-24

Hive 中的数据总数如下:

select count(*) from ads_ad_show_place_window;

导出数据

执行步骤

  • 在 MySQL 创建对应的表
  • 创建配置文件(JSON)
  • 执行命令,使用 JSON 配置文件,测试
  • 编写执行脚本(Shell)
  • Shell 脚本的测试

MySQL

drop table if exists dwads.ads_ad_show_place;
create table dwads.ads_ad_show_place(
  ad_action tinyint,
  hour varchar(2),
  place varchar(20),
  product_id int,
  cnt int,
  dt varchar(10)
);

DataX

配置文件

vim /opt/wzk/datax/ads_ad_show_place.json

写入的内容如下所示:

{
  "job":{
    "setting":{
      "speed":{
        "channel":1
      }
    },
    "content":[
      {
        "reader":{
          "name":"hdfsreader",
          "parameter":{
            "path":"/user/hive/warehouse/ads.db/ads_ad_show_place/dt=$do_date/*",
            "defaultFS":"hdfs://h121.wzk.icu:9000",
            "column":[
              {
                "index":0,
                "type":"string"
              },
              {
                "index":1,
                "type":"string"
              },
              {
                "index":2,
                "type":"string"
              },
              {
                "index":3,
                "type":"string"
              },
              {
                "index":4,
                "type":"string"
              },
              {
                "type":"string",
                "value":"$do_date"
              }
            ],
            "fileType":"text",
            "encoding":"UTF-8",
            "fieldDelimiter":","
          }
        },
        "writer":{
          "name":"mysqlwriter",
          "parameter":{
            "writeMode":"insert",
            "username":"hive",
            "password":"hive@wzk.icu",
            "column":[
              "ad_action",
              "hour",
              "place",
              "product_id",
              "cnt",
              "dt"
            ],
            "preSql":[
              "delete from ads_ad_show_place where dt='$do_date'"
            ],
            "connection":[
              {
                "jdbcUrl":"jdbc:mysql://h122.wzk.icu:3306/dwads?useUnicode=true&characterEncoding=utf-8",
                "table":[
                  "ads_ad_show_place"
                ]
              }
            ]
          }
        }
      }
    ]
  }
}

DataX 简介

DataX 是由阿里巴巴开源的分布式离线数据同步工具,用于解决不同存储系统之间的数据传输问题。它被设计为一种高效、稳定、易扩展的工具,能够适应多种复杂的数据同步需求。

核心特点

支持多种数据源:

  • 关系型数据库:MySQL, PostgreSQL, Oracle, SQL Server, DB2 等。
  • NoSQL 数据库:MongoDB, HBase 等。
  • 大数据存储系统:Hive, MaxCompute (ODPS), HDFS。
  • 其他:FTP 文件、ElasticSearch 等。

高性能:

  • 基于多线程的并行架构,能充分利用机器的多核性能。
  • 支持分片传输,提高数据传输的吞吐量。

灵活性和易用性:

  • 配置文件化:使用 JSON 格式的配置文件定义任务,简单直观。
  • 支持任务调度,可与调度工具集成实现定时任务。
  • 兼容多种数据格式和传输协议。

扩展性:

  • 插件式架构,开发者可以通过编写 Reader 和 Writer 插件支持新的数据源。

开源与社区支持:

  • 基于 Apache 2.0 开源协议,开发者可以自由使用和修改。
  • 拥有活跃的社区和丰富的文档支持。

组成部分

Reader:

  • 负责从数据源中读取数据。
  • 示例:MySQLReader, HdfsReader。

Writer:

  • 负责将数据写入目标存储。
  • 示例:MySQLWriter, MySQLWriter。

Framework:

  • DataX 的核心调度引擎,负责 Reader 和 Writer 的协调工作。
  • 提供错误处理、数据校验、性能优化等功能。

Transform:

  • 用于对传输的数据进行处理和转换(可选)。
  • 例如数据格式的转换、字段的增删改等。

工作流程

初始化:

  • 加载用户配置的 JSON 文件,解析 Reader 和 Writer 的配置。
  • 准备任务上下文。

读取数据:

  • Reader 读取源数据并以批量的方式输出。

转换数据:

  • 可选步骤,Transform 模块对数据进行处理。

写入数据:

  • Writer 接收 Reader 输出的数据并将其写入目标存储。

任务管理与监控:

  • DataX 提供实时的任务运行日志和统计信息,包括速度、成功率、错误信息等。

执行导出

vim /opt/wzk/hive/ads_ad_show_place.sh

写入的内容如下所示:

#!/bin/bash
source /etc/profile
JSON=/opt/wzk/datax
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/ads_ad_show_place.json

执行脚本可以得到结果:

sh /opt/wzk/hive/ads_ad_show_place.sh 2020-07-21

错误速查

症状根因修复
DataX 启动即报 JSON 解析错误preSql 中字符串跨行,JSON 非法用 python -m json.tool 或在线 JSON 校验器检查配置,将 delete from ads_ad_show_place where dt='$do_date' 写成单行合法字符串
DataX 任务执行成功但 MySQL 无数据HDFS path 分区路径不存在或日期变量未替换检查 /user/hive/warehouse/.../dt=$do_date/* 是否实际有文件,确认 -Ddo_date 传参成功,且 Hive 分区目录与表名一致
导出时报字段数不匹配HDFS 读取列数与 MySQL 目标表列数不一致对照 reader.column 与 writer.column 数量,保持源 5 列 + 补 1 个 dt 常量,与目标 6 列严格对齐
运行脚本提示找不到 datax.py环境变量未加载或 $DATAX_HOME 未生效echo $DATAX_HOME 检查变量,在 /etc/profile 中补齐 DATAX_HOME,并重新 source
MySQL 导出重复数据未按分区先删后写,或 preSql 未生效查询同一 dt 是否存在重复记录,保留 preSql delete where dt='$do_date',并确认表含 dt 字段
Hive 查询无结果ADS 层脚本未成功执行或查询表名写错先执行 show tables,再核对脚本日志,统一表名与脚本名,避免 ad_show_pageads_ad_show_place 混用
文档读者复现失败文中命名、代码块语言标记、截图与文本不完全一致通读标题、脚本名、SQL 表名、JSON 路径统一命名规范;Shell 用 shell 代码块,SQL 用 sql 代码块
导出脚本执行正常但日期不对未传参时默认取前一天,和示例日期不一致打印 do_date 值,在脚本中增加 echo $do_date 便于核对,重跑指定日期