Sqoop基本使用
本文于2072天之前发表,文中内容可能已经过时。
一、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,从而可以导出任何想要的结果集。使用示例如下:
| 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 |