【Sqoop】Sqoop 工具之 Sqoop-import

全文内容来自:Sqoop工具模块之sqoop-import

一、常用命令列举

序号 命令 说明
1 import ImportTool 将数据导入到集群
2 export ExportTool 将集群数据导出
3 codegen CodeGenTool 获取数据库中某张表数据生成Java并打包Jar
4 create-hive-table CreateHiveTableTool 创建 Hive 表
5 eval EvalSqlTool 查看 SQL 执行结果
6 import-all-tables ImportAllTablesTool 导入某个数据库下所有表到 HDFS 中
7 list-databases ListDatabasesTool 列出所有数据库名
8 list-tables ListTablesTool 列出某个数据库下所有表
9 help HelpTool 打印 sqoop 帮助信息
10 version VersionTool 打印 sqoop 版本信息

主要记录 import 命令。

二、import 参数

2.1、连接参数

--connect :指定JDBC连接字符串。
--connection-manager :指定要使用的连接管理器类。
--driver :手动指定要使用的JDBC驱动程序类。
--hadoop-mapred-home :覆盖$ HADOOP_MAPRED_HOME
--help:打印使用说明。
--password-file:为包含认证密码的文件设置路径。
-P:从控制台读取密码。
--password :设置验证密码。
--username :设置验证用户名。
--verbose:在控制台打印更多信息。
--connection-param-file :提供连接参数的可选属性文件。
--relaxed-isolation:将连接事务隔离设置为对映射器未提交的读取。

2.2、 安全验证参数

--validate:启用对复制数据的验证,仅支持单个表复制。
--validator :指定要使用的验证程序类。
--validation-threshold :指定要使用的验证阈值类。
--validation-failurehandler :指定要使用的验证失败处理程序类。

2.3、导入控制参数

以下是 Sqoop 在导入数据时,可选的控制导入数据内容的参数:

--append:将数据追加到HDFS中的现有数据集。
--as-avrodatafile:将数据导入Avro数据文件。
--as-sequencefile:将数据导入到SequenceFiles。
--as-textfile:以纯文本形式导入数据(Sqoop导入的默认方式)。
--as-parquetfile:将数据导入Parquet文件。
--boundary-query :边界查询用于创建分割。
--columns :从表中选择要导入列。
--delete-target-dir:删除导入目标目录(如果存在)。
--direct:如果数据库存在,则使用直接连接器。
--fetch-size :一次从数据库读取的条目数。
--inline-lob-limit :设置内联LOB的最大大小。
-m,--num-mappers :使用n个map任务执行导入。
-e,--query :导入结果statement。
--split-by :用于分割表单元的表格列。不能与--autoreset-to-one-mapper选项一起使用 。
--split-limit :每个拆分大小的上限。这仅适用于整数和日期列。对于日期或时间戳字段,它以秒计算。
--autoreset-to-one-mapper:如果表中没有主键并且没有提供分割列,导入应该使用一个mapper。不能与--split-by 选项一起使用。
--table :导入的表名。
--target-dir :目标HDFS目录。
--temporary-rootdir :导入期间创建的临时文件的HDFS目录(覆盖默认的“_sqoop”)。
--warehouse-dir :表目的地的HDFS父级目录。
--where :在导入过程中使用WHERE子句。
-z,--compress:启用压缩。
--compression-codec :使用Hadoop编解码器(默认gzip)。
--null-string :要为字符串列写入空值的字符串。
--null-non-string :要为非字符串列写入空值的字符串。
--null-string和--null-non-string参数都是可选的。如果未指定,那么字符串“null”将被使用。

2.4、Hive参数

以下是导入到 Hive 中时可选的参数:

