Sqoop基本使用
Sqoop基本使用
KNOWU前言
qoop 并不仅限于对接 MySQL,实际上它支持与多种关系型数据库管理系统(RDBMS)之间的数据交换。Sqoop 主要用于在 Hadoop 生态系统(如 HDFS、Hive、HBase 等)与关系型数据库之间进行大规模的数据导入和导出操作。
除了 MySQL,Sqoop 还可以与以下几种数据库进行对接:
1. PostgreSQL
- Sqoop 支持与 PostgreSQL 数据库进行数据导入导出。
2. Oracle
- Oracle 数据库也是 Sqoop 支持的数据源之一,可以与其进行高效的数据交换。
3. Microsoft SQL Server (MSSQL)
- 支持与 Microsoft SQL Server 进行集成,进行数据导入导出。
4. DB2 (IBM)
- IBM 的 DB2 数据库也可以与 Sqoop 集成,进行大规模的数据迁移。
5. Teradata
- Sqoop 支持与 Teradata 数据库进行数据导入导出。
6. Apache Derby
- Apache Derby 是一种轻量级的关系数据库,Sqoop 也支持与其进行交互。
7. Sybase
- Sqoop 同样支持 Sybase 数据库与 Hadoop 之间的数据迁移。
8. MariaDB
- 虽然 MariaDB 是 MySQL 的一个分支,Sqoop 对 MariaDB 的支持也是可以实现的,基本与 MySQL 的操作兼容。
9. Others
- Sqoop 也支持其他一些通过 JDBC 驱动程序可以连接的数据库,通常需要通过提供特定的 JDBC 驱动程序和相应的配置来实现。
主要功能:
- 数据导入:将关系型数据库中的数据导入到 Hadoop 生态系统(如 HDFS、Hive、HBase)中。
- 数据导出:将 Hadoop 中的数据导出到关系型数据库中。
一、Sqoop 基本命令
1. 查看所有命令
1 | sqoop help |
2. 查看某条命令的具体使用方法
1 | sqoop help 命令名 |
二、Sqoop 与 MySQL
1. 查询MySQL所有数据库
通常用于 Sqoop 与 MySQL 连通测试:
1 | sqoop list-databases \ |
2. 查询指定数据库中所有数据表
1 | sqoop list-tables \ |
三、Sqoop 与 HDFS
3.1 MySQL数据导入到HDFS
1. 导入命令
示例:导出 MySQL 数据库中的 help_keyword 表到 HDFS 的 /sqoop 目录下,如果导入目录存在则先删除再导入,使用 3 个 map tasks 并行导入。
注:help_keyword 是 MySQL 内置的一张字典表,之后的示例均使用这张表。
1 | sqoop import \ |
日志输出如下,可以看到输入数据被平均 split 为三份,分别由三个 map task 进行处理。数据默认以表的主键列作为拆分依据,如果你的表没有主键,有以下两种方案:
- 添加
-- autoreset-to-one-mapper参数,代表只启动一个map task,即不并行执行; - 若仍希望并行执行,则可以使用
--split-by <column-name>指明拆分数据的参考列。
2. 导入验证
1 | 查看导入后的目录 |
查看 HDFS 导入目录,可以看到表中数据被分为 3 部分进行存储,这是由指定的并行度决定的。
3.2 HDFS数据导出到MySQL
1 | sqoop export \ |
表必须预先创建,建表语句如下:
1 | CREATE TABLE help_keyword_from_hdfs LIKE help_keyword ; |
四、Sqoop 与 Hive
4.1 MySQL数据导入到Hive
Sqoop 导入数据到 Hive 是通过先将数据导入到 HDFS 上的临时目录,然后再将数据从 HDFS 上 Load 到 Hive 中,最后将临时目录删除。可以使用 target-dir 来指定临时目录。
1. 导入命令
1 | sqoop import \ |
导入到 Hive 中的 sqoop_test 数据库需要预先创建,不指定则默认使用 Hive 中的 default 库。
1 | 查看 hive 中的所有数据库 |
2. 导入验证
1 | 查看 sqoop_test 数据库的所有表 |
3. 可能出现的问题
如果执行报错 java.io.IOException: java.lang.ClassNotFoundException: org.apache.hadoop.hive.conf.HiveConf,则需将 Hive 安装目录下 lib 下的 hive-exec-**.jar 放到 sqoop 的 lib 。
1 | [root@hadoop001 lib]# ll hive-exec-* |
4.2 Hive 导出数据到MySQL
由于 Hive 的数据是存储在 HDFS 上的,所以 Hive 导入数据到 MySQL,实际上就是 HDFS 导入数据到 MySQL。
1. 查看Hive表在HDFS的存储位置
1 | 进入对应的数据库 |
Location 属性为其存储位置:
这里可以查看一下这个目录,文件结构如下:
3.2 执行导出命令
1 | sqoop export \ |
MySQL 中的表需要预先创建:
1 | CREATE TABLE help_keyword_from_hive LIKE help_keyword ; |
五、Sqoop 与 HBase
本小节只讲解从 RDBMS 导入数据到 HBase,因为暂时没有命令能够从 HBase 直接导出数据到 RDBMS。
5.1 MySQL导入数据到HBase
1. 导入数据
将 help_keyword 表中数据导入到 HBase 上的 help_keyword_hbase 表中,使用原表的主键 help_keyword_id 作为 RowKey,原表的所有列都会在 keywordInfo 列族下,目前只支持全部导入到一个列族下,不支持分别指定列族。
1 | sqoop import \ |
导入的 HBase 表需要预先创建:
1 | 查看所有表 |
2. 导入验证
使用 scan 查看表数据:
六、全库导出
Sqoop 支持通过 import-all-tables 命令进行全库导出到 HDFS/Hive,但需要注意有以下两个限制:
- 所有表必须有主键;或者使用
--autoreset-to-one-mapper,代表只启动一个map task; - 你不能使用非默认的分割列,也不能通过 WHERE 子句添加任何限制。
第二点解释得比较拗口,这里列出官方原本的说明:
- You must not intend to use non-default splitting column, nor impose any conditions via a
WHEREclause.
全库导出到 HDFS:
1 | sqoop import-all-tables \ |
全库导出到 Hive:
1 | sqoop import-all-tables -Dorg.apache.sqoop.splitter.allow_text_splitter=true \ |
七、Sqoop 数据过滤
7.1 query参数
Sqoop 支持使用 query 参数定义查询 SQL,从而可以导出任何想要的结果集。sqoop暂不支持export +query使用示例如下:
1 | sqoop import \ |
在使用 query 进行数据过滤时,需要注意以下三点:
- 必须用
--hive-table指明目标表; - 如果并行度
-m不为 1 或者没有指定--autoreset-to-one-mapper,则需要用--split-by指明参考列; - SQL 的
where字句必须包含$CONDITIONS,这是固定写法,作用是动态替换。
7.2 增量导入
1 | sqoop import \ |
incremental 参数有以下两个可选的选项:
- append:要求参考列的值必须是递增的,所有大于
last-value的值都会被导入; - lastmodified:要求参考列的值必须是
timestamp类型,且插入数据时候要在参考列插入当前时间戳,更新数据时也要更新参考列的时间戳,所有时间晚于last-value的数据都会被导入。
通过上面的解释我们可以看出来,其实 Sqoop 的增量导入并没有太多神器的地方,就是依靠维护的参考列来判断哪些是增量数据。当然我们也可以使用上面介绍的 query 参数来进行手动的增量导入,这样反而更加灵活。
八、类型支持
Sqoop 默认支持数据库的大多数字段类型,但是某些特殊类型是不支持的。遇到不支持的类型,程序会抛出异常 Hive does not support the SQL type for column xxx 异常,此时可以通过下面两个参数进行强制类型转换:
- –map-column-java<mapping> :重写 SQL 到 Java 类型的映射;
- –map-column-hive <mapping> : 重写 Hive 到 Java 类型的映射。
示例如下,将原先 id 字段强制转为 String 类型,value 字段强制转为 Integer 类型:
1 | $ sqoop import ... --map-column-java id=String,value=Integer |
导入和导出的目标表不能有数据。

