Sqoop Import – 从RDBMS导入数据到HDFS

1. Sqoop Import及其目的

用于将表从RDBMS导入到HDFS的工具是Sqoop Import工具。 表中的每一行都被认为是HDFS中的记录。 当谈论文本文件时,所有记录都被存储为文本数据。 当谈论Avro和sequence文件时,所有记录都存储为二进制数据。 可以说Sqoop将所有表导入为从RDBMS到HDFS的单独表。

2. Sqoop Import语法

要将数据导入HDFS,使用以下语法 :

$ sqoop import (generic-args) (import-args)

可以按任意顺序输入sqoop Import参数。 当出现Hadoop通用参数时,Hadoop参数只能在任何Import参数之前。所有的参数都按功能分组。

Sqoop Import 通用参数

1542511711854982.png

1542511774170277.png

例如:

$ sqoop import –connect jdbc:mysql://database.example.com/employees

Sqoop Import Validation 参数

1542511893624528.png

Sqoop Import 导入控制参数

1542511975631544.png

1542512030215459.png

1542512095720008.png

选择要导入的数据

Sqoop以表为单位来导入数据。 通常在选择要导入的表时使用-table参数。 数据库中的这个参数也可以标识为VIEW或其他类似表的实体。

所有数据字段都以默认的顺序写入HDFS。 如这是一个包含列A,B和C的表格,在Sqoop中导入数据。 如下所示:

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

通过选择列,使用-columns参数可以控制列的排序。 条件是它应该包含一个以逗号分隔的列导入列表。 例如:-columns“name,employee_id,jobtitle”。

Free-form查询导入

可以在Sqoop中导入任意SQL查询的结果集。 可以用-query参数指定一条SQL语句。 即使已经使用了-table,-columns和-where参数。

导入一个Free-form的查询时,需要用-target-dir指定一个目标目录。

另外,可以并行地导入查询的结果。 之后,每个Map任务都需要执行查询的副本,结果通过Sqoop推断的边界条件来进行划分。 查询必须包含$ CONDITIONS。 每个Sqoop进程将用一个唯一的条件表达式替换$CONDITIONS。 使用-split-by指定需要切分的字段。如:

$ sqoop import \
–query ‘SELECT a.*, b.* FROM a JOIN b on (a.id == b.id) WHERE $CONDITIONS’ \
–split-by a.id –target-dir /user/foo/joinresults

通过使用-m 1指定单个Map任务,查询可以执行一次并连续导入。

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

控制并行导入

从大多数数据库源,Sqoop支持并行导入数据。 使用-m或-num-mappers参数在sqoop中执行导入。 此外,我们可以指定map任务(并行进程)的数量 。

控制Sqoop导入过程

Sqoop中的导入过程默认使用JDBC连接。  但是,通过使用特定于数据库的数据移动工具,某些数据库可以以更高性能的方式执行导入。

在HDFS的主目录中,Sqoop会将名为foo的表导入到名为foo的目录中。 例如,如果您的用户名是某个用户,则Sqoop导入工具将写入/ user / someuser / foo /(文件)。 可以使用-warehouse-dir参数调整导入的父目录。 例如:

$ sqoop import –connnect <connect-str> –table foo –warehouse-dir /shared \

类型映射

为了将大多数SQL类型映射到合适的Java或Hive表中,可以预先配置Sqoop。 默认的映射可能不适合每种情况。 可以通过 override来覆盖默认类型映射。 通过-map-column-java(用于更改映射到Java)或-map-column-hive(用于更改Hive映射)。

类型映射参数

1542531158915316.png

Sqoop以<列名称> = <新类型>形式使用逗号分隔的映射列表,例如:

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

如果某些配置的映射不被使用,Sqoop会抛出异常。

增量式导入

Sqoop提供增量导入模式。 可以用来控制只导入一组更新的行。

以下参数控制sqoop中的增量式导入:

增量式导入参数

1542531281287633.png

Sqoop中支持两种类型的增量导入。一种是追加记录的,另一个是基于修改时间的。 指定要执行的增量导入的类型,使用-incremental参数。

