本文是大数据系列第 23 篇,介绍 Sqoop 从 MySQL 按条件导入部分数据到 HDFS 的三种实用方式。
为什么需要部分导入
全量导入在初始化时很有用,但实际生产中往往只需要:
- 特定列(减少传输量)
- 满足条件的行(如价格大于某阈值的商品)
- 多表 JOIN 后的结果集
Sqoop 提供三种方式实现部分导入。
方式一:—query 自定义查询
适合需要多表 JOIN 或复杂 SQL 过滤的场景:
sqoop import \
--connect jdbc:mysql://h122.wzk.icu:3306/sqoop \
--username hive \
--password hive@wzk.icu \
--target-dir /root/sqoop_query \
--append \
-m 1 \
--fields-terminated-by "\t" \
--query 'select gname, serialNumber, price, stock_number, create_time
from goodtbl where price > 88 and $CONDITIONS;'
核心注意事项:
- WHERE 子句必须包含
$CONDITIONS占位符,Sqoop 用它注入分片条件 - 使用单引号时
$CONDITIONS无需转义;使用双引号时需写成\$CONDITIONS --append表示向已存在目录追加数据,而非覆盖
方式二:—columns 指定列
只需要导入表的部分列时,最简洁的方式:
sqoop import \
--connect jdbc:mysql://h122.wzk.icu:3306/sqoop \
--username hive \
--password hive@wzk.icu \
--target-dir /root/sqoop_columns \
--delete-target-dir \
--num-mappers 1 \
--fields-terminated-by "\t" \
--columns gname,serialNumber,price \
--table goodtbl
注意: 多列之间用逗号分隔,不能有空格,否则解析失败。
方式三:—where 条件过滤
使用标准 SQL WHERE 语法,结合 --table 使用,写法最直观:
sqoop import \
--connect jdbc:mysql://h122.wzk.icu:3306/sqoop \
--username hive \
--password hive@wzk.icu \
--target-dir /root/sqoop_where \
--delete-target-dir \
-m 1 \
--fields-terminated-by "\t" \
--table goodtbl \
--where "price >= 68"
三种方式对比
| 方式 | 适用场景 | 支持多表 JOIN | 列过滤 | 行过滤 |
|---|---|---|---|---|
--query | 复杂 SQL,多表关联 | 是 | 是 | 是 |
--columns | 只需部分列 | 否 | 是 | 否 |
--where | 简单行过滤 | 否 | 否 | 是 |
--columns与--where可以组合使用,但不能与--query同时使用。
—append 与 —delete-target-dir 的选择
| 参数 | 行为 | 适用场景 |
|---|---|---|
--append | 向已存在目录追加文件 | 增量场景,不覆盖历史数据 |
--delete-target-dir | 先删除目标目录再写入 | 全量覆盖,保证幂等性 |
| 不加任何参数 | 目录存在则报错退出 | 防误操作的默认保护 |
验证结果
# 查看 HDFS 文件
hdfs dfs -ls /root/
# 检查数据内容
hdfs dfs -cat /root/sqoop_query/part-m-00000
导入成功后可在 YARN Web UI(http://h121.wzk.icu:8088)中查看 MapReduce Job 的执行详情,确认 Mapper 任务分配与耗时。
下一篇介绍 Sqoop 将 MySQL 数据直接导入 Hive 表,以及从 Hive 导出数据回 MySQL 的双向操作。