本文是大数据系列第 22 篇,演示使用 Sqoop 将 MySQL 表数据全量导入 HDFS 的完整操作流程。
实验环境
三台 2C4G 公有云服务器(h121、h122、h123)组成 Hadoop 集群,其中 h122 承担 MySQL 服务。HDFS、YARN 和 Hive 服务均已就绪。
准备测试数据
在 MySQL 中创建测试表并批量插入数据:
CREATE DATABASE sqoop;
USE sqoop;
CREATE TABLE goodtbl (
gname VARCHAR(50),
serialNumber INT,
price INT,
stock_number INT,
create_time DATE
);
-- 使用存储过程批量插入 100 条测试记录
CALL batchInsertTestData(1, 100);
全量导入命令
sqoop import \
--connect jdbc:mysql://h122.wzk.icu:3306/sqoop \
--username hive \
--password hive@wzk.icu \
--table goodtbl \
--target-dir /user/hadoop/goodtbl \
--delete-target-dir \
--num-mappers 4 \
--fields-terminated-by "\t"
关键参数说明
| 参数 | 说明 |
|---|---|
--connect | JDBC 连接字符串 |
--username / --password | 数据库凭证 |
--table | 源表名 |
--target-dir | HDFS 目标目录 |
--delete-target-dir | 若目标目录已存在则先删除,避免冲突 |
--num-mappers | 并行 Mapper 数量(默认 4) |
--fields-terminated-by | 输出字段分隔符 |
MapReduce 并行机制
Sqoop 导入时自动生成 MapReduce Job,多个 Mapper 并行工作:
- 读取源表主键范围(min / max)
- 将范围均匀切分为 N 个区间(N =
--num-mappers) - 每个 Mapper 通过 JDBC 拉取对应区间的数据分片
- 各 Mapper 输出文件写入 HDFS 目标目录
例如主键 1-100、4 个 Mapper 时,分片为:1-25、26-50、51-75、76-100。
若表无主键或主键分布不均,可用 --split-by 指定分割列:
sqoop import \
--connect jdbc:mysql://h122.wzk.icu:3306/sqoop \
--username hive \
--password hive@wzk.icu \
--table goodtbl \
--target-dir /user/hadoop/goodtbl \
--split-by serialNumber \
--num-mappers 4 \
--fields-terminated-by "\t"
自定义查询导入
当需要多表 JOIN 或复杂过滤时,使用 --query 替代 --table:
sqoop import \
--connect jdbc:mysql://h122.wzk.icu:3306/sqoop \
--username hive \
--password hive@wzk.icu \
--query "SELECT gname, price, create_time FROM goodtbl WHERE \$CONDITIONS" \
--target-dir /user/hadoop/goodtbl_filtered \
--split-by serialNumber \
--num-mappers 2 \
--fields-terminated-by "\t"
注意:使用
--query时,WHERE 子句必须包含$CONDITIONS占位符(双引号中需转义为\$CONDITIONS),Sqoop 会自动替换为分片条件。
验证导入结果
# 查看 HDFS 上生成的文件
hdfs dfs -ls /user/hadoop/goodtbl
# 查看数据内容(前 5 行)
hdfs dfs -cat /user/hadoop/goodtbl/part-m-00000 | head -5
典型输出(制表符分隔):
商品A 1 88 100 2024-01-01
商品B 2 66 200 2024-01-02
常见问题
Q:导入报错 Target directory already exists
A:添加 --delete-target-dir 参数,或提前执行 hdfs dfs -rm -r /target/path。
Q:Mapper 数量设为 1 还是多个?
A:小表用 -m 1 避免不必要的并行开销;大表根据集群资源适当提高,通常 4-8 个 Mapper 效果较好。
Q:密码明文有安全风险怎么办?
A:可使用 --password-file 参数指定包含密码的 HDFS 文件,避免明文暴露在命令历史中。
下一篇介绍 Sqoop 部分导入:通过 --query、--columns、--where 三种方式实现条件过滤导入。