转载请注明出处:http://www.cnblogs.com/xiaodf/
1 Sqoop概述
Sqoop是一个旨在Hadoop和关系数据库或主机之间传输数据的工具。你可以使用Sqoop从关系型数据库管理系统(RDBMS),如MySQL、Oracle或大型机到Hadoop分布式文件系统(HDFS)导入数据,在Hadoop中的MapReduce转换数据,然后将数据导出到一个RDBMS 。Sqoop使用MapReduce导入和导出数据,它提供了并行操作,以及容错。
2 版本说明
本文档适用于Sqoop1。
软件 | 版本 |
---|---|
Sqoop | 1.4.5-cdh5.3.0 |
Mysql JDBC驱动 | 5.1.32 |
ORACLE JDBC驱动 | 和oracle版本保持一致 |
3 驱动安装
3.1 MySQL
将驱动对应的jar包放置到 /usr/share/java/下。
如:/usr/share/java/mysql-connector-java-5.1.32-bin.jar
4 基本用法
4.1 导入
sqoop import
--connect JDBC_URL
--username USERNAME
--password PASSWORD
--table TABLE
--hive-import
--split-by SPLIT_BY_COL
--num-mappers N
--hive-database HIVE_DB_NAME
--hive-table HIVE_TABLE_NAME
(--hive-partition-key partition_name
--hive-partition-value partititon_value
附:如果是分区表则需指出分区名称和分区值)
--columns col1,clo2,col3…
--warehouse-dir /user/hive/warehouse/
--fields-terminated-by ‘|’
--direct
--compress
参数说明
参数 | 说明 |
---|---|
--connect | 连接RDBMS的jdbc连接字符串。 示例:--connect jdbc:mysql:// MYSQL_SERVER: PORT / DBNAME 其中:mysql默认端口号为3306; 示例:--connect jdbc:oracle:thin:USERNAME/PASSWORD@ORACLE_SERVER:PORT: SID 其中:Oracle默认端口号为1521; thin:是驱动方式,“瘦”的意思,直接使用原生的Oracle JDBC驱动; SID:是一个数据库的唯一标识符,是建立一个数据库时系统自动赋予的一个初始ID。 |
--username | 连接RDBMS所使用的用户名。 |
--password | 连接RDBMS所使用的密码。 |
--table | 将要导入到hive的表。 |
--split-by | 分割导入任务所使用的字段。需要明确指定,推荐使用主键。 |
--hive-import | 插入数据到hive当中,使用hive默认的分隔符。 |
-m, --num-mappers< n> | 使用n个map任务并行导入数据。是指生成的map任务的总数量, 不是同时处于RUNNING状态的数量。 |
--hive-database | hive当中的数据库。 |
-- hive-table | hive当中的表名 |
--hive-partition-key | hive分区的列名 。 |
--hive-partition-value | hive分区的值。 |
--columns < col,col,col…> | 从表中导出指定的一组列的数据,用逗号分隔, oracle中列名需要大写。 |
--warehouse-dir | (必选)可以指定为-warehouse-dir/user/hive/warehouse/ 即导入数据的存放路径,如果该路径不存在,会首先创建。 在该路径下会生成和TABLE(--table)同名的文件夹,该文件夹下存放数据文件。 如果路径存在,需要保证该文件夹下不存在与TABLE(--table)同名文件。 如果不手动指定,默认是启动sqoop任务的用户的home目录。 |
--direct | 使用快速模式导入 |
--compress | 启用压缩,生成的文件为经过压缩的文件。 默认使用GZIP算法。 通过--compression-codec设置压缩算法。 通常当空间不够时可以使用压缩,不过需要注意,如果压缩率过大可能导致CPU占用过高。 如果可以,推荐使用snappy。 另外,如果配置了mapreduce的“map输出压缩”, 那么即使不适用—compress开关, 导入的数据文件也会使用对应的codec进行压缩。 |
--compression-codec | 使用Hadoop Codec。(默认gzip)前提是设置了—cpmpress。 |
其他 | 可使用 sqoop import 命令查看帮助。 |
附:对于--warehouse-dir需要指定为/user/hive/warehouse/但在该路径下不能存在与TABLE(--table)同名的文件,否则导入失败。当导入成功时,会在该路径下生成数据文件part-m-XXXXX并且生成与TABLE(--table)同名文件,存放导入成功的标志文件_SUCCESS。
4.1.1 保护密码
在sqoop命令中显式指定密码会是很不安全的操作,使用操作系统的列出正在执行的命令的方式可以很容易的获取到密码。有两种方式可以解决这个问题。
方式一:使用-P(大写)参数,在执行命令时再输入密码。
方式二:使用--password-file参数,即将密码存放在参数指定的文件中。
4.1.2 使用其他文件格式
Sqoop支持3中不同的文件格式,其中一种是文本格式,两外两种是二进制格式。二进制格式分别是Avro和SequenceFile。使用--as-avrodatafile或--as-sequencefile以指定具体使用哪种二进制格式。
4.1.3 压缩导入的数据
使用—compress或-z参数以压缩导入之后的数据。默认的压缩算法为GZip,所有文件的后缀名均为.gz。可以使用—compress-codec来指定其他的codec。如
--compression-codec org.apache.hadoop.io.compress.BZip2Codec
使用压缩需要将mapreduce中对应的设置项开启,如mapreduce.output.
compress。
4.1.4 提高传输速度
不同于JDBC接口,direct模式下使用数据库提供的本地工具进行数据传输。在MySQL中使用mysqldump和mysqlimport。对于PostgreSQL,sqoop会使用pg_dump工具来导入数据。使用本地工具会极大提高性能,因为他们针对数据传输做了优化,以降低数据库服务器的负担。当然也有很多限制,比如并不是所有的数据库都提供本地工具。目前sqoop的direct模式只支持MySQL和PostgreSQL。
4.1.5 自定义类型映射
使用—amp-column-java参数来将列列映射到java类以覆盖sqoop提供的默认的映射关系。
如要将c1、c2、c3分别映射为Float、String、String,对应的设置如下所示。
sqoop import --map-column-java c1=Float,c2=String,c3=String ...
4.1.6 并行控制
Sqoop默认使用4个并发的map任务来项hadoop传输数据。当数据量比较大时可以考虑增加并发执行的map任务的数量以提高传输速度。使用参数—num-mappers来控制map任务的数量。
4.1.7 对NULL值进行编码
Sqoop使用“null”字符串来代替数据库中的NULL值。对于文本类型的列,使用—null-string来设置替代NULL值得字符串,对于其他类型的列,则使用—null-non-string来设置。
如果想使用N来编码NULL值,则对应sqoop命令中的值为N, 在JAVA中是转义字符。
--null-string '\N'
--null-non-string '\N'
4.1.8 导入所有表
使用如下命令导入所有表。sqoop会一次导入每张表,以避免对数据库服务器造成额外的负担。
sqoop import-all-tables
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
4.2 增量导入
增量导入是每次只导入新增加的或者需要更新的数据。增量导入会大大降低数据库服务器的负担。
4.2.1 只导入细腻数据
假设我们有INTEGER类型的主键,并且只追加新列,并且需要定期将表的状态同步到Hadoop中。我们需要使用增量导入的功能。典型代码如下所示。
sqoop import
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table visits
--incremental append
--check-column id
--last-value 1
--incremental参数表示使用增量导入,参数值为使用的增量导入的类型。,由于我们只添加而不修改列的值,所以使用append。增量导入中还需要额外的两个参数:--check-column指定一个列,用于检查新增加的数据,--last-value包含上次成功导入到Hadoop的值。
4.2.2 增量导入可变数据
使用lastmodified模式而不是append模式来导入变化的数据。例如使用如下命令导入所last_update_date列大于“2013-05-22 01:01:01”的行。
sqoop import
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table visits
--incremental lastmodified
--check-column last_update_date
--last-value "2013-05-22 01:01:01"
增量导入模式lastmodified需要一个日期(可选的类型有date、time、datetime和timestamp)列来保存列被修改的时间。
注:--last-value的值在增量导入时是包含在需要导入的范围之内的。
Sqoop不会检查数据是否重复,即不会按照MySQL中那样更新数据。
4.2.3 保存last-value
Sqoop导入任务完成后会给出新的last-value,我们可以保存当前下来,以便下次使用。
Sqoop的metastore会保存任务的信息,所以我们创建对应的任务即可。
sqoop job
--create visits
--
import
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table visits
--incremental append
--check-column id
--last-value 0
执行任务
sqoop job --exec visits
删除任务
sqoop job --delete visits
查看任务信息,信息中会包含last-value的当前值。
sqoop job --show visits
4.2.4 在metastore中保存密码
很不幸,每次使用sqoop job执行任务都需要手动输入密码。
解决方式有两种:
第一种方式,使用password-file(“导入”一章中有介绍);
第二种方式,在sqoop-site.xml中添加如下属性即可(添加后第一次仍然需要输入密码 )。
<property>
<name>sqoop.metastore.client.record.password</name>
<value>true</value>
</property>
4.2.5 客户端之间共享metastore
启动metastore服务
sqoop metastore
客户端连接到metastore服务
sqoop job
--create visits
--meta-connect
jdbc:hsqldb:hsql://metastore.example.com:16000/sqoop
--
import
--table visits
...
显示任务
sqoop job --list --meta-connect jdbc:hsqldb:hsql://metastore.example.com:16000/sqoop
4.3 导出
4.3.1 hive导出数据到mysql
sqoop export
--connect jdbc:mysql://MYSQL_SERVER:PORT/DBNAME
--username USERNAME
--table TABLE
--export-dir /user/hive/warehouse/HIVE_TABLE_NAME/
--num-mappers N
--fields-terminated-by ','
附:对于hive中有null时,导入到MySQL中依然是NULL。
4.3.2 批量插入
sqoop使用独立的insert语句来添加每一行记录,使用如下的方式可以每次插入多条记录。即批量插入,每次插入10条。
sqoop export
-Dsqoop.export.records.per.statement=10
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table cities
--export-dir cities
--batch
4.3.3 导出所有数据或不导出任何数据
我们需要确保或者所有数据均导出成功,或者不导出任何数据。为此我们使用临时表,即先将数据导出到临时表(staging-table)中,然后再转移到目标表中。
sqoop export
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table cities
--staging-table staging_cities
4.3.4 更新已有数据
使用—update-key参数指定一列,该列可以识别出被修改的行,通常是表中的主键。例如下面的示例中使用列id来更新cities表。
sqoop export
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table cities
--update-key id
可以指定多个列,列之间用逗号隔开。
注意,该操作只会更新已有的数据,不会插入新的数据,
4.3.5 更新或插入数据
使用如下的参数可以同时插入新数据或更新已有数据。
sqoop export
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table cities
--update-key id
--update-mode allowinsert
4.3.6 只导出某些列
Sqoop默认hdfs中的数据和数据库中有相同数量的列并且顺序相同,使用—columns参数可以指定需要导出到数据库中的列或者指定导出列之间的顺序。如只导出coutry和city列,就可以使用如下示例。
sqoop export
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table cities
--columns country,city
4.3.7 编码NULL值
你可以使用—input-null-string和—input-null-no-string参数来覆盖NULL值的替换字符串,例如使用‘N’替换NULL值。
sqoop export
--connect jdbc:mysql://mysql.example.com/sqoop
--username sqoop
--password sqoop
--table cities
--input-null-string '\N'
--input-null-non-string '\N'
5 附:import和export参数详解
5.1 import和export工具通用选项
选项 | 说明 |
---|---|
--connect < jdbc-uri > | 指定JDBC连接字符串 |
--connection-manager < class-name > | 指定要使用的连接管理器类 |
--driver < class-name > | 指定要使用的JDBC驱动类 |
--hadoop-mapred-home < dir > | 指定$HADOOP_MAPRED_HOME路径 |
--help | 打印用法帮助信息 |
--password-file | 设置用于存放认证的密码信息文件的路径 |
-P | 从控制台读取输入的密码 |
--password < password > | 设置认证密码 |
--username < username > | 设置认证用户名 |
--verbose | 打印详细的运行信息 |
--connection-param-file < filename > | 可选,指定存储数据库连接参数的属性文件 |
5.2 数据导入工具import参数详解
import工具,是将HDFS平台外部的结构化存储系统中的数据导入到Hadoop平台,便于后续分析。我们先看一下import工具的基本选项及其含义,如下表所示:
选项 | 说明 |
---|---|
--append | 将数据追加到HDFS上一个已存在的数据集上 |
--as-avrodatafile | 将数据导入到Avro数据文件 |
--as-sequencefile | 将数据导入到SequenceFile |
--as-textfile | 将数据导入到普通文本文件(默认) |
--boundary-query < statement > | 边界查询,用于创建分片(InputSplit) |
--columns < col,col,col…> | 从表中导出指定的一组列的数据 |
--delete-target-dir | 如果指定目录存在,则先删除掉 |
--direct | 使用直接导入模式(优化导入速度) |
--direct-split-size < n > | 分割输入stream的字节大小(在直接导入模式下) |
--fetch-size < n > | 从数据库中批量读取记录数 |
--inline-lob-limit < n > | 设置内联的LOB对象的大小 |
-m,--num-mappers < n > | 使用n个map任务并行导入数据 |
-e,--query < statement > | 导入的查询语句 |
--split-by < column-name > | 指定按照哪个列去分割数据 |
--table < table-name > | 导入的源表表名 |
--target-dir < dir > | 导入HDFS的目标路径 |
--warehouse-dir < dir > | HDFS存放表的根路径 |
--where < where clause> | 指定导出时所使用的查询条件 |
-z,--compress | 启用压缩 |
--compression-codec < c > | 指定Hadoop的codec方式(默认gzip) |
--null-string < null-string > | 如果指定列为字符串类型,使用指定字符串替换值为null的该类列的值 |
--null-non-string < null-string > | 如果指定列为非字符串类型,使用指定字符串替换值为null的该类列的值 |
hive参数
选项 | 说明 |
---|---|
--hive-home < dir > | Override $HIVE_HOME |
--hive-import | 插入数据到hive当中,使用hive的默认分隔符 |
--hive-overwrite | 覆盖hive表中的数据 |
--create-hive-table | 建表,如果表已经存在,该操作会报错 |
--hive-table < table-name > | 设置到hive当中的表名 |
--hive-drop-import-delims | 导入到hive时删除 , , and 1 |
--hive-delims-replacement | 导入到hive时用自定义的字符替换掉 , , and 1 |
--hive-partition-key | hive分区的key |
--hive-partition-value < v > | hive分区的值 |
--map-column-hive < map > | 类型匹配,sql类型对应到hive类型 |
HBase参数
选项 | 说明 |
---|---|
--column-family < family > | 把内容导入到hbase当中,默认是用主键作为split列 |
--hbase-create-table | 创建Hbase表 |
--hbase-row-key < col > | 指定字段作为row key ,如果输入表包含复合主键,用逗号分隔 |
--hbase-table < table-name > | 指定hbase表 |
5.3 数据导出工具export参数详解
export工具,是将HDFS平台的数据,导出到外部的结构化存储系统中,可能会为一些应用系统提供数据支持。我们看一下export工具的基本选项及其含义,如下表所示:
选项 | 说明 |
---|---|
--validate < class-name > | 启用数据副本验证功能,仅支持单表拷贝,可以指定验证使用的实现类 |
--validation-threshold < class-name > | 指定验证门限所使用的类表 |
--direct | 使用直接导出模式(优化速度) |
--export-dir < dir > | 导出过程中HDFS源路径 |
-m,--num-mappers < n > | 使用n个map任务并行导出 |
--table < table-name > | 导出的目的表名称 |
--call < stored-proc-name > | 导出数据调用的指定存储过程名 |
--update-key col-name > | 更新参考的列名称,多个列名使用逗号分隔 |
--update-mode < mode > | 指定更新策略,包括:updateonly(默认)、allowinsert |
--input-null-string < null-string > | 使用指定字符串,替换字符串类型值为null的列 |
--input-null-non-string < null-string > | 使用指定字符串,替换非字符串类型值为null的列 |
--staging-table < staging-table-name> | 在数据导出到数据库之前,数据临时存放的表名称 |
--clear-staging-table | 清除工作区中临时存放的数据 |
--batch | 使用批量模式导出 |
5.4 Sqoop Job参数详解
选项 | 说明 |
---|---|
--create < job-id > | 定义sqoop job |
--delete < job-id> | 删除sqoop job |
--exec < job-id> | 执行sqoop job |
--show < job-id> | 查看sqoop job状态 |
--list | 查看所有sqoop job |