--hive-home :覆盖 $HIVE_HOME。
--hive-import:将表导入Hive(如果没有设置,则使用Hive的默认分隔符。)
--hive-overwrite:覆盖Hive表中的现有数据。
--create-hive-table:如果设置,那么如果存在目标hivetable,作业将失败。默认情况下,此属性为false。
--hive-table :设置导入到Hive时要使用的表名。
--hive-drop-import-delims:导入到Hive时,从字符串字段中删除\n、\r和\01。
--hive-delims-replacement:在导入到Hive时,将字符串字段中的\n、\r和\01替换为用户定义的字符串。
--hive-partition-key:分配到分区的Hive字段的名称。
--hive-partition-value :作为该任务导入到Hive中的分区键的字符串值。
--map-column-hive :覆盖从SQL类型到配置列的Hive类型的默认映射。如果在此参数中指定逗号,请使用URL编码的键和值,例如,使用DECIMAL(1%2C%201)而不是DECIMAL(1,1)。

三、文件格式

Sqoop 提供了两种文件格式用于存储导入的数据,分别是:分隔文本和 SequenceFiles。

3.1、分割文本

分隔文本是默认的导入数据存储格式。也可以使用 --as-textfile 参数显式指定。该方式将每个基于字符串的表示形式的记录写入分割文件中,在各个行和列之间使用分隔符进行行列的划分。分隔符可以是逗号、制表符或其他字符。

以下是基于分割文本导入数据的示例:

1,这里是一条消息,2010-05-01
2,新年快乐!,2010-01-01
3,另一个消息,2009-11-12

分隔文本适用于大多数非二进制数据类型。它也支持其他工具的进一步操作,例如 Hive。

3.2、SequenceFiles

SequenceFiles 是一种二进制格式,它将单个记录存储在自定义的特定的数据类型记录中。这些数据类型表现为 Java 类。Sqoop 会自动生成这些数据类型。这种格式支持二进制表示中所有数据的准确存储,适用于存储二进制数据(例如,VARBINARY列)或将主要由自定义 MapReduce 程序操作的数据。从SequenceFiles 读取性能高于从文本文件读取数据,因为记录不需要被解析。

Avro 数据文件是一种紧凑且高效的二进制格式,可与使用其他编程语言编写的应用程序进行交互操作。Avro 还支持版本控制,以便在添加或删除列时,将以前导入的数据文件和新文件一起处理。

3.3、压缩

默认情况下,导入的数据未被压缩。可以使用 -z 或 --compress 参数的deflate(gzip)算法来压缩数据,或使用 --compression-codec 参数指定 Hadoop 压缩编解码器。压缩可以用于 SequenceFile,文本和 Avro 文件。

四、参数详解

4.1、用户名密码

--username 参数用来提供数据库的用户名。

Sqoop 提供了几种不同的提交密码的方法,下面详细描述数据库提供安全和不安全的密码提交方式。

安全提交密码的方式

将密码保存在具有 400 权限的用户主目录中的文件中,并使用 --password-file 参数指定该文件的路径,这是输入密码的首选方法。

Sqoop 会从文件中读取密码,并使用安全的方式将它传递给 MapReduce 集群,而不必在配置中公开密码。包含密码的文件可以位于本地磁盘或 HDFS上 。

例如:

$ sqoop import \
--connect jdbc:mysql://database.example.com/employees \
--username venkatesh \
--password-file ${user.home}/.password

Sqoop 将读取密码文件的全部内容用作密码。包括空格字符。需要确保密码文件仅包含属于密码的字符。

在命令行中,可以使用 echo -n 来存储密码,这样将不会产生多余字符。

例如:存储 secret 为密码,可以使用如下命令:

echo -n "secret" > password.file

别名的方式

Hadoop 2.6.0 提供了一个 API 来将密码存储与应用程序分开。有一个新的credential 命令行工具来管理密码及其别名。密码与其别名一起存储在密码保护的密钥库中。

使用 Credential Provider 工具存储密码并且 Hadoop 配置已经适当更新后,所有应用程序都可以选择使用别名代替实际密码,并在运行时解析别名以供使用密码。

用法示例如下所示:

