Bootstrap

电商数仓——DataX同步全量数据(同步MySQL数据到HDFS案例)

一、同步MySQL数据到HDFS案例

案例要求:同步gmall数据库中base_province表数据到HDFS的/base_province目录

需求分析:要实现该功能,需选用MySQLReader和HDFSWriter,MySQLReader具有两种模式分别是TableMode和QuerySQLMode,前者使用table,column,where等属性声明需要同步的数据;后者使用一条SQL查询语句声明需要同步的数据。

因为需要使用到MySQL和HDFS,需要确保MySQL服务和HDFS进程都成功启动。

1.MySQLReader之TableMode

1.1 编写配置文件

(1)创建配置文件base_province.json

 vim /opt/module/datax/job/base_province.json

(2)配置文件内容如下

{
    "job": {
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "column": [
                            "id",
                            "name",
                            "region_id",
                            "area_code",
                            "iso_code",
                            "iso_3166_2",
                            "create_time",
                            "operate_time"
                        ],
                        "where": "id>=3",
                        "connection": [
                            {
                                "jdbcUrl": [
                                    "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"
                                ],
                                "table": [
                                    "base_province"
                                ]
                            }
                        ],
                        "password": "000000",
                        "splitPk": "",
                        "username": "root"
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "column": [
                            {
                                "name": "id",
                                "type": "bigint"
                            },
                            {
                                "name": "name",
                                "type": "string"
                            },
                            {
                                "name": "region_id",
                                "type": "string"
                            },
                            {
                                "name": "area_code",
                                "type": "string"
                            },
                            {
                                "name": "iso_code",
                                "type": "string"
                            },
                            {
                                "name": "iso_3166_2",
                                "type": "string"
                            },
                            {
                                "name": "create_time",
                                "type": "string"
                            },
                            {
                                "name": "operate_time",
                                "type": "string"
                            }
                        ],
                        "compress": "gzip",
                        "defaultFS": "hdfs://hadoop102:8020",
                        "fieldDelimiter": "\t",
                        "fileName": "base_province",
                        "fileType": "text",
                        "path": "/base_province",
                        "writeMode": "append"
                    }
                }
            }
        ],
        "setting": {
            "speed": {
                "channel": 1
            }
        }
    }
}

配置文件说明

(1)Reader参数说明

"reader": {

                    "name": "mysqlreader",        #使用MySQL读取器

                    "parameter": {

                        "column": [ "id","name", "region_id", "area_code", "iso_code","iso_3166_2",

"create_time","operate_time" ],

                        "where": "id>=3",       # where过滤条件,只同步id>3的数据

                        "connection": [

                            {

                                "jdbcUrl": [        #数据库JDBC URL

                                    "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"

                                ],

                                "table": [

                                    "base_province"        #需要同步的表名

                                ]

                            }

                        ],

                        "password": "******",        #数据库密码

                        "splitPk": "",                #分片字段,如果指定该字段,则DataX会启动多个Taask同步数据;若未指定,则只会有单个Task。该参数只在TableMode模式下有效,QueryMode只会有单个Task。

                        "username": "root"        #数据库用户名

                    }

                }

(2)Writer参数说明

"writer": {

                    "name": "hdfswriter",

                    "parameter": {

                        "column": [        #列信息

                            {

                                "name": "id",

                                "type": "bigint"

                            },

                            {

                                "name": "name",

                                "type": "string"

                            },

                            {

                                "name": "region_id",

                                "type": "string"

                            },

                            {

                                "name": "area_code",

                                "type": "string"

                            },

                            {

                                "name": "iso_code",

                                "type": "string"

                            },

                            {

                                "name": "iso_3166_2",

                                "type": "string"

                            },

                            {

                                "name": "create_time",

                                "type": "string"

                            },

                            {

                                "name": "operate_time",

                                "type": "string"

                            }

                        ],

                        "compress": "gzip",         #HDFS压缩类型

                        "defaultFS": "hdfs://hadoop102:8020",        #HDFS文件系统给namenode节点地址

                        "fieldDelimiter": "\t",       #HDFS文件字段分隔符

                        "fileName": "base_province",        #HDFS文件名前缀

                        "fileType": "text",        #HDFS文件类型,支持“text”或“orc”

                        "path": "/base_province",       #HDFS文件系统目标路径

                        "writeMode": "append"        #数据写入格式

                    }

                }

(3)Setting参数说明

 "setting": {

            "speed": {        #传输速度配置

                "channel": 1        #并发数

            }

        }

        HFDS Writer并未提供nullFormat参数:也就是用户并不能自定义null值写到HFDS文件中的存储格式。默认情况下,HFDS Writer会将null值存储为空字符串(''),而Hive默认的null值存储格式为\N。所以后期将DataX同步的文件导入Hive表就会出现问题。

解决该问题的方案有两个:

