MySQLReader是DataX生态中用于从MySQL数据库抽取数据的核心插件。作为DataX框架的Reader组件,它通过JDBC协议与MySQL数据库建立连接,执行用户配置的查询语句,并将结果集转换为DataX内部数据格式传递给下游Writer。
在实际生产环境中,MySQLReader常被用于以下场景:
提示:MySQLReader仅支持数据抽取,不包含DDL同步功能。如需同步表结构,需要额外处理。
MySQLReader采用经典的JDBC访问模式,其核心工作流程可分为四个阶段:
连接初始化阶段:
SQL生成阶段:
数据抽取阶段:
资源释放阶段:
当配置了splitPk参数时,MySQLReader会启动并发数据抽取,其分片算法如下:
首先执行查询获取splitPk列的最小值和最大值:
sql复制SELECT MIN(splitPk), MAX(splitPk) FROM table [WHERE ...]
根据配置的channel数计算每个分片的范围:
code复制分片大小 = (MAX - MIN) / channel
为每个分片生成WHERE条件:
sql复制WHERE ... AND splitPk >= start AND splitPk < end
注意事项:分片字段必须是整型且数据分布均匀。如果数据倾斜严重,会导致某些分片任务执行时间远长于其他分片。
MySQLReader在读取数据时会进行类型转换,其转换规则如下表所示:
| MySQL类型 | DataX内部类型 | 说明 |
|---|---|---|
| TINYINT,SMALLINT,INT等 | Long | 所有整数类型统一转换为Long |
| FLOAT,DOUBLE,DECIMAL | Double | 浮点类型转换为Double |
| CHAR,VARCHAR,TEXT系列 | String | 字符串类型保持原样 |
| DATE,DATETIME,TIMESTAMP | Date | 日期时间类型转换为DataX的Date类型 |
| BIT | Boolean | BIT(1)转换为Boolean,其他长度的BIT转换为Bytes |
| BLOB,BINARY系列 | Bytes | 二进制类型转换为字节数组 |
特殊处理:
以下是一个完整的MySQLReader配置示例,包含所有必填参数:
json复制{
"reader": {
"name": "mysqlreader",
"parameter": {
"username": "datax_user",
"password": "secure_password",
"column": ["id", "name", "age", "create_time"],
"connection": [
{
"table": ["user"],
"jdbcUrl": ["jdbc:mysql://mysql-prod:3306/prod_db?useSSL=false"]
}
]
}
}
}
启用分片读取的配置示例:
json复制{
"splitPk": "id",
"channel": 4
}
最佳实践:
增量同步配置示例:
json复制{
"where": "create_time >= '2023-01-01' AND status = 1"
}
复杂查询配置示例:
json复制{
"querySql": [
"SELECT u.id, u.name, d.department_name " +
"FROM user u JOIN department d ON u.dept_id = d.id " +
"WHERE u.status = 1"
]
}
可在jdbcUrl中添加以下参数提升性能:
code复制jdbc:mysql://host:3306/db?
useCursorFetch=true&
defaultFetchSize=1000&
useCompression=true&
rewriteBatchedStatements=true
通过jvm参数调整连接池:
code复制-Ddatax.jdbc.driver.max.active=10
-Ddatax.jdbc.driver.max.idle=5
code复制ERROR: Communications link failure
解决方案:
code复制java.lang.OutOfMemoryError: Java heap space
解决方案:
code复制Duplicate entry '123' for key 'PRIMARY'
解决方案:
对于TB级数据迁移建议采用以下策略:
按时间范围分批迁移
json复制{
"where": "create_time BETWEEN '2023-01-01' AND '2023-01-31'"
}
多维度分片
启用压缩传输
code复制jdbc:mysql://host:3306/db?useCompression=true
json复制{
"where": "update_time >= '${last_sync_time}'"
}
json复制{
"where": "id > ${last_max_id}"
}
结合Canal等工具实现准实时同步:
对于分库分表场景,可采用以下配置模式:
json复制{
"connection": [
{
"table": ["user_00", "user_01"],
"jdbcUrl": [
"jdbc:mysql://shard1:3306/db",
"jdbc:mysql://shard2:3306/db"
]
}
]
}
| 指标类别 | 具体指标 | 健康阈值 |
|---|---|---|
| 资源使用 | CPU使用率 | <70% |
| 内存使用量 | <80% of Xmx | |
| 网络 | 网络吞吐量 | <80% of 带宽 |
| MySQL | 慢查询数量 | 0 |
| 连接数 | < max_connections*0.8 | |
| DataX | 记录读取速度 | 根据硬件调整 |
| 通道活跃数 | =配置channel数 |
| 参数 | 默认值 | 建议范围 | 说明 |
|---|---|---|---|
| channel | 1 | 2-16 | 根据CPU核心数和MySQL性能调整 |
| fetchSize | 1000 | 1000-5000 | 过大可能导致OOM |
| batchSize | 1024 | 512-2048 | 每次写入的记录数 |
| connectionTimeout | 30s | 30s-120s | 网络不稳定时增加 |
| socketTimeout | 30s | 30s-300s | 大数据量查询时增加 |
敏感信息保护
SQL注入防护
网络传输安全
code复制jdbc:mysql://host:3306/db?useSSL=true&requireSSL=true
资源隔离
MySQLReader对不同版本MySQL的支持情况:
| MySQL版本 | 支持情况 | 注意事项 |
|---|---|---|
| 5.6 | 完全支持 | 建议使用5.6.5+ |
| 5.7 | 完全支持 | 推荐版本 |
| 8.0 | 支持 | 需要JDBC驱动8.0+ |
| MariaDB | 部分支持 | 可能遇到兼容性问题 |
JDBC驱动推荐版本:
当MySQLReader不能满足需求时,可考虑以下替代方案:
| 工具 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| Canal | 实时同步 | 部署复杂 | 需要实时同步的场景 |
| Flink CDC | 流式处理 | 资源消耗大 | 实时ETL |
| Sqoop | Hadoop生态集成 | 功能单一 | Hadoop数据导入 |
| Kettle | 图形化界面 | 性能较差 | 小型数据迁移 |
在实际使用MySQLReader过程中,我们总结了以下宝贵经验:
批量提交优化
连接池调优
bash复制-Ddatax.jdbc.driver.max.active=20
-Ddatax.jdbc.driver.max.wait=60000
内存管理技巧
code复制-Xmn1024m
异常处理策略
数据一致性保障
在实际项目中,我曾遇到一个典型案例:某次迁移200GB数据时,最初配置的channel=4但未设置splitPk,导致实际只有单线程工作。通过添加splitPk配置并将channel调整为8,性能提升了6倍。这个案例告诉我们,合理配置分片参数对性能至关重要。