$ sqoop import \
--connect jdbc:mysql://database.example.com/employees \
--username dbuser \
--password-alias mydb.password.alias

直接通过 --password 参数是不安全的

4.2、控制导入数据相关参数

Sqoop 通常以表格为单位的方式导入数据。导入的数据各个节点都是可选的,例如要导入的表、表中的字段、表中的数据等等。

4.2.1、选择表

--table 参数用来选择要导入的表。

例如:--table employees。

该参数还可以标识数据库中的一张表或其他类似表的实体。

默认情况下,表格中的所有列都被选中用于导入。导入的数据以“自然顺序”写入HDFS。

例如:包含列A,B和C的表数据导入结果如下:

A1,B1,C1
A2,B2,C2
...

4.2.2、选择字段

导入的列是可选的,使用 --columns 参数控制列的数量以及排序。使用“,”号进行列分割。

例如:

--columns "name,employee_id,jobtitle"

4.2.3、选择数据内容

导入的数据也是可选的,使用 --where 参数可以附加一个 WHERE 子句来选择要导入的数据。默认情况下,Sqoop 生成表单的语句如下:

SELECT  FROM 

例如:--where "id > 400"。只有列 id 值大于 400 的行才会被导入。

4.2.4、选择数据分割边界

默认情况下,Sqoop 使用 select min(),max() from

查询找出创建分割的边界。在某些情况下,这个查询不是最优化的,所以可以使用 --boundary-query 参数指定列作为边界。

4.2.5、导入查询结果集

Sqoop 也可以导入任意 SQL 查询的结果集。除了使用的 --table,--columns 和 --where 参数,还可以指定 --query 的参数,其参数值为简单 SQL 语句。

自定义查询 SQL,语句要有 $CONDITIONS 关键字,作用是动态替换。

导入查询结果集时,必须使用 --target-dir 参数指定目标目录。

如果要启动多个 mapper 并行执行导入的话,则每个 mapper 都需要执行查询的语句,这样就需要 Sqoop 推断出每个进程需要执行的任务边界,那么就需要使用 --split-by 指定一个列来进行任务边界判断的依据,这个列最好是整数类型而且没有跳跃值的列,这样可以使每个进程能够得到均分的任务。

$ sqoop import \
  --query 'SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS' \
  -m 1 --target-dir /user/foo/joinresults

注意:如果使用双引号(“)将查询语句引起来的话,则必须使用 $CONDITIONS 进行转义,而不是 $CONDITIONS, 转义之后 shell 才会将其视为 shell 变量。双引号查询语句如下所示:

"SELECT * FROM x WHERE a='foo' AND \$CONDITIONS"

4.3、控制并行相关参数

从数据库导入数据的时候可以使用 -m 或 --num-mappers 参数来增加导入任务的并行。这些参数中的每一个参数值都是整数,该值与使用的并行度相对应。默认情况下,使用四个任务。有些数据库可能会通过将此值增加到8或16来提高性能。

注意:

1.不要将并行度提高到大于 MapReduce 集群中可用的最大数量,如果超过,任务将连续运行,并可能增加执行导入所需的时间。

2.不要将并行度设置的高于数据库可以合理支持的程度。例如:将100个并发客户端连接到数据库可能会增加数据库服务器的负载,从而导致性能受到影响。

在执行并行导入时,Sqoop 需要一个可以分割工作负载的标准。Sqoop 使用列来分割工作量。默认情况下,Sqoop 将识别表中的主键列(如果存在)并将其用作拆分列。分割列的低值和高值从数据库中检索,并且 mapper 任务在总范围的大小均匀的分量上进行操作。

例如:有一个表的主键列id最小值为0,最大值为 1000,并且 Sqoop 指向使用4个任务,则 Sqoop 将运行四个进程,每个进程都执行如下的 SQL 语句:

SELECT * FROM sometable WHERE id >= lo AND id < hi