一是修改DataX HDFS Writer的源码,增加自定义null值存储格式的逻辑,可参考记Datax3.0解决MySQL抽数到HDFSNULL变为空字符的问题_datax nullformat-CSDN博客

二是在Hive中建表时指定null值存储格式为空字符串(''),例如:

CREATE EXTERNAL TABLE base_province

(

    `id`         STRING COMMENT '编号',

    `name`       STRING COMMENT '省份名称',

    `region_id`  STRING COMMENT '地区ID',

    `area_code`  STRING COMMENT '地区编码',

    `iso_code`   STRING COMMENT '旧版ISO-3166-2编码,供可视化使用',

    `iso_3166_2` STRING COMMENT '新版IOS-3166-2编码,供可视化使用'

) COMMENT '省份表'

    ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'

    NULL DEFINED AS ''

LOCATION '/base_province/';

1.2 提交任务

1)在HDFS创建base_province目录

使用DataX向HDFS同步数据时,需确保目标路径已存在

hadoop  fs  -mkdir  /base_province

2)进入DataX根目录

cd /opt/module/datax

3)开始同步

python bin/datax.py job/base_province.json

4)查看同步完成后的结果

查看HDFS文件

hadoop fs -cat /base_province/* | zcat

内容如下:

2. MySQLReader之QuerySQLMode

2.1 编写配置文件

(1)创建并修改配置文件base_province_sql.json

vim /opt/module/datax/job/base_province_sql.json

(2)配置文件内容如下

{

    "job": {

        "content": [

            {

                "reader": {

                    "name": "mysqlreader",

                    "parameter": {

                        "connection": [

                            {

                                "jdbcUrl": [

                                    "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"

                                ],

                                "querySql": [

                                    "select id,name,region_id,area_code,iso_code,iso_3166_2,create_time,operate_time from base_province where id>=3"

                                ]

                            }

                        ],

                        "password": "000000",

                        "username": "root"

                    }

                },

                "writer": {

                    "name": "hdfswriter",

                    "parameter": {

                        "column": [

                            {

                                "name": "id",

                                "type": "bigint"

                            },

                            {

                                "name": "name",

                                "type": "string"

                            },

                            {

                                "name": "region_id",

                                "type": "string"

                            },

                            {

                                "name": "area_code",

                                "type": "string"

                            },

                            {

                                "name": "iso_code",

                                "type": "string"

                            },

                            {

                                "name": "iso_3166_2",

                                "type": "string"

                            },

                            {

                                "name": "create_time",

                                "type": "string"

                            },

                            {

                                "name": "operate_time",

                                "type": "string"

                            }

                        ],

                        "compress": "gzip",

                        "defaultFS": "hdfs://hadoop102:8020",

                        "fieldDelimiter": "\t",

                        "fileName": "base_province",

                        "fileType": "text",

                        "path": "/base_province",

                        "writeMode": "append"

                    }

                }

            }

        ],

        "setting": {

            "speed": {

                "channel": 1

            }

        }

    }

}

配置文件说明

(1)Reader参数说明

                "reader": {

                    "name": "mysqlreader",

                    "parameter": {

                        "connection": [

                            {

                                "jdbcUrl": [        #数据JDBC URL

                                    "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"

                                ],

                                "querySql": [        #SQL查询语句。查询base_province表中id>3的数据

                                    "select id,name,region_id,area_code,iso_code,iso_3166_2,create_time,operate_time from base_province where id>=3"

                                ]

                            }

                        ],

                        "password": "000000",        #数据库密码

                        "username": "root"        #数据库用户名

                    }

                }

2.2 提交任务

1)清空历史数据

hadoop fs -rm -r -f /base_province/*

2)进入DataX根目录

cd /opt/module/datax

3)开始同步

python bin/datax.py job/base_province_sql.json

4)查看结果

查看HDFS文件

hadoop fs -cat /base_province/* | zcat

3. DataX传参

        通常情况下,离线数据同步任务需要每日定时重复执行,故HDFS上的目标路径通常会包含一层日期,以对每日同步的数据加以区分,也就是说每日同步数据的目标路径不是固定不变的,因此DataX配置文件中HDFS Writer的path参数的值应该是动态的。为实现这一效果,就需要使用DataX传参的功能。

        DataX传参的用法如下,在JSON配置文件中使用${param}引用参数,在提交任务时使用-p"-Dparam=value"传入参数值。

3.1 修改配置文件

1)修改配置文件base_province.json

vim /opt/module/datax/job/base_province.json

配置文件内容如下

{

    "job": {

        "content": [

            {

                "reader": {

                    "name": "mysqlreader",

                    "parameter": {

                        "connection": [

                            {

                                "jdbcUrl": [

                                    "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"

                                ],

                                "querySql": [

                                    "select id,name,region_id,area_code,iso_code,iso_3166_2,create_time,operate_time from base_province where id>=3"

                                ]

                            }

                        ],

                        "password": "000000",

                        "username": "root"

                    }

                },

                "writer": {

                    "name": "hdfswriter",

                    "parameter": {

                        "column": [

                            {

                                "name": "id",

                                "type": "bigint"

                            },

                            {

                                "name": "name",

                                "type": "string"

                            },

                            {

                                "name": "region_id",

                                "type": "string"

                            },

                            {

                                "name": "area_code",

                                "type": "string"

                            },

                            {

                                "name": "iso_code",

                                "type": "string"

                            },

                            {

                                "name": "iso_3166_2",

                                "type": "string"

                            },

                            {

                                "name": "create_time",

                                "type": "string"

                            },

                            {

                                "name": "operate_time",

                                "type": "string"

                            }

                        ],

                        "compress": "gzip",

                        "defaultFS": "hdfs://hadoop102:8020",

                        "fieldDelimiter": "\t",

                        "fileName": "base_province",

                        "fileType": "text",

                        "path": "/base_province/${dt}",

                        "writeMode": "append"

                    }

                }

            }

        ],

        "setting": {

            "speed": {

                "channel": 1

            }

        }

    }

}

3.2 提交任务

1)创建目标路径

hadoop fs -mkdir /base_province/2022-06-08

2)进入DataX目录

cd /opt/module/datax

3)开始

python bin/datax.py -p"-Ddt=2022-06-08" job/base_province.json

3.3 查看结果

二、同步HDFS数据到MySQL案例

案例要求:同步HDFS上的/base_province目录下的数据到MySQL gmall数据库下的test_province表。

需求分析:要实现该功能,需选用HDFSReader和MySQLWriter。

1.编写配置文件

1)创建配置文件test_province.json

 vim /opt/module/datax/job/test_province.json

配置文件内容如下

{

    "job": {

        "content": [

            {

                "reader": {

                    "name": "hdfsreader",

                    "parameter": {

                        "defaultFS": "hdfs://hadoop102:8020",

                        "path": "/base_province/2022-06-08",

                        "column": [

                            "*"

                        ],

                        "fileType": "text",

                        "compress": "gzip",

                        "encoding": "UTF-8",

                        "nullFormat": "\\N",

                        "fieldDelimiter": "\t",

                    }

                },

                "writer": {

                    "name": "mysqlwriter",

                    "parameter": {

                        "username": "root",

                        "password": "000000",

                        "connection": [

                            {

                                "table": [

                                    "test_province"

                                ],

                                "jdbcUrl": "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"

                            }

                        ],

                        "column": [

                            "id",

                            "name",

                            "region_id",

                            "area_code",

                            "iso_code",

                            "iso_3166_2",

"create_time",

"operate_time"

                        ],

                        "writeMode": "replace"

                    }

                }

            }

        ],

        "setting": {

            "speed": {

                "channel": 1

            }

        }

    }

}

配置文件说明

(1)Reader参数说明

"reader": {

                    "name": "hdfsreader",

                    "parameter": {

                        "defaultFS": "hdfs://hadoop102:8020",        #HDFS文件系统namenode地址

                        "path": "/base_province",        #文件所在路径

                        "column": [        #需要同步的列,*标识所有列

                            "*"

                        ],

                        "fileType": "text",        #文件类型

                        "compress": "gzip",        #压缩类型

                        "encoding": "UTF-8",        #文件编码

                        "nullFormat": "\\N",        #null值存储格式

                        "fieldDelimiter": "\t",        #字段分隔符

                    }

                }

(2)Writer参数说明

"writer": {

                    "name": "mysqlwriter",

                    "parameter": {

                        "username": "root",        #数据库用户名

                        "password": "000000",        #数据库密码

                        "connection": [

                            {

                                "table": [

                                    "test_province/2022-06-08"        #目标表

                                ],

                                "jdbcUrl": "jdbc:mysql://hadoop102:3306/gmall?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"

                            }

                        ],

                        "column": [        #目标列

                            "id",

                            "name",

                            "region_id",

                            "area_code",

                            "iso_code",

                            "iso_3166_2",

"create_time",

"operate_time"

                        ],

                        "writeMode": "replace"        #写入方式

                    }

                }

            }

//column:需要同步的列。可以使用索引选择所需列,例如:[{"index":0,"type":"数据类型"},{"index":1,"type":"数据类型"}]标识前两列;或者直接使用属性名选择,例如:["id","name"];         * 可以标识所有列。

写入方式:控制写入数据到目标表采用insert into(insert)或者replace into(replace) 或者 ON DUPLICATE KEY UPDATE(update)语句。

2. 提交任务

1)在MySQL的gmall数据库中创建test_province表

DROP TABLE IF EXISTS `test_province`;
CREATE TABLE `test_province`  (
  `id` bigint(20) NOT NULL,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `region_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `area_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `iso_code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `iso_3166_2` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `create_time` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `operate_time` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

2)进入DataX根目录

cd /opt/module/datax

3)开始同步

python bin/datax.py job/test_province.json

4)查看结果

查看MySQL目标表数据

;