本文是大数据系列第 23 篇,介绍 Sqoop 从 MySQL 按条件导入部分数据到 HDFS 的三种实用方式。

完整图文版(含截图):CSDN 原文 | 掘金

为什么需要部分导入

全量导入在初始化时很有用,但实际生产中往往只需要:

  • 特定列(减少传输量)
  • 满足条件的行(如价格大于某阈值的商品)
  • 多表 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 的双向操作。