Sqoop

MapReduce需要使用额外的API与存储在HDFS外的数据交互。例如,数据经常存储在RDBMS,开源的工具Sqoop允许用户将结构化数据提取到Hadoop,使用MapReduce处理或者更高级的工具(例如hive)。Sqoop可以将处理的最终结果导出到RDBMS。

Getting Sqoop

列出Sqoop所有的工具
% sqoop help

列出具体工具的使用说明
% sqoop help import

Sqoop Connectors

Sqoop connector是一个模块化的组件,使得Sqoop可以将数据导入或导出到其它数据库(MySQL, PostgreSQL, Oracle, SQL Server, DB2, and Netezza)。如果数据库支持JDBC协议,可以使用通用的JDBC connector。Sqoop提供优化(MySQL, PostgreSQL, Oracle, and Netezza)后的connector,使用数据库定义的API,执行批量数据传输效率更高。

A Sample Import

我们先下载MySQL的JDBC driver JAR文件,放到Sqoop的lib目录下。
将数据表导入到HDFS
% sqoop import –connect jdbc:mysql://localhost/mydatabase –table mytable -m 1
sqoop的导入工具将运行一个MapReduce工作,连接数据库并读表。默认开启4个map并行任务加快导入速度。每个任务导入到不同的文件,但是都在同一个目录下。(-m 1)指定单独的map任务。
检查导入的文件:
% hadoop fs -cat widgets/part-m-00000
Sqoop默认导入逗号分割的文本文件,分割符可以明确指定,以及允许字段内容存在分割符的字段封闭符和转义符。

Imports: A Deeper Look

分割数据到多个map任务可以提高导入性能,Sqoop通常会选择主键作为分割依据。
假设有100.000行数据,id为0-99.999,5个map分别执行查询:
SELECT id, widget_name, … FROM widgets WHERE id >= 0 AND id < 20000 ,
SELECT id, widget_name, … FROM widgets WHERE id >= 20000 AND id < 40000 ,
and so on.
如果id非均匀分布,一些map会有很少甚至没有导入工作。用户可以指定字段作为分割依据(via the –split-by argument)。

Controlling the Import

Sqoop不需要每次导入全部数据,可以导入表的子集,通过 –where 参数。
指定 –query参数,可以执行更多的控制。

Incremental Imports

增量导入很常见,为了识别新数据,–check-column指定字段,–last-value指定值大于的数值。
这种方法适合新增而没有更新的情况,称为append模式。通过–incremental append激活。如果某一列记录最后更新时间,可以基于时间进行增量导入,通过–incremental lastmodified激活。
增量导入以后,Sqoop将打印出作为下次使用的last-value。手工导入时很有用,但是定期导入最好使用Sqoop的saved job工具,自动保存last value并用于下次job。sqoop job –hlep

Direct-Mode Imports

Sqoop有很多测律执行导入。有些数据库提供更快提取数据的工具,例如MySQL的mysqldump,这些工具的使用称为direct mode(via the –direct argument)。但是MySQL的direct mode不能处理大的对象,例如CLOB或者BLOB字段,所以Sqoop需要JDBC加载这些字段。因此direct mode不能像JDBC一样实现通用的目的。