每个 mapper 任务的(lo, hi)的值分别对应为(0,250),(250,500),(500,750)和(750,1001)。

可以使用 --split-limit 参数替换 --num-mapers 参数。使用 --split-limit 参数会限制所创建的拆分部分的大小。如果创建的分割大小大于此参数中指定的大小,则分割将根据此限制调整大小,并且分割的数量也根据此 项变化。如果根据 --num-mappers 参数计算出的分割大小超过了 --split-limit 参数设置的大小,那么将增加实际的 mapper 数量。如果- -split-limit 参数中指定的值为0或负数,则该参数将被全部忽略,分割大小将根据 mapper 的数量计算。

如果一个表没有定义主键并且 --split-by

参数也没有指定,那么导入将会失败,除非使用 --num-mappers 1选项或使用 --autoreset-to-one-mapper 选项将mapper 的数量显式设置为1。--autoreset-to-one-mapper 选项通常与 import-all-tables 工具一起使用,自动处理没有主键的表。

4.4、控制导入过程

默认情况下,导入过程将使用供应商提供的 JDBC 导入通道。一些数据库可以使用特定的数据移动工具以更高性能的方式执行导入。

MySQL 提供的 mysqldump 工具可以非常快速地将数据从 MySQL 导出到其他系统。Sqoop 可以通过 --direct 参数指定该工具导入,比使用 JDBC 性能更高。

默认情况下,Sqoop 将数据导入 HDFS 中一个名为 foo 的目录中。

例如,用户名是 someuser,则导入工具会将数据写入 /user/someuser/foo/(files)中。

可以使用 --warehouse-dir 参数调整导入的这个目录。

例如:

$ sqoop import \
--connnect  \
--table foo \
--warehouse-dir /shared 

该命令将数据写入目录 /shared/foo/ 目录下的文件中。

可以明确地选择目标目录,如下所示:

$ sqoop import \
--connnect  \
--table foo \
--target-dir /dest 

上述命令将文件导入到/dest目录中。--target-dir 与 --warehouse-dir 不相容。只能使用两者之一。

使用 direct 模式时,可以指定应传递给底层工具的其他参数。如果参数--是在命令行上 出现的,则--后的参数将直接发送到底层工具。

例如,以下内容将调整 mysqldump 使用的字符集:

$ sqoop import \
--connect jdbc:mysql://server.foo.com/db \
--table bar \
--direct -- --default-character-set=latin1

4.5、控制类型映射

Sqoop 预先配置为将大多数 SQL 类型映射到适当的 Java 或 Hive 类型。默认映射可能并不适合每个场景,可以使用 --map-column-java(用于更改映射到 Java)或 --map-column-hive(用于更改 Hive 映射)进行更改。

--map-column-java :指定已配置列从SQL到Java类型的映射。
--map-column-hive :指定从SQL到配置列Hive类型的映射。

Sqoop 以<列名称> = <新类型>形式的逗号分隔映射列表。

例如:

$ sqoop import ... --map-column-java id = String,value = Integer

注意:在--map-column-hive 选项中需要逗号分割,应使用 URL 编码的键和值,例如,使用 DECIMAL(1%2C%201)而不是 DECIMAL(1,1)。如果某些配置的映射不可用,Sqoop 会抛出异常。

4.6、增量导入

Sqoop 提供了一种增量导入模式,可用于检索比以前导入的一组行更新的行数据。

以下参数控制增量导入:

--check-column (col):要导入某些行时要检查的列。(该列不能是CHAR/NCHAR/VARCHAR/VARNCHAR/LONGVARCHAR/LONGNVARCHAR类型)。
--incremental (mode):指定Sqoop如何确定哪些行是新的。此项参数的值有append 和 lastmodified 两个。
--last-value (value):指定先前导入中的检查列的最大值。

Sqoop支持两种方式的增量导入:append 和 lastmodified。可以使用该 --incremental 参数来指定要执行的增量导入的方式。

4.6.1、append