文件格式

可以导入数据的文件格式有两种。 一个是delimited文本格式,另一类是SequenceFiles。

大对象列

Sqoop可以处理大对象列(BLOB和CLOB类型)。 如果这些数据真的很大,应该避免在内存中操作这些列,通常情况下,大数据列是以数据流的方式处理的。

Sqoop Import – 输出行格式参数

1542531421419562.png

Sqoop Import – 输入解析参数

1542531521245302.png

数据导入到Hive中

将数据上传到HDFS中的文件是Sqoop的导入工具的主要功能。 如果我们有一个与HDFS集群关联的Hive Metastore,则Sqoop也可以将数据导入到Hive中。 通过生成并执行CREATE TABLE语句来定义Hive中的数据表。 

Sqoop Import – Hive 参数

1542531699660867.png

1542531753288834.png

数据导入HBase

除了HDFS和Hive之外,Sqoop还支持其他导入目标数据库。 Sqoop也可以将记录导入HBase的表中。

Sqoop Import – Hbase 参数

1542531881542328.png

其他Sqoop Import 配置属性

一些额外的属性可以通过修改conf / sqoop-site.xml来配置。 就像在Hadoop配置文件中一样指定属性。

<property>
<name>property.name</name>
<value>property.value</value>
</property>

在通用参数的命令行中,也可以指定这些配置,例如:

sqoop import -D property.name=property.value …

Sqoop Import 其他导入配置属性

1542532013237834.png

3. Sqoop Import 示例调用

我们将通过以下示例了解如何在各种情况下使用导入工具。

假设在corp数据库中导入一个名为EMPLOYEES的表:

$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES

需要登录信息的输入

$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
-username SomeUser -P
从EMPLOYEES表中选择特定的列:
$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
-columns“employee_id,first_name,last_name,job_title”
并行导入(使用8个并行任务):
$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
   -m 8

将数据存储在SequenceFiles中,并将生成的类名称设置为com.foocorp.Employee:

$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
-class-name com.foocorp.Employee -as-sequencefile
另外,指定要在文本模式导入中使用的分隔符:
$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
–fields-terminated-by ‘\t’ –lines-terminated-by ‘\n’ \
–optionally-enclosed-by ‘\”‘
将数据导入Hive:
$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
-hive-import
只导入新增的新员工:
$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
- “start_date>'2010-01-01'”

更改分割列:

$ sqoop import -connect jdbc:mysql://db.foo.com/corp --table EMPLOYEES \
-split-by dept_id

然后,验证导入是否成功:

$ hadoop fs -ls EMPLOYEES
Found 5 items
drwxr-xr-x - someuser somegrp 0 2010-04-27 16:40 / user / someuser / EMPLOYEES / _logs
-rw-r-r- 1 someuser somegrp 2913511 2010-04-27 16:40 / user / someuser / EMPLOYEES / part-m-00000
-rw-r-r- 1 someuser somegrp 1683938 2010-04-27 16:40 / user / someuser / EMPLOYEES / part-m-00001
-rw-r-r- 1 someuser somegrp 7245839 2010-04-27 16:40 / user / someuser / EMPLOYEES / part-m-00002
-rw-r-r- 1 someuser somegrp 7842523 2010-04-27 16:40 / user / someuser / EMPLOYEES / part-m-00003
$ hadoop fs -cat EMPLOYEES / part-m-00000 |头-n 10

在导入表格的100,000行之后,执行增量导入新数据:

$ sqoop import -connect jdbc:mysql://db.foo.com/somedb --table sometable \
-where“id> 100000”-target-dir / incremental_dataset -append

用来验证导入的正确性,通过使用表格行数和复制到HDFS的行数对比。

$ sqoop import -connect jdbc:mysql://db.foo.com/corp \
-table employees –validate

Sqoop Import – 从RDBMS导入数据到HDFS

发表评论

邮箱地址不会被公开。 必填项已用*标注

九十 ÷ = 九

滚动到顶部