append 方式在导入表格时,必须指定起始行 id 列所对应的值。可以通过 --check-column 指定该行包含的列。Sqoop 导入行的检查列的值是否大于 --last-value 参数指定的值。

4.6.2、lastmodified

Sqoop 支持的备用表更新策略称为 lastmodified 模式。

当源表的行更新时,每次更新都会将最后更新的列的值设置为当前的时间戳,如果行检查的列的时间戳比 --last-value 指定的时间戳新,那么该行会被导入。

在增量导入结束时,--last-value 应为后续导入指定的值打印到屏幕上。在运行后续导入时,--last-value 会指定上次的值以确保导入新的数据。这是增量导入自动处理的,这也是执行循环增量导入的首选机制。

五、Hive相关参数

Sqoop 的导入工具的主要功能是将数据上传到 HDFS 中的文件中。如果 Hive Metastore 与 HDFS 集群相关联,则 Sqoop 还可以将数据导入到 Hive 中,并执行CREATE TABLE 语句来定义 Hive 中的数据布局。将数据导入 Hive 中非常简单,只需要在命令中加入 --hive-import 参数即可。

5.1、覆盖表格

如果 Hive 中表已经存在,可以使用 --hive-overwrite 参数指定要替换表。然后将数据导入 HDFS 或省略此步骤,Sqoop 还将生成一个 Hive 脚本,其中包含 CREATE TABLE 语句和 LOAD DATA INPATH 语句。

5.2、指定目录

脚本将在安装了 Sqoop 的机器上运行。如果安装了多个 Hive,或者没有配置 hive的环境变量 PATH 一般为:$HIVE_HOME/bin/hive。

注意:将数据导入到 Hive 中不能使用 --as-avrodatafile 和 --assequencefile 两种文件的存储方式。

5.3、指定分隔符

如果数据库的数据内容包含Hive的缺省行分隔符(\n和\r字符)或列分隔符(\01字符)的字符串字段,则使用 Sqoop 将数据导入到Hive中时会遇到问题。(导入后发现数据错位了,或者有好多原来有值的字段都变成了 NULL,就是因为原表varchar 类型的字段中可能含有\n\r等一些特殊字符。 )

可以使用 --hive-drop-import-delims 选项在导入时删除这些字符,以保证数据与Hive 的文本数据格式兼容。或者,可以使用该 --hive-delims-replacement 选项在导入时将这些字符替换为自定义的字符串,以保证数据与 Hive 的文本数据格式兼容。

如果使用 --hive-import 参数并没有设置分隔符,则使用 Hive 的默认分隔符:字段分隔符为 ^A,记录分隔符为 \n。

Sqoop 将默认导入 NULL 值作为字符串 null。Hive 使用字符串 \N 来表示 NULL 值,因此在将数据导入 Hive 中时 NULL 将无法被正确识别。(将原来为 null 的值导入的时候转化为 null 的字符串,不是真正意义上面的 null 值,所以当使用 is null 的时候就匹配不到数据。)

如果想要在数据导入 Hive 时正确地处理 NULL,可以使用参数 --null-string 和 --null-non-string。

如果想要在数据导出 Hive 时正确的处理 NULL,可以使用参数 --input-null-string 和 --input-null-non-string。

Sqoop 在生成的代码中需要使用这些参数,所以需要正确地将值转义 \N 为 \N:

$ sqoop import ... --null-string '\\N' --null-non-string '\\N'

5.4、指定表名

Hive 中使用的表名默认情况下与源表的名称相同。也可以使用 --hive-table 选项控制输出表名称。

5.5、指定分区

Hive 可以将数据放入分区以提高查询性能。Sqoop 可以通过指定 --hive-partition-key(hive分区字段) 和 --hive-partition-value(hive分区值) 参数将数据导入 Hive 的特定分区。分区值必须是一个字符串。

你可能感兴趣的:(【Sqoop】Sqoop 工具之 Sqoop-import)